Ejemplo n.º 1
0
        public void MonitorDisposeProperlyWhenDisposedAfterMonitoredTcpSocket()
        {
            // The bug:
            // Given we monitor a netmq tcp socket
            // Given we disposed of the monitored socket first
            // When we dispose of the monitor
            // Then our monitor is Faulted with a EndpointNotFoundException
            // And monitor can't be stopped or disposed

            using (var context = NetMQContext.Create())
                using (var res = context.CreateResponseSocket())
                {
                    NetMQMonitor monitor;
                    using (var req = context.CreateRequestSocket())
                    {
                        monitor = new NetMQMonitor(context, req, "inproc://#monitor", SocketEvents.All);
                        Task.Factory.StartNew(monitor.Start);

                        // Bug only occurs when monitoring a tcp socket
                        var port = res.BindRandomPort("tcp://127.0.0.1");
                        req.Connect("tcp://127.0.0.1:" + port);

                        req.Send("question");
                        Assert.That(res.ReceiveFrameString(), Is.EqualTo("question"));
                        res.Send("response");
                        Assert.That(req.ReceiveFrameString(), Is.EqualTo("response"));
                    }
                    Thread.Sleep(100);
                    // Monitor.Dispose should complete
                    var completed = Task.Factory.StartNew(() => monitor.Dispose()).Wait(1000);
                    Assert.That(completed, Is.True);
                }
            // NOTE If this test fails, it will hang because context.Dispose will block
        }
Ejemplo n.º 2
0
        public void MonitorDisposeProperlyWhenDisposedAfterMonitoredTcpSocket()
        {
            // The bug:
            // Given we monitor a netmq tcp socket
            // Given we disposed of the monitored socket first
            // When we dispose of the monitor
            // Then our monitor is Faulted with a EndpointNotFoundException
            // And monitor can't be stopped or disposed

            using (var theContext = NetMQContext.Create())
            using (var resSocket = theContext.CreateResponseSocket())
            {
                NetMQMonitor monitor;
                using (var reqSocket = theContext.CreateRequestSocket())
                {
                    monitor = new NetMQMonitor(theContext, reqSocket, "inproc://#monitor", SocketEvent.All);
                    Task.Factory.StartNew(() => monitor.Start());

                    //The bug is only occurring when monitor a tcp socket
                    var port = resSocket.BindRandomPort("tcp://127.0.0.1");
                    reqSocket.Connect("tcp://127.0.0.1:" + port);

                    reqSocket.Send("question");
                    Assert.That(resSocket.ReceiveString(), Is.EqualTo("question"));
                    resSocket.Send("response");
                    Assert.That(reqSocket.ReceiveString(), Is.EqualTo("response"));
                }
                Thread.Sleep(100);
                // Monitor.Dispose should complete
                var completed = Task.Factory.StartNew(() => monitor.Dispose()).Wait(1000);
                Assert.That(completed, Is.True);
            }
            //Note: If this test fails, it will hang because the context Dispose will block
        }
Ejemplo n.º 3
0
 private void DisposeMonitor()
 {
     _monitor.Connected      -= Monitor_Connected;
     _monitor.Disconnected   -= Monitor_Disconnected;
     _monitor.ConnectRetried -= Monitor_ConnectRetried;
     _monitor.Dispose();
     _monitor = null;
 }
Ejemplo n.º 4
0
        public void MonitorDisposeProperlyWhenDisposedAfterMonitoredTcpSocket()
        {
            // The bug:
            // Given we monitor a netmq tcp socket
            // Given we disposed of the monitored socket first
            // When we dipose of the monitor
            // Then our monitor is Faulted with a EndpointNotFoundException
            // And monitor can't be stopped or disposed

            Task monitorTask;

            using (var theContext = NetMQContext.Create())
                using (var resSocket = theContext.CreateResponseSocket())
                {
                    NetMQMonitor monitor = null;
                    using (var reqSocket = theContext.CreateRequestSocket())
                    {
                        monitor     = new NetMQMonitor(theContext, reqSocket, "inproc://#monitor", SocketEvent.All);
                        monitorTask = Task.Factory.StartNew(() => monitor.Start());

                        //The bug is only occuring when monitor a tcp socket
                        resSocket.Bind("tcp://127.0.0.1:12345");
                        reqSocket.Connect("tcp://127.0.0.1:12345");

                        reqSocket.Send("question");
                        Assert.That(resSocket.ReceiveString(), Is.EqualTo("question"));
                        resSocket.Send("response");
                        Assert.That(reqSocket.ReceiveString(), Is.EqualTo("response"));
                    }
                    Thread.Sleep(100);
                    // Monitor.Dispose should complete
                    var completed = Task.Factory.StartNew(() => monitor.Dispose()).Wait(1000);
                    Assert.That(completed, Is.True);
                }
            //Note: If this test fails, it will hang because the context Dispose will block
        }
