Example #1
0
        public void TaskSchedulerIsPreserved()
        {
            var executor = new SingleThreadEventExecutor("test", TimeSpan.FromSeconds(5));
            IEnumerable <Task <int> > tasks = Enumerable.Range(1, 1).Select(i =>
            {
                var completion = new TaskCompletionSource <int>();
                executor.Execute(async() =>
                {
                    try
                    {
                        Assert.True(executor.InEventLoop);
                        await Task.Delay(1);
                        Assert.True(executor.InEventLoop);
                        completion.TrySetResult(0); // all is well
                    }
                    catch (Exception ex)
                    {
                        completion.TrySetException(ex);
                    }
                });
                return(completion.Task);
            });

            Task.WhenAll(tasks).Wait(TimeSpan.FromSeconds(500));
            executor.ShutdownGracefullyAsync();
        }
Example #2
0
        public void FuzzyScheduling(int producerCount, bool perCpu, int taskPerProducer)
        {
            int producerCountFinal = perCpu ? producerCount * Environment.ProcessorCount : producerCount;
            var valueContainer     = new Container <int>
            {
                Value = taskPerProducer * producerCountFinal
            };
            var    mre  = new ManualResetEvent(false);
            Action noop = () =>
            {
                if (--valueContainer.Value <= 0)
                {
                    Assert.Equal(0, valueContainer.Value);
                    mre.Set();
                }
            };
            var scheduler = new SingleThreadEventExecutor("test", TimeSpan.FromSeconds(1));
            IEnumerable <Task <Task> > producers = Enumerable.Range(1, producerCountFinal).Select(x => Task.Factory.StartNew(
                                                                                                      async() =>
            {
                var r = new Random((int)Stopwatch.GetTimestamp() ^ x);
                for (int i = 0; i < taskPerProducer; i++)
                {
                    scheduler.Execute(noop);
                    await Task.Delay(r.Next(10, 100));
                }
            },
                                                                                                      TaskCreationOptions.LongRunning));

            Task.WhenAll(producers).Wait();
            Assert.True(mre.WaitOne(TimeSpan.FromSeconds(5)));
        }
        public void TaskSchedulerIsPreserved()
        {
            var executor = new SingleThreadEventExecutor("test", TimeSpan.FromSeconds(5));
            IEnumerable <Task <int> > tasks = Enumerable.Range(1, 1).Select(async i =>
            {
                //Clear SynchronizationContext set by xunit
                SynchronizationContext.SetSynchronizationContext(null);

                var completion = new TaskCompletionSource();
                executor.Execute(async() =>
                {
                    try
                    {
                        Assert.True(executor.InEventLoop);
                        await Task.Delay(1);
                        Assert.True(executor.InEventLoop);
                        completion.TryComplete(); // all is well
                    }
                    catch (Exception ex)
                    {
                        completion.TrySetException(ex);
                    }
                });
                await completion.Task;
                Assert.False(executor.InEventLoop);
                return(i);
            });

            Task.WhenAll(tasks).Wait(TimeSpan.FromSeconds(500));
            executor.ShutdownGracefullyAsync();
        }
Example #4
0
        public static void BuggyImplementation(this IInternalLogger logger, SingleThreadEventExecutor eventExecutor)
        {
            var type = eventExecutor.GetType();

            logger.Error(
                $"Buggy {type.Name} implementation; {type.Name}.ConfirmShutdown() must be called "
                + "before run() implementation terminates.");
        }
