public Task <IResponseMessage <IResponseData> > SendRequest(PluginClient whoRequested, int id, IRequestMessage <IRequestData> request) { var pendingRequest = new PendingRequest(id, request, whoRequested); _pendingRequests.Update(l => l.Add(pendingRequest)); _outStream.OnNext(request.ChangeId(id)); return(pendingRequest.Task); }
public void PassRequestToAnImplementor(PluginClient whoRequested, IRequestMessage <IRequestData> request) { var clientsThatImplementsRequest = _clients.Values.Where(c => c.IsImlementorOf(request.Name)); foreach (var client in clientsThatImplementsRequest) { var responseTask = client.SendRequest(whoRequested, Interlocked.Increment(ref _currentGlobalRequestId), request); if (!responseTask.Wait(TimeSpan.FromMinutes(1))) { continue; } var response = responseTask.Result; if (response.Status == Status.Unhandled) { continue; } whoRequested.SendResponse(response.ChangeId(request.Id)); return; } whoRequested.SendResponse(Response.CreateUnhandled(request, new Error(ErrorCode.InvalidRequest, "Did not find an implementor for " + request.Name), (UnresolvedMessagePayload)null)); }
public PendingRequest(int id, IRequestMessage <IRequestData> request, PluginClient whoRequested) { Id = id; Request = request; WhoRequested = whoRequested; }
void HandleHello( HelloRequest helloReq, IMessageConnection c, ConcurrentStack <IDisposable> disposables, RequestReceiver requestReceiver, IObservable <IMessage> messagesIn, IObserver <IMessage> messagesOut) { if (helloReq == null) { throw new FuseRequestErrorException(ErrorCode.InvalidData, "Expected data to not be empty."); } // TODO: Enforce daemonkey to be present in the future if (!string.IsNullOrWhiteSpace(helloReq.DaemonKey) && DaemonKey.Deserialize(helloReq.DaemonKey) != _daemonKey) { throw new FuseRequestErrorException( ErrorCode.WrongDaemonKey, "Daemon key was not right, maybe because daemon possesses wrong local user."); } #pragma warning disable 0618 var pluginClient = new PluginClient( messagesOut, helloReq.Identifier, helloReq.Implements, helloReq.EventFilter); #pragma warning restore 0618 _pluginClients.Add(c, pluginClient); _report.Info("Client connected: " + helloReq.Identifier, ReportTo.LogAndUser); c.Disconnected.Subscribe(d => _report.Info("Client disconnected: " + helloReq.Identifier, ReportTo.LogAndUser)); // Broadcast events to clients that wants the events. disposables.Push(messagesIn.OfType <IEventMessage <IEventData> >().Subscribe(_broadcastEvents.OnNext)); disposables.Push(_broadcastEvents .Subscribe(pluginClient.HandleEvent)); // Handle Subscribe to event request. disposables.Push( messagesIn .OfType <IRequestMessage <UnresolvedMessagePayload> >() .Deserialize <SubscribeRequest>(_report) .Subscribe( r => disposables.Push( pluginClient.SubscribeToEvent( r, hotMessages: _broadcastEvents, replayMessages: _replayBroadcastEvents)) )); disposables.Push( requestReceiver.SubscribeToRequest <PublishServiceRequest, PublishServiceResponse>(pluginClient.AppendSupportedRequests)); // Send requests to clients that implements the request. disposables.Push( messagesIn.OfType <IRequestMessage <IRequestData> >() .Where(r => r.Name != "Subscribe" && r.Name != "Fuse.KillDaemon" && r.Name != "PublishService") .Subscribe(r => Task.Run(() => _pluginClients.PassRequestToAnImplementor(pluginClient, r)))); // Handle the response from the one that implemented the request disposables.Push( messagesIn.OfType <IResponseMessage <IResponseData> >().Subscribe(pluginClient.HandleResponse)); }
public void Add(IMessageConnection socket, PluginClient client) { _clients.TryAdd(socket, client); }