/// <summary> /// Process a message sent to this client. /// </summary> /// <param name="clientMessage">Message to process</param> private void ProcessMessageToClient(RequestResponse clientMessage) { WatcherCall watcherCall = clientMessage.Content as WatcherCall; if (watcherCall == null) { RingMasterClientEventSource.Log.ProcessMessageToClientFailedNotWatcherCall(); this.instrumentation.InvalidClientMessageReceived(); return; } lock (this.watcherMap) { WatcherWrapper watcher = null; if (this.watcherMap.TryGetValue(watcherCall.WatcherId, out watcher)) { watcher.Process(watcherCall.WatcherEvt); // If it is a one use watcher, it must be removed from the watcher map as it won't receive any further // notifications. Similarly, if it is a multi use watcher and the current notification is a WatcherRemoved // notification, it will not receive any further notifications. if (watcher.Kind.HasFlag(WatcherKind.OneUse) || watcherCall.WatcherEvt.EventType == WatchedEvent.WatchedEventType.WatcherRemoved) { RingMasterClientEventSource.Log.UnregisterWatcher(watcher.Id); this.watcherMap.Remove(watcher.Id); } } else { RingMasterClientEventSource.Log.ProcessMessageToClientFailedWatcherDoesNotExist(watcherCall.WatcherId); this.instrumentation.WatcherNotFound(); } } }
/// <summary> /// Drain currently installed watchers. /// </summary> private void DrainWatchers() { lock (this.watcherMap) { RingMasterClientEventSource.Log.DrainWatchers(this.watcherMap.Count); foreach (var pair in this.watcherMap) { WatcherWrapper watcher = pair.Value; Debug.Assert(watcher != null, "Watcher in watchers map is null"); RingMasterClientEventSource.Log.DrainWatcher(pair.Key, watcher.Path); watcher.Process( new WatchedEvent( WatchedEvent.WatchedEventType.WatcherRemoved, WatchedEvent.WatchedEventKeeperState.Disconnected, watcher.Path)); } this.watcherMap.Clear(); } }
/// <summary> /// Register a watcher to receive notifications. /// </summary> /// <param name="watcher">Watcher that must be notified</param> /// <param name="path">Path associated with the watcher</param> /// <returns>A wrapper that associates a unique id with the given watcher</returns> private WatcherWrapper RegisterWatcher(IWatcher watcher, string path) { if (watcher == null) { return(null); } WatcherWrapper wrapper = null; ulong watcherId = (ulong)Interlocked.Increment(ref this.watcherId); RingMasterClientEventSource.Log.RegisterWatcher(watcherId, path); wrapper = new WatcherWrapper(this, watcherId, watcher, path); lock (this.watcherMap) { WatcherWrapper result = wrapper; this.watcherMap.Add(watcherId, wrapper); wrapper = null; return(result); } }
/// <summary> /// Process a response to a request. /// </summary> /// <param name="callId">Id of the call associated with this response</param> /// <param name="request">The request associated with the response</param> /// <param name="response">The response that was received</param> private void ProcessRequestResponse(ulong callId, RequestWrapper request, RequestResponse response) { // If the message comes with a path, this means we need to assume // that path is the one the data relates to, so we will modify the // request to reflect that. if (response.ResponsePath != null) { request.WrappedRequest.Path = response.ResponsePath; } RingMasterClientEventSource.Log.ProcessResponse(callId, response.ResponsePath, response.ResultCode); this.instrumentation.ResponseProcessed(request.CallId, request.WrappedRequest.RequestType, response.ResultCode, TimeSpan.FromTicks(request.ElapsedInTicks)); Task.Run(() => { request.TaskCompletionSource.SetResult(response); // The response for the request that installed the watcher has been processed // Now, notifications for any watcher installed by the request can be dispatched. WatcherWrapper watcher = request.AssociatedWatcher; if (watcher != null) { if (response.ResultCode == (int)RingMasterException.Code.Ok) { watcher.EnableDispatch(); } else { // If the request that installed the watcher failed, then remove the watcher lock (this.watcherMap) { this.watcherMap.Remove(watcher.Id); } } } }); }
public GetChildrenOperation(GetChildrenRequest request, WatcherWrapper wrapper) : base(request) { this.wrapper = wrapper; }
public GetDataOperation(GetDataRequest request, WatcherWrapper wrapper) : base(request) { this.wrapper = wrapper; }
public ExistsOperation(ExistsRequest request, WatcherWrapper wrapper) : base(request) { this.wrapper = wrapper; }