public async Task RestoreClassifier_ReturnsValidObjectToClient()
        {
            var bytes = BitConverter.GetBytes(0);

            Assert.That(bytes.Length, Is.EqualTo(4));

            var endpoint = new Uri("tcp://localhost:9211");

            var data = Functions.NormalRandomDataset(3, 10).Select(x => new
            {
                x = x,
                y = Math.Log(x)
            }).AsQueryable();

            using (var blobs = new InMemoryBlobStore())
            using (var server = new RemoteClassifierTrainingServer(endpoint, blobs))
            using (var client = new RemoteClassifierTrainingClient(endpoint))
            {
                client.Timeout = 10000;

                server.Start();

                var trainingSet = data.CreatePipeline().AsTrainingSet(x => x.x > 10 ? 'a' : 'b');

                var keyAndclassifier = await client.CreateClassifier(trainingSet, true);

                var restoredClassifier = await client.RestoreClassifier(keyAndclassifier.Key, trainingSet.FeaturePipeline.FeatureExtractor, 'a');

                var results = restoredClassifier.Classify(new
                {
                    x = 7d,
                    y = 4.543d
                });
            }
        }
        public async Task CreateClassifier_ThenExtendClassifier_ReturnsTheSameUri()
        {
            var bytes = BitConverter.GetBytes(0);

            Assert.That(bytes.Length, Is.EqualTo(4));

            var endpoint = new Uri("tcp://localhost:9212");

            var data = Functions.NormalRandomDataset(3, 10).Select(x => new
            {
                x = x,
                y = Math.Log(x)
            }).AsQueryable();

            using (var blobs = new InMemoryBlobStore())
            using (var server = new RemoteClassifierTrainingServer(endpoint, blobs))
            using (var client = new RemoteClassifierTrainingClient(endpoint))
            {
#if DEBUG
                client.Timeout = 15000;
#endif
                server.Start();

                var trainingSet1 = data.Take(100).CreatePipeline().AsTrainingSet(x => x.x > 10 ? 'a' : 'b');
                var trainingSet2 = data.Skip(100).CreatePipeline().AsTrainingSet(x => x.x > 10 ? 'a' : 'b');

                var keyAndclassifier = await client.CreateClassifier(trainingSet1, true);

                Assert.That(keyAndclassifier.Value, Is.Not.Null);

                Console.WriteLine(keyAndclassifier.Key);

                var keyAndclassifier2 = await client.ExtendClassifier(trainingSet2, keyAndclassifier.Key);

                Console.WriteLine(keyAndclassifier2.Key);

                Assert.That(keyAndclassifier.Key, Is.EqualTo(keyAndclassifier2.Key));

                Assert.That(keyAndclassifier2.Value, Is.Not.Null);
            }
        }
        public async Task CreateClassifier_SavesOutput()
        {
            var bytes = BitConverter.GetBytes(0);

            Assert.That(bytes.Length, Is.EqualTo(4));

            var endpoint = new Uri("tcp://localhost:9212");

            var data = Functions.NormalRandomDataset(3, 10).Select(x => new
            {
                x = x,
                y = Math.Log(x)
            }).AsQueryable();

            using (var blobs = new InMemoryBlobStore())
            using (var server = new RemoteClassifierTrainingServer(endpoint, blobs))
            using (var client = new RemoteClassifierTrainingClient(endpoint))
            {
#if DEBUGGING
                client.Timeout = 20000;
#endif
                server.Start();

                var trainingSet = data.CreatePipeline().AsTrainingSet(x => x.x > 10 ? 'a' : 'b');

                var keyAndclassifier = await client.CreateClassifier(trainingSet, true);

                // We should be able to restore the raw blob back into a network

                var nn = new MultilayerNetwork(new NetworkParameters(1, 1));

                blobs.Restore(new string(keyAndclassifier.Key.PathAndQuery.Skip(1).ToArray()), nn);

                // We should receive a valid classifier object back

                var cls = keyAndclassifier.Value.Classify(new
                {
                    x = 12.432,
                    y = Math.Log(12.432)
                });

                foreach (var c in cls)
                {
                    Console.WriteLine(c);
                }

                Assert.That(cls.Any());
            }
        }
        public async Task CreateClassifier_TwoClients()
        {
            var bytes = BitConverter.GetBytes(0);

            Assert.That(bytes.Length, Is.EqualTo(4));

            var endpoint = new Uri("tcp://localhost:9214");

            var data = Functions.NormalRandomDataset(3, 10).Select(x => new
            {
                x = x,
                y = Math.Log(x)
            }).AsQueryable();

            using (var blobs = new InMemoryBlobStore())
            using (var server = new RemoteClassifierTrainingServer(endpoint, blobs))
            using (var client1 = new RemoteClassifierTrainingClient(endpoint))
            using (var client2 = new RemoteClassifierTrainingClient(endpoint))
            {
                client1.Timeout = 5000;
                client2.Timeout = 5000;

                server.Start();

                var trainingSet = data.CreatePipeline().AsTrainingSet(x => x.x > 10 ? 'a' : 'b');

                var task1 = client1.CreateClassifier(trainingSet, true);
                var task2 = client2.CreateClassifier(trainingSet, true);
                
                await task1;
                await task2;
            }
        }