Example #5
0
        public async Task TlsWrite(int[] frameLengths, bool isClient, SslProtocols serverProtocol, SslProtocols clientProtocol)
        {
            this.Output.WriteLine($"frameLengths: {string.Join(", ", frameLengths)}");
            this.Output.WriteLine($"isClient: {isClient}");
            this.Output.WriteLine($"serverProtocol: {serverProtocol}");
            this.Output.WriteLine($"clientProtocol: {clientProtocol}");

            var writeStrategy = new AsIsWriteStrategy();

            this.Output.WriteLine($"writeStrategy: {writeStrategy}");

            var executor = new SingleThreadEventExecutor("test executor", TimeSpan.FromMilliseconds(10));

            try
            {
                var writeTasks = new List <Task>();
                var pair       = await SetupStreamAndChannelAsync(isClient, executor, writeStrategy, serverProtocol, clientProtocol, writeTasks);

                EmbeddedChannel ch           = pair.Item1;
                SslStream       driverStream = pair.Item2;

                int         randomSeed     = Environment.TickCount;
                var         random         = new Random(randomSeed);
                IByteBuffer expectedBuffer = Unpooled.Buffer(16 * 1024);
                foreach (IEnumerable <int> lengths in frameLengths.Split(x => x < 0))
                {
                    ch.WriteOutbound(lengths.Select(len =>
                    {
                        var data = new byte[len];
                        random.NextBytes(data);
                        expectedBuffer.WriteBytes(data);
                        return((object)Unpooled.WrappedBuffer(data));
                    }).ToArray());
                }

                IByteBuffer finalReadBuffer = Unpooled.Buffer(16 * 1024);
                var         readBuffer      = new byte[16 * 1024 * 10];
                await ReadOutboundAsync(
                    async() =>
                {
                    int read = await driverStream.ReadAsync(readBuffer, 0, readBuffer.Length);
                    return(Unpooled.WrappedBuffer(readBuffer, 0, read));
                },
                    expectedBuffer.ReadableBytes, finalReadBuffer, TestTimeout);

                bool isEqual = ByteBufferUtil.Equals(expectedBuffer, finalReadBuffer);
                if (!isEqual)
                {
                    Assert.True(isEqual, $"---Expected:\n{ByteBufferUtil.PrettyHexDump(expectedBuffer)}\n---Actual:\n{ByteBufferUtil.PrettyHexDump(finalReadBuffer)}");
                }
                driverStream.Dispose();
                Assert.False(ch.Finish());
            }
            finally
            {
                await executor.ShutdownGracefullyAsync(TimeSpan.Zero, TimeSpan.Zero);
            }
        }
Example #6
0
        public async Task TlsWrite(int[] frameLengths, bool isClient, SslProtocols protocol, string targetHost)
        {
            this.Output.WriteLine("frameLengths: " + string.Join(", ", frameLengths));
            this.Output.WriteLine($"protocol: {protocol}");
            this.Output.WriteLine($"targetHost: {targetHost}");

            var writeStrategy = new AsIsWriteStrategy();
            var executor      = new SingleThreadEventExecutor("test executor", TimeSpan.FromMilliseconds(10));

            try
            {
                var writeTasks = new List <Task>();
                var pair       = await SetupStreamAndChannelAsync(isClient, executor, writeStrategy, protocol, writeTasks, targetHost);

                EmbeddedChannel ch           = pair.Item1;
                SslStream       driverStream = pair.Item2;

                int         randomSeed     = Environment.TickCount;
                var         random         = new Random(randomSeed);
                IByteBuffer expectedBuffer = Unpooled.Buffer(16 * 1024);
                foreach (IEnumerable <int> lengths in frameLengths.Split(x => x < 0))
                {
                    ch.WriteOutbound(lengths.Select(len =>
                    {
                        var data = new byte[len];
                        random.NextBytes(data);
                        expectedBuffer.WriteBytes(data);
                        return((object)Unpooled.WrappedBuffer(data));
                    }).ToArray());
                }

                IByteBuffer finalReadBuffer = Unpooled.Buffer(16 * 1024);
                var         readBuffer      = new byte[16 * 1024 * 10];
                await ReadOutboundAsync(
                    async() =>
                {
                    int read = await driverStream.ReadAsync(readBuffer, 0, readBuffer.Length);
                    return(Unpooled.WrappedBuffer(readBuffer, 0, read));
                },
                    expectedBuffer.ReadableBytes, finalReadBuffer, TestTimeout);

                Assert.True(ByteBufferUtil.Equals(expectedBuffer, finalReadBuffer), $"---Expected:\n{ByteBufferUtil.PrettyHexDump(expectedBuffer)}\n---Actual:\n{ByteBufferUtil.PrettyHexDump(finalReadBuffer)}");

                if (!isClient)
                {
                    // check if snihandler got replaced with tls handler
                    Assert.Null(ch.Pipeline.Get <SniHandler>());
                    Assert.NotNull(ch.Pipeline.Get <TlsHandler>());
                }

                driverStream.Dispose();
            }
            finally
            {
                await executor.ShutdownGracefullyAsync(TimeSpan.FromMilliseconds(100), TimeSpan.FromMilliseconds(300));
            }
        }
