public async void Test1()
        {
            IThrottleQueue tq = new ThrottleQueue(1);
            var            t1 = await tq.QueueUp();

            Assert.Equal(0, tq.ItemsWaiting);
            Assert.Equal(1, tq.ItemsRunning);
            Console.WriteLine(t1);
            Task.Factory.StartNew(() => {
                Thread.Sleep(1000);
                tq.Finish(t1);
                Assert.Equal(tq.ItemsWaiting, 0);
                Thread.Sleep(2000);
            });
            var t2 = await tq.QueueUp();

            Console.WriteLine(t2);
            Assert.Equal(1, tq.ItemsRunning);
            tq.Finish(t2);
            Assert.Equal(0, tq.ItemsRunning);
            Assert.NotEqual(t1.ToString(), t2.ToString());
        }
Пример #2
0
        protected Puppet(PuppetOptions options, ILogger <Puppet> logger, ILoggerFactory loggerFactory)
        {
            Options = options;
            Logger  = logger;
            State   = new StateSwitch(GetType().Name, loggerFactory.CreateLogger <StateSwitch>());
            Memory  = new MemoryCard((MemoryCardOptions?)null, loggerFactory.CreateLogger <MemoryCard>(), loggerFactory);
            //load here is for testing only
            Memory.Load()
            .ContinueWith(task =>
            {
                if (!task.IsFaulted)
                {
                    if (Logger.IsEnabled(LogLevel.Trace))
                    {
                        Logger.LogTrace("constructor() memory.load() done");
                    }
                }
                else
                {
                    Logger.LogWarning("constructor() memory.load() rejection", task.Exception);
                }
            });
            // 1. Setup Watchdog
            // puppet implementation class only need to do one thing:
            // feed the watchdog by `this.emit('heartbeat', ...)`
            Watchdog = new Watchdog <object, EventHeartbeatPayload>(loggerFactory.CreateLogger <Watchdog <object, EventHeartbeatPayload> >());
            _        = this.On <Puppet, EventHeartbeatPayload>("heartbeat", payload => _ = Watchdog.Feed(payload));
            _        = Watchdog
                       .On <Watchdog <object, EventHeartbeatPayload>, EventHeartbeatPayload>("reset", lastFood =>
            {
                Logger.LogWarning($"constructor() watchdog.on(reset) reason: {JsonConvert.SerializeObject(lastFood)}");
                _ = Emit("reset", lastFood);
            });
            // 2. Setup `reset` Event via a 1 second Throttle Queue:
            _resetThrottleQueue = new ThrottleQueue <string>(TimeSpan.FromSeconds(1));

            // 2.2. handle all `reset` events via the resetThrottleQueue
            _ = this.On <Puppet, EventHeartbeatPayload>("reset", payload =>
            {
                if (Logger.IsEnabled(LogLevel.Trace))
                {
                    Logger.LogTrace($"constructor() this.on(reset) payload: {JsonConvert.SerializeObject(payload)}");
                }
                _resetThrottleQueue.OnNext(payload.Data);
            });

            // 2.3. call reset() and then ignore the following `reset` event for 1 second
            _resetThrottleQueue.Subscribe(reason =>
            {
                if (Logger.IsEnabled(LogLevel.Trace))
                {
                    Logger.LogTrace($"constructor() resetThrottleQueue.subscribe() reason: \"{reason}\"");
                }
                Reset(reason);
            });

            // 3. Setup LRU Caches
            CacheContactPayload        = new LRUCache <string, ContactPayload>(3000);
            CacheFriendshipPayload     = new LRUCache <string, FriendshipPayload>(3000);
            CacheMessagePayload        = new LRUCache <string, MessagePayload>(3000);
            CacheRoomPayload           = new LRUCache <string, RoomPayload>(3000);
            CacheRoomMemberPayload     = new LRUCache <string, RoomMemberPayload>(3000);
            CacheRoomInvitationPayload = new LRUCache <string, RoomInvitationPayload>(3000);
        }