public async Task MethodCall()
        {
            await DefaultSetup(new CalculatorService(), 1);

            const int first     = 91;
            const int second    = 23;
            int       addResult = first + second;
            int       subResult = first - second;

            var calculatorProxy = new CalculatorProxy <SimpleInMemConnection>(connections[0]);

            var input = new PairedInput
            {
                First  = first,
                Second = second
            };
            var request = new Message <PairedInput>(input);
            IMessage <Output> addResponse = await calculatorProxy.AddAsync(request, System.Threading.CancellationToken.None);

            IMessage <Output> subResponse = await calculatorProxy.SubtractAsync(request, System.Threading.CancellationToken.None);

            Output addOutput = addResponse.Payload.Deserialize();
            Output subOutput = subResponse.Payload.Deserialize();

            Assert.AreEqual(addResult, addOutput.Result);
            Assert.AreEqual(subResult, subOutput.Result);
        }
        public async void TestWithServerAndClientConnections()
        {
            await DefaultSetup(new CalculatorService(), 1);

            IEnumerator <Guid> pairIds = listener.GetPairIds().GetEnumerator();

            pairIds.MoveNext();
            Guid firstPair = pairIds.Current;
            SimpleInMemConnection serverConnection = listener.GetConnection(firstPair, ConnectionType.Server);
            SimpleInMemConnection clientConnection = listener.GetConnection(firstPair, ConnectionType.Client);

            const int first     = 91;
            const int second    = 23;
            int       addResult = first + second;
            int       subResult = first - second;

            var serverProxy = new CalculatorProxy <SimpleInMemConnection>(serverConnection);
            var clientProxy = new CalculatorProxy <SimpleInMemConnection>(clientConnection);


            var input = new PairedInput
            {
                First  = first,
                Second = second
            };
            var request = new Message <PairedInput>(input);
            IMessage <Output> addResponse = await clientProxy.AddAsync(request, System.Threading.CancellationToken.None);

            IMessage <Output> subResponse = await clientProxy.SubtractAsync(request, System.Threading.CancellationToken.None);

            Assert.IsFalse(addResponse.IsError);
            Assert.IsFalse(subResponse.IsError);
            Output addOutput = addResponse.Payload.Deserialize();
            Output subOutput = subResponse.Payload.Deserialize();

            Assert.AreEqual(addResult, addOutput.Result);
            Assert.AreEqual(subResult, subOutput.Result);

            addResponse = await serverProxy.AddAsync(request, System.Threading.CancellationToken.None);

            subResponse = await serverProxy.SubtractAsync(request, System.Threading.CancellationToken.None);

            Assert.IsTrue(addResponse.IsError);
            Assert.IsTrue(subResponse.IsError);
            Error addError = addResponse.Error.Deserialize();
            Error subError = subResponse.Error.Deserialize();

            Assert.AreEqual((int)ErrorCode.METHOD_NOT_FOUND, (int)addError.error_code);
            Assert.AreEqual("Got request for unknown method [unittest.simpleinmem.Calculator.Add].", addError.message);
            Assert.AreEqual((int)ErrorCode.METHOD_NOT_FOUND, (int)subError.error_code);
            Assert.AreEqual("Got request for unknown method [unittest.simpleinmem.Calculator.Subtract].", subError.message);
        }
        public async void TestWithServerAndClientConnections()
        {
            await DefaultSetup(new CalculatorService(), 1);
            IEnumerator<Guid> pairIds = listener.GetPairIds().GetEnumerator();
            pairIds.MoveNext();
            Guid firstPair = pairIds.Current;
            SimpleInMemConnection serverConnection = listener.GetConnection(firstPair, ConnectionType.Server);
            SimpleInMemConnection clientConnection = listener.GetConnection(firstPair, ConnectionType.Client);

            const int first = 91;
            const int second = 23;
            int addResult = first + second;
            int subResult = first - second;

            var serverProxy = new CalculatorProxy<SimpleInMemConnection>(serverConnection);
            var clientProxy = new CalculatorProxy<SimpleInMemConnection>(clientConnection);


            var input = new PairedInput
            {
                First = first,
                Second = second
            };
            var request = new Message<PairedInput>(input);
            IMessage<Output> addResponse = await clientProxy.AddAsync(request, System.Threading.CancellationToken.None);
            IMessage<Output> subResponse = await clientProxy.SubtractAsync(request, System.Threading.CancellationToken.None);
            Assert.IsFalse(addResponse.IsError);
            Assert.IsFalse(subResponse.IsError);
            Output addOutput = addResponse.Payload.Deserialize();
            Output subOutput = subResponse.Payload.Deserialize();
            Assert.AreEqual(addResult, addOutput.Result);
            Assert.AreEqual(subResult, subOutput.Result);

            addResponse = await serverProxy.AddAsync(request, System.Threading.CancellationToken.None);
            subResponse = await serverProxy.SubtractAsync(request, System.Threading.CancellationToken.None);
            Assert.IsTrue(addResponse.IsError);
            Assert.IsTrue(subResponse.IsError);
            Error addError = addResponse.Error.Deserialize();
            Error subError = subResponse.Error.Deserialize();
            Assert.AreEqual((int)ErrorCode.MethodNotFound, (int)addError.error_code);
            Assert.AreEqual("Got request for unknown method [unittest.simpleinmem.Calculator.Add].", addError.message);
            Assert.AreEqual((int)ErrorCode.MethodNotFound, (int)subError.error_code);
            Assert.AreEqual("Got request for unknown method [unittest.simpleinmem.Calculator.Subtract].", subError.message);
        }
        public async Task MultipleClientConnectionsMethodCalls()
        {
            Stopwatch sw = Stopwatch.StartNew();

            await DefaultSetup(new CalculatorService(), 10);

            Task[] connectionTasks = new Task[connections.Length];

            for (int connectionIndex = 0; connectionIndex < connections.Length; connectionIndex++)
            {
                SimpleInMemConnection conn = connections[connectionIndex];
                connectionTasks[connectionIndex] = Task.Run(() =>
                {
                    int taskCount = 25;
                    Task[] tasks  = new Task[taskCount];

                    for (int taskIndex = 0; taskIndex < taskCount; taskIndex++)
                    {
                        tasks[taskIndex] = Task.Run(async() =>
                        {
                            Random rand           = new Random(DateTime.UtcNow.Millisecond);
                            int first             = rand.Next(1, 100);
                            int second            = rand.Next(1, 50);
                            int expectedAddResult = first + second;
                            int expectedSubResult = first - second;
                            var addTraceId        = Guid.NewGuid().ToString();
                            var subTraceId        = Guid.NewGuid().ToString();
                            var calculatorProxy   = new CalculatorProxy <SimpleInMemConnection>(conn);

                            var addInput = new PairedInput
                            {
                                First   = first,
                                Second  = second,
                                TraceId = addTraceId
                            };

                            var subInput = new PairedInput
                            {
                                First   = first,
                                Second  = second,
                                TraceId = subTraceId
                            };

                            Message <PairedInput> addRequest = new Message <PairedInput>(addInput);
                            Message <PairedInput> subRequest = new Message <PairedInput>(subInput);
                            IMessage <Output> addResponse    = await calculatorProxy.AddAsync(addRequest, System.Threading.CancellationToken.None);
                            IMessage <Output> subResponse    = await calculatorProxy.SubtractAsync(subRequest, System.Threading.CancellationToken.None);
                            Output addOutput = addResponse.Payload.Deserialize();
                            Output subOutput = subResponse.Payload.Deserialize();

                            Assert.AreEqual(expectedAddResult, addOutput.Result);
                            Assert.AreEqual(addInput.TraceId, addOutput.TraceId);
                            Assert.AreEqual(expectedSubResult, subOutput.Result);
                            Assert.AreEqual(subInput.TraceId, subOutput.TraceId);
                        });
                    }

                    Task.WaitAll(tasks);
                });
            }

            Task.WaitAll(connectionTasks);
            sw.Stop();
            Console.WriteLine($"{nameof(MultipleClientConnectionsMethodCalls)} - test time: {sw.Elapsed.TotalSeconds}");
        }
        public async Task MultipleClientConnectionsMethodCalls()
        {
            Stopwatch sw = Stopwatch.StartNew();

            await DefaultSetup(new CalculatorService(), 10);

            Task[] connectionTasks = new Task[connections.Length];

            for (int connectionIndex = 0; connectionIndex < connections.Length; connectionIndex++)
            {
                SimpleInMemConnection conn = connections[connectionIndex];
                connectionTasks[connectionIndex] = Task.Run(() =>
                {
                    int taskCount = 25;
                    Task[] tasks = new Task[taskCount];

                    for (int taskIndex = 0; taskIndex < taskCount; taskIndex++)
                    {
                        tasks[taskIndex] = Task.Run(async () =>
                        {
                            Random rand = new Random(DateTime.UtcNow.Millisecond);
                            int first = rand.Next(1, 100);
                            int second = rand.Next(1, 50);
                            int expectedAddResult = first + second;
                            int expectedSubResult = first - second;
                            var addTraceId = Guid.NewGuid().ToString();
                            var subTraceId = Guid.NewGuid().ToString();
                            var calculatorProxy = new CalculatorProxy<SimpleInMemConnection>(conn);

                            var addInput = new PairedInput
                            {
                                First = first,
                                Second = second,
                                TraceId = addTraceId
                            };

                            var subInput = new PairedInput
                            {
                                First = first,
                                Second = second,
                                TraceId = subTraceId
                            };

                            Message<PairedInput> addRequest = new Message<PairedInput>(addInput);
                            Message<PairedInput> subRequest = new Message<PairedInput>(subInput);
                            IMessage<Output> addResponse = await calculatorProxy.AddAsync(addRequest, System.Threading.CancellationToken.None);
                            IMessage<Output> subResponse = await calculatorProxy.SubtractAsync(subRequest, System.Threading.CancellationToken.None);
                            Output addOutput = addResponse.Payload.Deserialize();
                            Output subOutput = subResponse.Payload.Deserialize();

                            Assert.AreEqual(expectedAddResult, addOutput.Result);
                            Assert.AreEqual(addInput.TraceId, addOutput.TraceId);
                            Assert.AreEqual(expectedSubResult, subOutput.Result);
                            Assert.AreEqual(subInput.TraceId, subOutput.TraceId);
                        });
                    }

                    Task.WaitAll(tasks);
                });
            }

            Task.WaitAll(connectionTasks);
            sw.Stop();
            Console.WriteLine($"{nameof(MultipleClientConnectionsMethodCalls)} - test time: {sw.Elapsed.TotalSeconds}");
        }
        public async Task MethodCall()
        {
            await DefaultSetup(new CalculatorService(), 1);

            const int first = 91;
            const int second = 23;
            int addResult = first + second;
            int subResult = first - second;

            var calculatorProxy = new CalculatorProxy<SimpleInMemConnection>(connections[0]);

            var input = new PairedInput
            {
                First = first,
                Second = second
            };
            var request = new Message<PairedInput>(input);
            IMessage<Output> addResponse = await calculatorProxy.AddAsync(request, System.Threading.CancellationToken.None);
            IMessage<Output> subResponse = await calculatorProxy.SubtractAsync(request, System.Threading.CancellationToken.None);
            Output addOutput = addResponse.Payload.Deserialize();
            Output subOutput = subResponse.Payload.Deserialize();
            Assert.AreEqual(addResult, addOutput.Result);
            Assert.AreEqual(subResult, subOutput.Result);
        }