Ejemplo n.º 5
0
 public void Dispose()
 {
     _monitor?.Dispose();
     _monitorTask?.Wait(1000);
 }
Ejemplo n.º 6
0
        void IShimHandler.Run(PairSocket shim)
        {
            _poller = new NetMQPoller();

            // Listen to actor dispose
            _ = Observable.FromEventPattern <NetMQSocketEventArgs>(e => shim.ReceiveReady += e, e => shim.ReceiveReady -= e)
                .Select(e => e.EventArgs)
                .ObserveOn(Scheduler.CurrentThread)
                .Subscribe(OnShimReady);

            _poller.Add(shim);

            _subscriberSocket = new SubscriberSocket();
            _subscriberSocket.Options.ReceiveHighWatermark = 1000;
            _subscriberSocket.Options.Linger               = TimeSpan.FromSeconds(2);
            _subscriberSocket.Options.TcpKeepalive         = true;
            _subscriberSocket.Options.TcpKeepaliveIdle     = TimeSpan.FromSeconds(5);
            _subscriberSocket.Options.TcpKeepaliveInterval = TimeSpan.FromSeconds(1);

#if MONITOR
            var monitor = new NetMQMonitor(_subscriberSocket, "inproc://#monitor", SocketEvents.All);
            _ =
                Observable.FromEventPattern <NetMQMonitorSocketEventArgs>(monitor, "Connected")
                .Select(e => new { Event = "Connected", e })
                .Merge(Observable.FromEventPattern <NetMQMonitorSocketEventArgs>(monitor, nameof(monitor.Listening)).Select(e => new { Event = "Listening", e }))
                .Merge(Observable.FromEventPattern <NetMQMonitorSocketEventArgs>(monitor, nameof(monitor.Accepted)).Select(e => new { Event = "Accepted", e }))
                .Merge(Observable.FromEventPattern <NetMQMonitorSocketEventArgs>(monitor, nameof(monitor.Closed)).Select(e => new { Event = "Closed", e }))
                .Merge(Observable.FromEventPattern <NetMQMonitorSocketEventArgs>(monitor, nameof(monitor.Disconnected)).Select(e => new { Event = "Disconnected", e }))
                .Do(e => _logger.Info("Monitor socket: {0}, {1}", e.Event, e.e.EventArgs.Address))
                .Subscribe();
            _ = Observable.FromEventPattern <NetMQMonitorErrorEventArgs>(monitor, nameof(monitor.AcceptFailed))
                .Merge(Observable.FromEventPattern <NetMQMonitorErrorEventArgs>(monitor, nameof(monitor.ConnectDelayed)))
                .Merge(Observable.FromEventPattern <NetMQMonitorErrorEventArgs>(monitor, nameof(monitor.CloseFailed)))
                .Merge(Observable.FromEventPattern <NetMQMonitorErrorEventArgs>(monitor, nameof(monitor.BindFailed)))
                .Do(e => _logger.Error("Monitor error socket: {0}, {1}", e.EventArgs.ErrorCode, e.EventArgs.Address))
                .Subscribe();
            _ = Observable.FromEventPattern <NetMQMonitorIntervalEventArgs>(monitor, nameof(monitor.ConnectRetried))
                .Do(e => _logger.Info("Monitor retry socket: {0}, {1}", e.EventArgs.Interval, e.EventArgs.Address))
                .Subscribe();
            monitor.AttachToPoller(_poller);
#endif

            _ = Observable.FromEventPattern <NetMQSocketEventArgs>(
                e => _subscriberSocket.ReceiveReady += e, e => _subscriberSocket.ReceiveReady -= e)
                .Select(e => e.EventArgs)
                .ObserveOn(Scheduler.CurrentThread)
                .Subscribe(ReceivedMessage);

            _poller.Add(_subscriberSocket);

            _subscriberSocket.Connect($"tcp://{_address}:{_port + 1}");

            shim.SignalOK();

            try
            {
                _poller.Run();
            }
            catch (Exception ex)
            {
                _logger.Fatal(ex, "Fatal error on NetMQ poller.");
            }

            // Cleanup stuff after stopping
            _poller.Remove(_subscriberSocket);
            _poller.Remove(shim);
#if MONITOR
            if (monitor != null)
            {
                monitor.DetachFromPoller();
                monitor.Dispose();
                monitor = null;
            }
#endif
            _poller.Dispose();
        }