private async Task BackendDiscoveryHandler() { while (this.IsRunning) { try { var endpoints = await this.BackendDiscoverer.DiscoverAll(); foreach (var endpoint in endpoints) { var endpointId = BitConverter.ToString(endpoint.Encode()); var registeredEndpoint = new RegisteredBackend(endpoint, this); if (this.backendEndpoints.TryAdd(endpointId, registeredEndpoint)) { registeredEndpoint.Connect(); Console.WriteLine($"Backend registered [ {endpointId} ] "); this.backendEndpointIds.Enqueue(endpointId); } else { this.backendEndpoints[endpointId].Heartbeat(); } } foreach (var endpointId in this.backendEndpoints.Keys) { if (!endpoints.Any(endpoint => BitConverter.ToString(endpoint.Encode()) == endpointId)) { if (this.backendEndpoints.TryRemove(endpointId, out RegisteredBackend expiredBackend)) { Console.WriteLine($"Backend {endpointId} expired"); expiredBackend.Close(); } } } } catch (Exception ex) { Console.WriteLine(ex.Message + ": " + ex.StackTrace); } await Task.Delay(5000); } }
private async Task BackendDiscoveryHandler() { while (this.IsRunning) { try { foreach (var backendDiscoverer in this.BackendDiscoverers) { var backendEndpointIds = this.backendEndpointIds.GetOrAdd(backendDiscoverer.Name, new ConcurrentQueue <string>()); var endpoints = await backendDiscoverer.Discoverer.DiscoverAll(); foreach (var endpoint in endpoints) { var endpointId = BitConverter.ToString(endpoint.Encode()); var registeredEndpoint = new RegisteredBackend(backendDiscoverer.Name, endpoint, this); if (this.backendEndpoints.TryAdd(endpointId, registeredEndpoint)) { registeredEndpoint.Connect(); this.OnDiagnosticMessage($"Backend registered [ {backendDiscoverer.Name}/{endpointId} ] "); backendEndpointIds.Enqueue(endpointId); } else { this.backendEndpoints[endpointId].Heartbeat(); } } foreach (var endpointId in backendEndpointIds) { if (!endpoints.Any(endpoint => BitConverter.ToString(endpoint.Encode()) == endpointId)) { if (this.backendEndpoints.TryRemove(endpointId, out RegisteredBackend expiredBackend)) { this.OnDiagnosticMessage($"Backend {backendDiscoverer.Name}/{endpointId} expired"); expiredBackend.Close(); if (this.backendEndpointIds.TryRemove(backendDiscoverer.Name, out var oldEndpoints)) { this.backendEndpointIds.GetOrAdd(backendDiscoverer.Name, new ConcurrentQueue <string>(oldEndpoints.Where(e => e != endpointId))); } } } } } foreach (var backendDiscoverer in this.BackendDiscoverers) { this.OnDiagnosticMessage($"Backend: {backendDiscoverer.Name}"); var backendEndpointIds = this.backendEndpointIds.GetOrAdd(backendDiscoverer.Name, new ConcurrentQueue <string>()); foreach (var eid in backendEndpointIds) { this.OnDiagnosticMessage($" {eid}"); } } } catch (Exception ex) { this.OnDiagnosticMessage(ex.Message + ": " + ex.StackTrace); } await Task.Delay(5000); } }
private async Task Handler() { while (this.IsRunning) { try { bool isListening = false; var connectionString = this.FrontendEndpoint.ToConnectionString(); using (var frontendSocket = new RouterSocket()) using (this.frontendBuffer = new NetMQQueue <TransportMessage>()) using (var poller = new NetMQPoller() { frontendSocket, this.frontendBuffer }) using (var monitor = new NetMQ.Monitoring.NetMQMonitor(frontendSocket, $"inproc://monitor.forwarderdevice.{Guid.NewGuid().ToString()}", SocketEvents.Listening | SocketEvents.Accepted | SocketEvents.Disconnected | SocketEvents.Closed)) { frontendSocket.ReceiveReady += (sender, e) => { try { var netmqMessage = new NetMQMessage(); while (e.Socket.TryReceiveMultipartMessage(ref netmqMessage)) { var message = netmqMessage.ToMessage(out var envelope); //var sourceEnvelope = message.Envelope; //if (message.Metadata.TryGet("action", out var encodedAction)) //{ // var action = Encoding.UTF8.GetString(encodedAction); // var activity = new Activity(action); // if (message.Metadata.TryGet("aid", out var encodedActivityId)) // { // var activityId = Encoding.UTF8.GetString(encodedActivityId); // activity.SetParentId(activityId); // } // message.Metadata.AddOrSet("aid", Encoding.UTF8.GetBytes(activity.Id)); //} string serviceIdentifier = message.Metadata.TryGetLast("serviceIdentifier", out var encodedService) ? Encoding.UTF8.GetString(encodedService) : null; this.OnFrontendReceived(message); var forwardStart = DateTime.UtcNow; RegisteredBackend registeredBackend = this.ResolveBackend(serviceIdentifier); if (registeredBackend != null) { message.Metadata.Add($"envelope[{this.Identity}]", envelope); registeredBackend.BackendBuffer.Enqueue(message); } else { this.OnDiagnosticMessage($"No backends available for {serviceIdentifier}!!!"); var nmqm = MessageHelpers.CreateNetMQErrorMessage(envelope, "No backends found", message.Metadata); e.Socket.SendMultipartMessage(nmqm); } } } catch (Exception ex) { this.OnDiagnosticMessage(ex.Message + ": " + ex.StackTrace); } }; this.frontendBuffer.ReceiveReady += (sender, e) => { try { while (this.frontendBuffer.TryDequeue(out TransportMessage message, TimeSpan.Zero)) { if (!message.Metadata.TryPluckLast($"envelope[{this.Identity}]", out var envelope)) { throw new Exception("Message envelope not found"); } this.OnBackendForwarded(message); if (!frontendSocket.TrySendMultipartMessage(TimeSpan.FromSeconds(1), message.ToNetMQMessage(envelope))) { this.OnDiagnosticMessage("Failed to forward to frontend"); } } } catch (Exception ex) { this.OnDiagnosticMessage(ex.Message + ": " + ex.StackTrace); } }; monitor.Listening += (sender, e) => { this.OnDiagnosticMessage($"Frontend router socket listening at {connectionString}"); isListening = true; }; monitor.Closed += (sender, e) => { this.OnDiagnosticMessage($"Frontend router socket closed on {connectionString}"); isListening = false; }; monitor.Accepted += (sender, e) => { this.OnDiagnosticMessage($"Frontend router socket connection accepted at {connectionString}"); }; monitor.Disconnected += (sender, e) => { this.OnDiagnosticMessage($"Frontend router socket disconnected at {connectionString}"); }; this.OnDiagnosticMessage($"Attempting to bind frontend socket to {connectionString}"); monitor.StartAsync(); monitor.AttachToPoller(poller); var pollerTask = new Task(poller.Run); pollerTask.ContinueWith((Task task) => { var ex = task.Exception; this.OnDiagnosticMessage(ex.Message + ": " + ex.StackTrace); isListening = false; }, TaskContinuationOptions.OnlyOnFaulted); pollerTask.Start(); frontendSocket.Bind(connectionString); var start = DateTime.Now; while (!isListening) { if ((DateTime.Now - start).TotalMilliseconds > 5000) { throw new Exception($"Frontend socket bind timeout ({connectionString})"); } await Task.Delay(1000); } while (this.IsRunning && isListening) { await Task.Delay(1000); } poller.StopAsync(); frontendSocket.Disconnect(connectionString); monitor.DetachFromPoller(); monitor.Stop(); } } catch (Exception ex) { this.OnDiagnosticMessage(ex.Message + ": " + ex.StackTrace); } } }
private async Task FrontendHandler() { while (this.IsRunning) { try { bool isListening = false; var connectionString = this.FrontendEndpoint.ToConnectionString(); using (var frontendSocket = new RouterSocket()) using (this.AltFrontendBuffer = new NetMQQueue <TransportMessage>()) using (var poller = new NetMQPoller() { frontendSocket, this.AltFrontendBuffer }) using (var monitor = new NetMQ.Monitoring.NetMQMonitor(frontendSocket, $"inproc://monitor.routerdevice.frontend.{Guid.NewGuid().ToString()}", SocketEvents.Listening | SocketEvents.Accepted | SocketEvents.Disconnected | SocketEvents.Closed)) { frontendSocket.ReceiveReady += (sender, e) => { try { var netmqMessage = new NetMQMessage(); while (e.Socket.TryReceiveMultipartMessage(ref netmqMessage)) { //Console.WriteLine("Frontend message received"); var message = netmqMessage.ToMessage(out var envelope); this.OnFrontendReceived(message); //this.receiveCount++; //Console.WriteLine("RECEIVED " + this.receiveCount); //var sourceEnvelope = message.Envelope; RegisteredBackend registeredBackend = null; var forwardStart = DateTime.UtcNow; while (this.IsRunning && registeredBackend == null) { while (this.RegisteredBackendIdentifiers.TryDequeue(out string backendIdentifier)) { registeredBackend = this.RegisteredBackends[backendIdentifier]; if ((DateTime.UtcNow - registeredBackend.RegsiteredDate).TotalMilliseconds < 2000) { this.RegisteredBackendIdentifiers.Enqueue(backendIdentifier); break; } else { if (this.RegisteredBackends.TryRemove(backendIdentifier, out RegisteredBackend expiredBackend)) { Console.WriteLine($"Backend {backendIdentifier} expired"); } } } if (registeredBackend != null || (DateTime.Now - forwardStart).TotalMilliseconds > 30000) { break; } System.Threading.Thread.Sleep(100); } if (registeredBackend != null) { //Console.WriteLine($"Forwarding to [ {BitConverter.ToString(registeredBackend.Envelope)} ]"); message.Metadata.Add($"envelope[{this.Identity}]", envelope); message.Metadata.Add($"backendEnvelope[{this.Identity}]", registeredBackend.Envelope); this.AltBackendBuffer.Enqueue(message); ////this.BackendSocket.SendMultipartMessage(message.ToNetMQMessage(true)); //if (!this.BackendSocket.TrySendMultipartMessage(TimeSpan.FromSeconds(1), message.ToNetMQMessage(true))) //{ // Console.WriteLine("Failed to forward to backend"); // var forwardedMessage = new Message(1, message.Frames, System.Text.Encoding.UTF8.GetBytes("Failed to forward to backend"), sourceEnvelope); // this.FrontendSocket.SendMultipartMessage(forwardedMessage.ToNetMQMessage(true)); //} } else { Console.WriteLine("No backends available!!!"); var nmqm = MessageHelpers.CreateNetMQErrorMessage(envelope, "No backends found", message.Metadata); e.Socket.SendMultipartMessage(nmqm); } } } catch (Exception ex) { Console.WriteLine(ex.Message + ": " + ex.StackTrace); } }; //var lastFlushed = DateTime.UtcNow; //frontendSocket.SendReady += (sender, e) => //{ // try // { // if (!this.BackendBuffer.IsEmpty) // { // while (this.BackendBuffer.TryDequeue(out Message message)) // { // Console.WriteLine("Backend forwarding"); // if (!e.Socket.TrySendMultipartMessage(TimeSpan.FromSeconds(1), message.ToNetMQMessage(true))) // { // Console.WriteLine("Failed to forward to frontend"); // //var forwardedMessage = new Message(1, message.Frames, System.Text.Encoding.UTF8.GetBytes("Failed to forward to backend"), sourceEnvelope); // //this.FrontendSocket.SendMultipartMessage(forwardedMessage.ToNetMQMessage(true)); // } // } // lastFlushed = DateTime.UtcNow; // } // if ((DateTime.UtcNow - lastFlushed).TotalSeconds > 1) // Task.Delay(1).Wait(); // } // catch (Exception ex) // { // Console.WriteLine(ex.Message + ": " + ex.StackTrace); // } //}; this.AltFrontendBuffer.ReceiveReady += (sender, e) => { try { while (this.AltFrontendBuffer.TryDequeue(out TransportMessage message, TimeSpan.Zero)) { if (!message.Metadata.TryPluck($"envelope[{this.Identity}]", out var envelope)) { throw new Exception("Message envelope not found"); } this.OnBackendForwarded(message); if (!frontendSocket.TrySendMultipartMessage(TimeSpan.FromSeconds(1), message.ToNetMQMessage(envelope))) { Console.WriteLine("Failed to forward to frontend"); } } } catch (Exception ex) { Console.WriteLine(ex.Message + ": " + ex.StackTrace); } }; monitor.Listening += (sender, e) => { Console.WriteLine($"Frontend router socket listening at {connectionString}"); isListening = true; }; monitor.Closed += (sender, e) => { Console.WriteLine($"Frontend router socket closed on {connectionString}"); isListening = false; }; monitor.Accepted += (sender, e) => { Console.WriteLine($"Frontend router socket connection accepted at {connectionString}"); }; monitor.Disconnected += (sender, e) => { Console.WriteLine($"Frontend router socket disconnected at {connectionString}"); }; Console.WriteLine($"Attempting to bind frontend socket to {connectionString}"); monitor.StartAsync(); monitor.AttachToPoller(poller); var pollerTask = new Task(poller.Run); pollerTask.ContinueWith((Task task) => { var ex = task.Exception; Console.WriteLine(ex.Message + ": " + ex.StackTrace); isListening = false; }, TaskContinuationOptions.OnlyOnFaulted); pollerTask.Start(); frontendSocket.Bind(connectionString); var start = DateTime.Now; while (!isListening) { if ((DateTime.Now - start).TotalMilliseconds > 5000) { throw new Exception($"Frontend socket bind timeout ({connectionString})"); } await Task.Delay(1000); } while (this.IsRunning && isListening) { if (this.FrontendAnnouncer != null) { //Console.WriteLine("Registering frontend"); await this.FrontendAnnouncer.Register(this.FrontendEndpoint); } await Task.Delay(1000); } poller.StopAsync(); frontendSocket.Disconnect(connectionString); monitor.DetachFromPoller(); monitor.Stop(); } } catch (Exception ex) { Console.WriteLine(ex.Message + ": " + ex.StackTrace); } } }