/// <summary> /// Protected default construtor for creating a new id. /// </summary> public NyxBorg( ILogger <NyxBorg> logger, IConfigManager config, PluginManager plugman) { NodeId = Guid.NewGuid().ToString("N"); _config = config; _logger = logger; _config.WhenConfigChanges.ObserveOn(ThreadPoolScheduler.Instance).Subscribe(LoadConfig); _plugman = plugman; _messageLoopToken = _messageLoopCancelation.Token; _serverCancelToken = _serverCancelationSource.Token; _disposables.Add(_messageSendResetEvent); _disposables.Add(_serverEvent); _disposables.Add(_messageLoopCancelation); _disposables.Add(_serverCancelationSource); LoadConfig(null); Heartbeat.CreateInstance(_lastHubIp, _port); //_heartbeat = new Heartbeat(_context, _lastHubIp, _port.ToString()); ConnectionStatusStream = Observable.Create <ConnectionStatus>(o => { _logger.Debug("Hearbeat restarted."); Heartbeat.Instance.Init(); return(Heartbeat.Instance.ConnectionStatusStream.Subscribe(o)); }).Repeat().Publish().RefCount(); _disposables.Add(ConnectionStatusStream .ObserveOn(ThreadPoolScheduler.Instance) .Subscribe(x => _hubOnline = x.HasFlag(ConnectionStatus.Online))); _disposables.Add(NyxMessageStream.Subscribe(x => { if (TotalInMessages == long.MaxValue) { TotalInMessages = 0; } TotalInMessages++; })); _disposables.Add(OutMessageStream.Subscribe(x => { if (TotalInMessages == long.MaxValue) { TotalOutMessages = 0; } TotalOutMessages++; })); }
/// <summary> /// Server loop /// </summary> private void ServerLoop() { if (Thread.CurrentThread.Name == null) { Thread.CurrentThread.Name = "Nyx Borg Server Loop"; } _logger.Debug("Starting borg server loop..."); //_disposables.Add(NyxMessageStream.SubscribeOn(ThreadPoolScheduler.Instance).Subscribe(ReceivedMessage)); _disposables.Add(NyxMessageStream .TimeInterval() .Do(t => _logger.Info("Last message ({1}) received {0:##0.000}s ago.", t.Interval.TotalSeconds, t.Value.Action)) .Select(t => new NyxMessage(t.Value as NyxMessage)) .ObserveOnPool() .Subscribe(ReceivedMessage)); _disposables.Add(OutMessageStream .Where(m => m.Status == MessageCondition.Sent) .TimeInterval() .Do(t => _logger.Info("Last message ({1}) sent {0:##0.000}s ago.", t.Interval.TotalSeconds, t.Value.Message.Action)) .ObserveOnPool() .Subscribe()); var messageLoopTask = new Task(MessageSenderLoop, _messageLoopToken, TaskCreationOptions.LongRunning); messageLoopTask.Start(); _plugman.StartAllPlugins(); Status = NyxNodeStatus.Started; _nodeStatusSubject.OnNext(NyxNodeStatus.Started); // Endless loop until request to stop, then shutdowns while (!_serverCancelToken.IsCancellationRequested) { _serverEvent.WaitOne(6000); } _logger.Debug("Stopping server loop..."); var stopTask = Task.Run(() => _plugman.StopAllPlugins(), _messageLoopToken); if (!stopTask.Wait(TimeSpan.FromSeconds(45))) { _logger.Error("Plugins didn't stop in the allocated time."); } // Dispose the event listener and no "leaks" // Flush any message leftovers _messageSendResetEvent.Set(); if (_messageQueue.Count > 0) { Thread.Sleep(TimeSpan.FromSeconds(15)); _messageSendResetEvent.Set(); } _messageLoopCancelation.Cancel(); _nodeConnectionSubject.OnNext(ConnectionStatus.Disconnected); Status = NyxNodeStatus.Stopped; _nodeStatusSubject.OnNext(Status); _actor?.Dispose(); _connectionDisposable?.Dispose(); _reqSocket?.Dispose(); IsStarted = false; }