Example #7
0
        public async Task ScheduledTaskFiresOnTime(bool scheduleFromExecutor)
        {
            var         scheduler    = new SingleThreadEventExecutor(null, TimeSpan.FromMinutes(1));
            var         promise      = new TaskCompletionSource();
            Func <Task> scheduleFunc = () => scheduler.ScheduleAsync(() => promise.Complete(), TimeSpan.FromMilliseconds(100));
            Task        task         = scheduleFromExecutor ? await scheduler.SubmitAsync(scheduleFunc) : scheduleFunc();

            await Task.WhenAny(task, Task.Delay(TimeSpan.FromMilliseconds(300)));

            Assert.True(task.IsCompleted);
        }
Example #8
0
        public void STE_should_not_run_cancelled_shutdown_hooks()
        {
            var executor = new SingleThreadEventExecutor("Foo" + ThreadLocalRandom.Current.Next(),
                                                         TimeSpan.FromMilliseconds(100));

            var hook = new MyHook();

            executor.AddShutdownHook(hook);
            executor.RemoveShutdownHook(hook);
            executor.GracefulShutdownAsync().Wait();
            Assert.False(hook.WasExecuted);
        }
Example #9
0
        public void STE_should_complete_task_when_operation_is_completed()
        {
            var executor = new SingleThreadEventExecutor("Foo" + ThreadNameCounter.GetAndIncrement(),
                                                         TimeSpan.FromMilliseconds(100));

            Func <bool> myFunc = () => true;
            var         task   = executor.SubmitAsync(myFunc);

            Assert.True(task.Wait(200), "Should have completed task in under 200 milliseconds");
            Assert.True(task.Result);
            executor.GracefulShutdownAsync();
        }
Example #10
0
        public async Task ShutdownWhileIdle(int delayInMs)
        {
            var scheduler = new SingleThreadEventExecutor("test", TimeSpan.FromMilliseconds(10));

            if (delayInMs > 0)
            {
                Thread.Sleep(delayInMs);
            }
            Task shutdownTask = scheduler.ShutdownGracefullyAsync(TimeSpan.FromMilliseconds(50), TimeSpan.FromSeconds(1));
            await Task.WhenAny(shutdownTask, Task.Delay(TimeSpan.FromSeconds(5)));

            Assert.True(shutdownTask.IsCompleted);
        }
