예제 #1
0
        public void Start()
        {
            if (_running)
            {
                throw new InvalidOperationException("Instance is already running.");
            }

            _running = true;

            _cancelSource = new CancellationTokenSource();

            var cancel = _cancelSource.Token;

            _chainThread = new Thread(() => ChainController.Loop(cancel))
            {
                Name = "ChainController", IsBackground = true
            };

            _coinThreads = new Thread[CoinControllers.Length];
            for (var i = 0; i < CoinControllers.Length; i++)
            {
                var coinController = CoinControllers[i];
                _coinThreads[i] = new Thread(() => coinController.Loop(cancel))
                {
                    Name = $"CoinController[{i}]", IsBackground = true
                };
            }

            _dispatchThread = new Thread(() => DispatchController.Loop(cancel))
            {
                Name = "DispatchController", IsBackground = true
            };

            _listenerThread = new Thread(() => Listener.Loop(cancel))
            {
                Name = "Listener", IsBackground = true
            };

            _chainThread.Start();
            foreach (var t in _coinThreads)
            {
                t.Start();
            }
            _dispatchThread.Start();
            _listenerThread.Start();
        }
예제 #2
0
        public void Stop()
        {
            _cancelSource.Cancel();

            // Wake controllers to let them terminate.
            ChainController.Wake();
            foreach (var c in CoinControllers)
            {
                c.Wake();
            }
            DispatchController.Wake();

            _chainThread.Join();
            foreach (var t in _coinThreads)
            {
                t.Join();
            }
            _dispatchThread.Join();
            _listenerThread.Join();

            _running = false;
        }
예제 #3
0
        public void SetupControllers()
        {
            // == Setup inboxes ==
            var dispatchInbox = new BoundedInbox(Constants.DispatchControllerOutboxSize);
            var coinInboxes   = new BoundedInbox[CoinStores.Length];

            for (var i = 0; i < coinInboxes.Length; i++)
            {
                coinInboxes[i] = new BoundedInbox(Constants.CoinControllerInboxSize);
            }
            var chainInbox = new BoundedInbox(Constants.ChainControllerInboxSize);

            // == Setup controllers ==
            Listener = new Listener(
                dispatchInbox,
                IpAddress,
                Port,
                _log);

            // Zero port can be re-associated to an available port.
            Port = Listener.Port;

            DispatchController = new DispatchController(
                dispatchInbox,
                chainInbox,
                coinInboxes,
                OutpointHash,
                _log);

            CoinControllers = new CoinController[CoinStores.Length];
            for (var i = 0; i < CoinControllers.Length; i++)
            {
                CoinControllers[i] = new CoinController(
                    coinInboxes[i],
                    dispatchInbox,
                    CoinStores[i],
                    OutpointHash,
                    _log,
                    shardIndex: i);
            }

            ChainController = new ChainController(
                ChainStore,
                chainInbox,
                dispatchInbox,
                lineage =>
            {
                // Whenever 'OpenBlock' or 'CommitBlock' is requested, lineages get refreshed.
                foreach (var c in CoinControllers)
                {
                    c.Lineage = lineage;
                }
            },
                _log);

            // == Bind controllers ==
            Listener.OnConnectionAccepted = conn => { DispatchController.AddConnection(conn); };

            foreach (var cc in CoinControllers)
            {
                cc.OnRequestHandled = () => { DispatchController.Wake(); }
            }
            ;

            ChainController.OnRequestHandled = () => { DispatchController.Wake(); };

            DispatchController.OnConnectionAccepted     = conn => conn.Start();
            DispatchController.OnBlockMessageDispatched = () => { ChainController.Wake(); };

            for (var i = 0; i < CoinStores.Length; i++)
            {
                var coinController = CoinControllers[i];
                DispatchController.OnCoinMessageDispatched[i] = () => { coinController.Wake(); };
            }
        }