Example #11
0
        public async Task TlsRead(int[] frameLengths, bool isClient, IWriteStrategy writeStrategy, SslProtocols protocol, string targetHost)
        {
            this.Output.WriteLine($"frameLengths: {string.Join(", ", frameLengths)}");
            this.Output.WriteLine($"writeStrategy: {writeStrategy}");
            this.Output.WriteLine($"protocol: {protocol}");
            this.Output.WriteLine($"targetHost: {targetHost}");

            var executor = new SingleThreadEventExecutor("test executor", TimeSpan.FromMilliseconds(10));

            try
            {
                var writeTasks = new List <Task>();
                var pair       = await SetupStreamAndChannelAsync(isClient, executor, writeStrategy, protocol, writeTasks, targetHost).WithTimeout(TimeSpan.FromSeconds(10));

                EmbeddedChannel ch           = pair.Item1;
                SslStream       driverStream = pair.Item2;

                int         randomSeed     = Environment.TickCount;
                var         random         = new Random(randomSeed);
                IByteBuffer expectedBuffer = Unpooled.Buffer(16 * 1024);
                foreach (int len in frameLengths)
                {
                    var data = new byte[len];
                    random.NextBytes(data);
                    expectedBuffer.WriteBytes(data);
                    await driverStream.WriteAsync(data, 0, data.Length).WithTimeout(TimeSpan.FromSeconds(5));
                }
                await Task.WhenAll(writeTasks).WithTimeout(TimeSpan.FromSeconds(5));

                IByteBuffer finalReadBuffer = Unpooled.Buffer(16 * 1024);
#pragma warning disable CS1998 // 异步方法缺少 "await" 运算符,将以同步方式运行
                await ReadOutboundAsync(async() => ch.ReadInbound <IByteBuffer>(), expectedBuffer.ReadableBytes, finalReadBuffer, TestTimeout);

#pragma warning restore CS1998 // 异步方法缺少 "await" 运算符,将以同步方式运行
                Assert.True(ByteBufferUtil.Equals(expectedBuffer, finalReadBuffer), $"---Expected:\n{ByteBufferUtil.PrettyHexDump(expectedBuffer)}\n---Actual:\n{ByteBufferUtil.PrettyHexDump(finalReadBuffer)}");

                if (!isClient)
                {
                    // check if snihandler got replaced with tls handler
                    Assert.Null(ch.Pipeline.Get <SniHandler>());
                    Assert.NotNull(ch.Pipeline.Get <TlsHandler>());
                }

                driverStream.Dispose();
                Assert.False(ch.Finish());
            }
            finally
            {
                await executor.ShutdownGracefullyAsync(TimeSpan.Zero, TimeSpan.Zero);
            }
        }
        public async Task TlsRead(int[] frameLengths, bool isClient, IWriteStrategy writeStrategy, SslProtocols serverProtocol, SslProtocols clientProtocol)
        {
            this.Output.WriteLine($"frameLengths: {string.Join(", ", frameLengths)}");
            this.Output.WriteLine($"isClient: {isClient}");
            this.Output.WriteLine($"writeStrategy: {writeStrategy}");
            this.Output.WriteLine($"serverProtocol: {serverProtocol}");
            this.Output.WriteLine($"clientProtocol: {clientProtocol}");

            var executor = new SingleThreadEventExecutor("test executor", TimeSpan.FromMilliseconds(10));

            try
            {
                var writeTasks = new List <Task>();
                var pair       = await SetupStreamAndChannelAsync(isClient, executor, writeStrategy, serverProtocol, clientProtocol, writeTasks).WithTimeout(TimeSpan.FromSeconds(10));

                EmbeddedChannel ch           = pair.Item1;
                SslStream       driverStream = pair.Item2;

                int         randomSeed     = Environment.TickCount;
                var         random         = new Random(randomSeed);
                IByteBuffer expectedBuffer = Unpooled.Buffer(16 * 1024);
                foreach (int len in frameLengths)
                {
                    var data = new byte[len];
                    random.NextBytes(data);
                    expectedBuffer.WriteBytes(data);
                    await driverStream.WriteAsync(data, 0, data.Length).WithTimeout(TimeSpan.FromSeconds(5));
                }
                await Task.WhenAll(writeTasks).WithTimeout(TimeSpan.FromSeconds(5));

                IByteBuffer finalReadBuffer = Unpooled.Buffer(16 * 1024);
                await ReadOutboundAsync(async() => ch.ReadInbound <IByteBuffer>(), expectedBuffer.ReadableBytes, finalReadBuffer, TestTimeout);

                bool isEqual = ByteBufferUtil.Equals(expectedBuffer, finalReadBuffer);
                if (!isEqual)
                {
                    Assert.True(isEqual, $"---Expected:\n{ByteBufferUtil.PrettyHexDump(expectedBuffer)}\n---Actual:\n{ByteBufferUtil.PrettyHexDump(finalReadBuffer)}");
                }
                driverStream.Dispose();
                Assert.False(ch.Finish());
            }
            finally
            {
                await executor.ShutdownGracefullyAsync(TimeSpan.Zero, TimeSpan.Zero);
            }
        }
Example #13
0
        static StaticAssignmentMultiplexer()
        {
            int cores = 0;

            foreach (var item in new System.Management.ManagementObjectSearcher("Select * from Win32_Processor").Get())
            {
                cores += int.Parse(item["NumberOfCores"].ToString());
            }

            for (int i = 1; i <= cores; i++)
            {
                int n = i;
                IScheduledExecutorService thread = new SingleThreadEventExecutor("Session Thread " + n, TimeSpan.FromMilliseconds(5));

                threads.Add(thread);
            }
        }
Example #14
0
        public void STE_should_run_shutdown_hooks()
        {
            var executor = new SingleThreadEventExecutor("Foo" + ThreadLocalRandom.Current.Next(),
                                                         TimeSpan.FromMilliseconds(100));

            var hook = new MyHook();

            executor.AddShutdownHook(hook);

            // added a sanity check here to make sure that normal scheduled operations can run
            Func <bool> myFunc = () => true;
            var         task   = executor.SubmitAsync(myFunc);

            Assert.True(task.Wait(200), "Should have completed task in under 200 milliseconds");
            Assert.True(task.Result);
            // end sanity check, begin actual test

            executor.GracefulShutdownAsync().Wait();
            Assert.True(hook.WasExecuted);
        }
Example #15
0
        public void STE_should_execute_scheduled_tasks_on_time()
        {
            var counter  = new AtomicCounter(0);
            var executor = new SingleThreadEventExecutor("Foo" + ThreadNameCounter.GetAndIncrement(),
                                                         TimeSpan.FromMilliseconds(100));
            Action <object> increment = o => ((AtomicCounter)o).GetAndIncrement();

            // schedule a delayed operation
            var checkCounter = executor.ScheduleAsync(o => Assert.True(((AtomicCounter)o).Current == 4), counter,
                                                      TimeSpan.FromMilliseconds(40));

            // schedule 4 immediate operations
            executor.Execute(increment, counter);
            executor.Execute(increment, counter);
            executor.Execute(increment, counter);
            executor.Execute(increment, counter);

            // delay should run after the first 4 previous
            checkCounter.Wait(TimeSpan.FromMilliseconds(100));
        }
Example #16
0
        public async Task ScheduledTaskFiresOnTimeWhileBusy()
        {
            var    scheduler       = new SingleThreadEventExecutor(null, TimeSpan.FromMilliseconds(10));
            var    promise         = new TaskCompletionSource();
            Action selfQueueAction = null;

            selfQueueAction = () =>
            {
                if (!promise.Task.IsCompleted)
                {
                    scheduler.Execute(selfQueueAction);
                }
            };

            scheduler.Execute(selfQueueAction);
            Task task = scheduler.ScheduleAsync(() => promise.Complete(), TimeSpan.FromMilliseconds(100));
            await Task.WhenAny(task, Task.Delay(TimeSpan.FromMilliseconds(300)));

            Assert.True(task.IsCompleted);
        }
        public void FlushNotDiscarded()
        {
            var executorService = new SingleThreadEventExecutor("Discarded", TimeSpan.FromMilliseconds(100));

            try
            {
                _sb = new ServerBootstrap();
                _sb.Group(new MultithreadEventLoopGroup(1), new MultithreadEventLoopGroup());
                _sb.Channel <TcpServerSocketChannel>();
                _sb.ChildHandler(new ActionChannelInitializer <IChannel>(ch =>
                {
                    ch.Pipeline.AddLast(new Http2FrameCodecBuilder(true).Build());
                    ch.Pipeline.AddLast(new Http2MultiplexHandler(new TestChannelInboundHandlerAdapter(executorService)));
                }));
                var loopback = IPAddress.IPv6Loopback;
                _serverChannel = _sb.BindAsync(loopback, 0).GetAwaiter().GetResult();

                CountdownEvent latch = new CountdownEvent(1);

                _bs = new Bootstrap();
                _bs.Group(new MultithreadEventLoopGroup());
                _bs.Channel <TcpSocketChannel>();
                _bs.Handler(new ActionChannelInitializer <IChannel>(ch =>
                {
                    ch.Pipeline.AddLast(new Http2FrameCodecBuilder(false).Build());
                    ch.Pipeline.AddLast(new Http2MultiplexHandler(DISCARD_HANDLER.Instance));
                }));
                var port = ((IPEndPoint)_serverChannel.LocalAddress).Port;
                var ccf  = _bs.ConnectAsync(loopback, port);
                _clientChannel = ccf.GetAwaiter().GetResult();
                Http2StreamChannelBootstrap h2Bootstrap = new Http2StreamChannelBootstrap(_clientChannel);
                h2Bootstrap.Handler(new TestFlushNotDiscardedHandler(latch));
                IHttp2StreamChannel streamChannel = h2Bootstrap.OpenAsync().GetAwaiter().GetResult();
                streamChannel.WriteAndFlushAsync(new DefaultHttp2HeadersFrame(new DefaultHttp2Headers(), true)).GetAwaiter().GetResult();
                latch.Wait();
            }
            finally
            {
                executorService.ShutdownGracefullyAsync(TimeSpan.FromMilliseconds(100), TimeSpan.FromSeconds(5));
            }
        }
 public TestChannelInboundHandlerAdapter(SingleThreadEventExecutor executorService)
 {
     _executorService = executorService;
 }