Repository: thrift
Updated Branches:
  refs/heads/master 55f976e0d -> b62247e0e


THRIFT-4039 Update of Apache Thrift .Net Core lib
Client: NetCore
Patch: Volodymyr Gotra <vgo...@gmail.com>

This closes #1163

Changes:
- Added framed transport, updated docs, updated global.json with SDKversion
- Added usage to multiplexer to tutorial
- Changed sdk to current sdk 1.0.0-preview2-1-003177


Project: http://git-wip-us.apache.org/repos/asf/thrift/repo
Commit: http://git-wip-us.apache.org/repos/asf/thrift/commit/b62247e0
Tree: http://git-wip-us.apache.org/repos/asf/thrift/tree/b62247e0
Diff: http://git-wip-us.apache.org/repos/asf/thrift/diff/b62247e0

Branch: refs/heads/master
Commit: b62247e0ea23139a9922a1de965357907319e937
Parents: 55f976e
Author: Volodymyr Gotra <vgo...@gmail.com>
Authored: Mon Jan 16 02:34:28 2017 +0200
Committer: Jens Geyer <je...@apache.org>
Committed: Wed Jan 25 00:04:45 2017 +0100

----------------------------------------------------------------------
 lib/netcore/README.md                           |  30 ++-
 lib/netcore/Thrift/TBaseClient.cs               |   1 +
 .../Transports/Client/TFramedClientTransport.cs |   2 -
 .../Transports/Server/TServerFramedTransport.cs | 150 +++++++++++++
 lib/netcore/global.json                         |   5 +-
 test/netcore/README.md                          |  17 ++
 test/netcore/global.json                        |   5 +-
 tutorial/netcore/Client/Program.cs              | 214 +++++++++++++------
 .../Client/Properties/launchSettings.json       |   2 +-
 tutorial/netcore/README.md                      |  48 ++++-
 tutorial/netcore/Server/Program.cs              |  80 +++++--
 .../Server/Properties/launchSettings.json       |   2 +-
 tutorial/netcore/global.json                    |   5 +-
 13 files changed, 445 insertions(+), 116 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/thrift/blob/b62247e0/lib/netcore/README.md
----------------------------------------------------------------------
diff --git a/lib/netcore/README.md b/lib/netcore/README.md
index ae926e9..a2b19a8 100644
--- a/lib/netcore/README.md
+++ b/lib/netcore/README.md
@@ -2,20 +2,34 @@
 
 Thrift client library ported to Microsoft .Net Core 
 
+# Content
+- Tests/Thrift.PublicInterfaces.Compile.Tests - project for checking public 
interfaces during adding changes to Thrift library
+- Thrift - Thrift library 
+
+# Reused components 
+- NET Core Standard 1.6 (SDK 1.0.0-preview2-003121)
+- NET Core App 1.1
+
 # How to build
 
-* Download the latest version of dotnet from 
https://www.microsoft.com/net/core (it can be 
https://go.microsoft.com/fwlink/?LinkID=809122 in case of VS Code)
-* Install downloaded version of dotnet
-* Clone repo
-* Run **build.sh** or **build.cmd** from the root of cloned repository
-* Check tests in **src/Tests** folder
-* Continue with /tutorials/netcore 
+- Download and install .NET Core SDK for your platform 
https://www.microsoft.com/net/core#windowsvs2015
+- Ensure that you have thrift.exe which supports netcore lib and it added to 
PATH 
+- Go to current folder 
+- Run **build.sh** or **build.cmd** from the root of cloned repository
+- Check tests in **src/Tests** folder
+- Continue with /tutorials/netcore 
 
 #Notes
 
-* No Silverlight suport, no longer supported by Microsoft
+- Migration to .NET Standard 2.0 planned for later (Q1 2017) according to  
https://blogs.msdn.microsoft.com/dotnet/2016/09/26/introducing-net-standard/
+- Possible adding additional platforms after stabilization of .NET Core 
(runtimes, platforms (Red Haat Linux, OpenSuse, etc.) 
 
 #Known issues
 
-* Framed transport not fully implemenented yet
+- In trace logging mode you can see some not important internal exceptions
+- Ubuntu 16.10 still not supported fully 
+- There is some problems with .NET Core CLI and usage specific -r|--runtime 
for building and publishing projects with different target frameworks 
(netstandard1.6 and netcoreapp1.1) 
+
+# Troubleshouting 
 
+It's possible to change dotnet SDK version for building for solution (in 
**global.json**). Just run **dotnet --info** to check your current version (or 
check your dotnet sdk folder for installed versions)
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/thrift/blob/b62247e0/lib/netcore/Thrift/TBaseClient.cs
----------------------------------------------------------------------
diff --git a/lib/netcore/Thrift/TBaseClient.cs 
b/lib/netcore/Thrift/TBaseClient.cs
index 24e08ce..5b338c6 100644
--- a/lib/netcore/Thrift/TBaseClient.cs
+++ b/lib/netcore/Thrift/TBaseClient.cs
@@ -35,6 +35,7 @@ namespace Thrift
         private readonly TProtocol _outputProtocol;
         private bool _isDisposed;
         private int _seqId;
+        public readonly Guid ClientId = Guid.NewGuid();
 
         protected TBaseClient(TProtocol inputProtocol, TProtocol 
outputProtocol)
         {

http://git-wip-us.apache.org/repos/asf/thrift/blob/b62247e0/lib/netcore/Thrift/Transports/Client/TFramedClientTransport.cs
----------------------------------------------------------------------
diff --git a/lib/netcore/Thrift/Transports/Client/TFramedClientTransport.cs 
b/lib/netcore/Thrift/Transports/Client/TFramedClientTransport.cs
index 514c1a6..f54a42a 100644
--- a/lib/netcore/Thrift/Transports/Client/TFramedClientTransport.cs
+++ b/lib/netcore/Thrift/Transports/Client/TFramedClientTransport.cs
@@ -37,8 +37,6 @@ namespace Thrift.Transports.Client
 
         public TFramedClientTransport(TClientTransport transport)
         {
-            throw new NotImplementedException("TFramedClientTransport is not 
fully ready for usage");
-
             if (transport == null)
             {
                 throw new ArgumentNullException(nameof(transport));

http://git-wip-us.apache.org/repos/asf/thrift/blob/b62247e0/lib/netcore/Thrift/Transports/Server/TServerFramedTransport.cs
----------------------------------------------------------------------
diff --git a/lib/netcore/Thrift/Transports/Server/TServerFramedTransport.cs 
b/lib/netcore/Thrift/Transports/Server/TServerFramedTransport.cs
new file mode 100644
index 0000000..0b86e9e
--- /dev/null
+++ b/lib/netcore/Thrift/Transports/Server/TServerFramedTransport.cs
@@ -0,0 +1,150 @@
+// Licensed to the Apache Software Foundation(ASF) under one
+// or more contributor license agreements.See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License. You may obtain a copy of the License at
+// 
+//     http://www.apache.org/licenses/LICENSE-2.0
+// 
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied. See the License for the
+// specific language governing permissions and limitations
+// under the License.
+
+using System;
+using System.Net;
+using System.Net.Sockets;
+using System.Threading;
+using System.Threading.Tasks;
+using Thrift.Transports.Client;
+
+namespace Thrift.Transports.Server
+{
+    // ReSharper disable once InconsistentNaming
+    public class TServerFramedTransport : TServerTransport
+    {
+        private readonly int _clientTimeout;
+        private readonly int _port;
+        private TcpListener _server;
+
+        public TServerFramedTransport(TcpListener listener)
+            : this(listener, 0)
+        {
+        }
+
+        public TServerFramedTransport(TcpListener listener, int clientTimeout)
+        {
+            _server = listener;
+            _clientTimeout = clientTimeout;
+        }
+
+        public TServerFramedTransport(int port)
+            : this(port, 0)
+        {
+        }
+
+        public TServerFramedTransport(int port, int clientTimeout)
+        {
+            _port = port;
+            _clientTimeout = clientTimeout;
+            try
+            {
+                // Make server socket
+                _server = new TcpListener(IPAddress.Any, _port);
+                _server.Server.NoDelay = true;
+            }
+            catch (Exception)
+            {
+                _server = null;
+                throw new TTransportException("Could not create ServerSocket 
on port " + port + ".");
+            }
+        }
+
+        public override void Listen()
+        {
+            // Make sure not to block on accept
+            if (_server != null)
+            {
+                try
+                {
+                    _server.Start();
+                }
+                catch (SocketException sx)
+                {
+                    throw new TTransportException("Could not accept on 
listening socket: " + sx.Message);
+                }
+            }
+        }
+
+        public override bool IsClientPending()
+        {
+            return _server.Pending();
+        }
+
+        protected override async Task<TClientTransport> 
AcceptImplementationAsync(CancellationToken cancellationToken)
+        {
+            if (cancellationToken.IsCancellationRequested)
+            {
+                return await 
Task.FromCanceled<TClientTransport>(cancellationToken);
+            }
+
+            if (_server == null)
+            {
+                throw new 
TTransportException(TTransportException.ExceptionType.NotOpen, "No underlying 
server socket.");
+            }
+
+            try
+            {
+                TFramedClientTransport tSocketTransport = null;
+                var tcpClient = await _server.AcceptTcpClientAsync();
+
+                try
+                {
+                    tSocketTransport = new TFramedClientTransport(new 
TSocketClientTransport(tcpClient)
+                    {
+                        Timeout = _clientTimeout
+                    });
+
+                    return tSocketTransport;
+                }
+                catch (Exception)
+                {
+                    if (tSocketTransport != null)
+                    {
+                        tSocketTransport.Dispose();
+                    }
+                    else //  Otherwise, clean it up ourselves.
+                    {
+                        ((IDisposable) tcpClient).Dispose();
+                    }
+
+                    throw;
+                }
+            }
+            catch (Exception ex)
+            {
+                throw new TTransportException(ex.ToString());
+            }
+        }
+
+        public override void Close()
+        {
+            if (_server != null)
+            {
+                try
+                {
+                    _server.Stop();
+                }
+                catch (Exception ex)
+                {
+                    throw new TTransportException("WARNING: Could not close 
server socket: " + ex);
+                }
+                _server = null;
+            }
+        }
+    }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/thrift/blob/b62247e0/lib/netcore/global.json
----------------------------------------------------------------------
diff --git a/lib/netcore/global.json b/lib/netcore/global.json
index 8c09275..e516241 100644
--- a/lib/netcore/global.json
+++ b/lib/netcore/global.json
@@ -1,3 +1,6 @@
 {
-  "projects": [ "." ]
+  "projects": [ "." ],
+  "sdk": {
+    "version": "1.0.0-preview2-1-003177" // "1.0.0-preview2-003121", 
"1.0.0-preview4-004233"
+  }
 }
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/thrift/blob/b62247e0/test/netcore/README.md
----------------------------------------------------------------------
diff --git a/test/netcore/README.md b/test/netcore/README.md
new file mode 100644
index 0000000..230897f
--- /dev/null
+++ b/test/netcore/README.md
@@ -0,0 +1,17 @@
+# Apache Thrift net-core-lib tests
+
+Tests for Thrift client library ported to Microsoft .Net Core 
+
+# Content
+- ThriftTest - tests for Thrift library 
+
+# Reused components 
+- NET Core Standard 1.6 (SDK 1.0.0-preview2-003121)
+- NET Core App 1.1
+
+# How to build
+- Download and install .NET Core SDK for your platform 
https://www.microsoft.com/net/core#windowsvs2015 (archive for SDK 
1.0.0-preview2-003121 located by: 
https://github.com/dotnet/core/blob/master/release-notes/download-archive.md)
+- Ensure that you have thrift.exe which supports netcore lib and it added to 
PATH 
+- Go to current folder 
+- Run **build.sh** or **build.cmd** from the root of cloned repository
+

http://git-wip-us.apache.org/repos/asf/thrift/blob/b62247e0/test/netcore/global.json
----------------------------------------------------------------------
diff --git a/test/netcore/global.json b/test/netcore/global.json
index 53f1811..42ed97a 100644
--- a/test/netcore/global.json
+++ b/test/netcore/global.json
@@ -1,3 +1,6 @@
 {
-  "projects": [ "../../lib/netcore" ]
+  "projects": [ "../../lib/netcore" ],
+   "sdk": {
+    "version": "1.0.0-preview2-1-003177" // "1.0.0-preview2-003121", 
"1.0.0-preview4-004233"
+  }
 }
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/thrift/blob/b62247e0/tutorial/netcore/Client/Program.cs
----------------------------------------------------------------------
diff --git a/tutorial/netcore/Client/Program.cs 
b/tutorial/netcore/Client/Program.cs
index 5485e95..ae1837b 100644
--- a/tutorial/netcore/Client/Program.cs
+++ b/tutorial/netcore/Client/Program.cs
@@ -36,17 +36,17 @@ namespace Client
 {
     public class Program
     {
-        private static readonly ILogger Logger = new 
LoggerFactory().CreateLogger(nameof(Client));
+        private static readonly ILogger Logger = new 
LoggerFactory().AddConsole().AddDebug().CreateLogger(nameof(Client));
 
         private static void DisplayHelp()
         {
-            Console.WriteLine(@"
+            Logger.LogInformation(@"
 Usage: 
     Client.exe -h
         will diplay help information 
 
-    Client.exe -t:<transport> -p:<protocol>
-        will run client with specified arguments (tcp transport and binary 
protocol by default)
+    Client.exe -t:<transport> -p:<protocol> -mc:<numClients>
+        will run client with specified arguments (tcp transport and binary 
protocol by default) and with 1 client
 
 Options:
     -t (transport): 
@@ -55,11 +55,16 @@ Options:
         namedpipe - namedpipe transport will be used (pipe address - "".test"")
         http - http transport will be used (address - 
""http://localhost:9090"";)        
         tcptls - tcp tls transport will be used (host - ""localhost"", port - 
9090)
+        framed - tcp framed transport will be used (host - ""localhost"", port 
- 9090)
 
     -p (protocol): 
         binary - (default) binary protocol will be used
         compact - compact protocol will be used
         json - json protocol will be used
+        multiplexed - multiplexed protocol will be used
+
+    -mc (multiple clients):
+        <numClients> - number of multiple clients to connect to server (max 
100, default 1)
 
 Sample:
     Client.exe -t:tcp -p:binary
@@ -76,6 +81,7 @@ Sample:
                 return;
             }
 
+            Logger.LogInformation("Starting client...");
 
             using (var source = new CancellationTokenSource())
             {
@@ -85,15 +91,38 @@ Sample:
 
         private static async Task RunAsync(string[] args, CancellationToken 
cancellationToken)
         {
-            var clientTransport = GetTransport(args);
+            var numClients = GetNumberOfClients(args);
+
+            Logger.LogInformation($"Selected # of clients: {numClients}");
+
+            var transports = new TClientTransport[numClients];
+            for (int i = 0; i < numClients; i++)
+            {
+                var t = GetTransport(args);
+                transports[i] = t;
+            }
+            
+            Logger.LogInformation($"Selected client transport: 
{transports[0]}");
+
+            var protocols = new Tuple<Protocol, TProtocol>[numClients];
+            for (int i = 0; i < numClients; i++)
+            {
+                var p = GetProtocol(args, transports[i]);
+                protocols[i] = p;
+            }
 
-            Logger.LogInformation($"Selected client transport: 
{clientTransport}");
+            Logger.LogInformation($"Selected client protocol: 
{protocols[0].Item1}");
 
-            var clientProtocol = GetProtocol(args, clientTransport);
+            var tasks = new Task[numClients];
+            for (int i = 0; i < numClients; i++)
+            {
+                var task = RunClientAsync(protocols[i], cancellationToken);
+                tasks[i] = task;
+            }
 
-            Logger.LogInformation($"Selected client protocol: 
{clientProtocol}");
+            Task.WaitAll(tasks);
 
-            await RunClientAsync(clientProtocol, cancellationToken);
+            await Task.CompletedTask;
         }
 
         private static TClientTransport GetTransport(string[] args)
@@ -112,20 +141,30 @@ Sample:
                     case Transport.Http:
                         return new THttpClientTransport(new 
Uri("http://localhost:9090";), null);
                     case Transport.TcpBuffered:
-                        return
-                            new TBufferedClientTransport(
-                                new TSocketClientTransport(IPAddress.Loopback, 
9090));
+                        return new TBufferedClientTransport(new 
TSocketClientTransport(IPAddress.Loopback, 9090));
                     case Transport.TcpTls:
-                        return new 
TTlsSocketClientTransport(IPAddress.Loopback, 9090,
-                            GetCertificate(), CertValidator, 
LocalCertificateSelectionCallback);
+                        return new 
TTlsSocketClientTransport(IPAddress.Loopback, 9090, GetCertificate(), 
CertValidator, LocalCertificateSelectionCallback);
                     case Transport.Framed:
-                        throw new NotSupportedException("Framed is not ready 
for samples");
+                        return new TFramedClientTransport(new 
TSocketClientTransport(IPAddress.Loopback, 9090));
                 }
             }
 
             return new TSocketClientTransport(IPAddress.Loopback, 9090);
         }
 
+        private static int GetNumberOfClients(string[] args)
+        {
+            var numClients = args.FirstOrDefault(x => 
x.StartsWith("-mc"))?.Split(':')?[1];
+
+            Logger.LogInformation($"Selected # of clients: {numClients}");
+
+            int c;
+            if( int.TryParse(numClients, out c) && (0 < c) && (c <= 100))
+                               return c;
+                       else
+                               return 1;
+        }
+
         private static X509Certificate2 GetCertificate()
         {
             // due to files location in net core better to take certs from top 
folder
@@ -162,7 +201,7 @@ Sample:
             return true;
         }
 
-        private static TProtocol GetProtocol(string[] args, TClientTransport 
transport)
+        private static Tuple<Protocol, TProtocol> GetProtocol(string[] args, 
TClientTransport transport)
         {
             var protocol = args.FirstOrDefault(x => 
x.StartsWith("-p"))?.Split(':')?[1];
 
@@ -172,79 +211,52 @@ Sample:
                 switch (selectedProtocol)
                 {
                     case Protocol.Binary:
-                        return new TBinaryProtocol(transport);
+                        return new Tuple<Protocol, 
TProtocol>(selectedProtocol, new TBinaryProtocol(transport));
                     case Protocol.Compact:
-                        return new TCompactProtocol(transport);
+                        return new Tuple<Protocol, 
TProtocol>(selectedProtocol, new TCompactProtocol(transport));
                     case Protocol.Json:
-                        return new TJsonProtocol(transport);
+                        return new Tuple<Protocol, 
TProtocol>(selectedProtocol, new TJsonProtocol(transport));
+                    case Protocol.Multiplexed:
+                        // it returns BinaryProtocol to avoid making wrapped 
protocol as public in TProtocolDecorator (in RunClientAsync it will be wrapped 
into Multiplexed protocol)
+                        return new Tuple<Protocol, 
TProtocol>(selectedProtocol, new TBinaryProtocol(transport));
                 }
             }
 
-            return new TBinaryProtocol(transport);
+            return new Tuple<Protocol, TProtocol>(selectedProtocol, new 
TBinaryProtocol(transport));
         }
 
-        private static async Task RunClientAsync(TProtocol protocol,
-            CancellationToken cancellationToken)
+        private static async Task RunClientAsync(Tuple<Protocol, TProtocol> 
protocolTuple, CancellationToken cancellationToken)
         {
             try
             {
-                var client = new Calculator.Client(protocol);
-                await client.OpenTransportAsync(cancellationToken);
+                var protocol = protocolTuple.Item2;
+                var protocolType = protocolTuple.Item1;
+
+                TBaseClient client = null;
 
                 try
                 {
-                    // Async version
-
-                    Logger.LogInformation("PingAsync()");
-                    await client.pingAsync(cancellationToken);
-
-                    Logger.LogInformation("AddAsync(1,1)");
-                    var sum = await client.addAsync(1, 1, cancellationToken);
-                    Logger.LogInformation($"AddAsync(1,1)={sum}");
-
-                    var work = new Work
-                    {
-                        Op = Operation.DIVIDE,
-                        Num1 = 1,
-                        Num2 = 0
-                    };
-
-                    try
+                    if (protocolType != Protocol.Multiplexed)
                     {
-                        Logger.LogInformation("CalculateAsync(1)");
-                        await client.calculateAsync(1, work, 
cancellationToken);
-                        Logger.LogInformation("Whoa we can divide by 0");
-                    }
-                    catch (InvalidOperation io)
-                    {
-                        Logger.LogInformation("Invalid operation: " + io);
-                    }
-
-                    work.Op = Operation.SUBTRACT;
-                    work.Num1 = 15;
-                    work.Num2 = 10;
 
-                    try
-                    {
-                        Logger.LogInformation("CalculateAsync(1)");
-                        var diff = await client.calculateAsync(1, work, 
cancellationToken);
-                        Logger.LogInformation($"15-10={diff}");
+                        client = new Calculator.Client(protocol);
+                        await 
ExecuteCalculatorClientOperations(cancellationToken, (Calculator.Client)client);
                     }
-                    catch (InvalidOperation io)
+                    else
                     {
-                        Logger.LogInformation("Invalid operation: " + io);
+                        // it uses binary protocol there  to create 
Multiplexed protocols
+                        var multiplex = new TMultiplexedProtocol(protocol, 
nameof(Calculator));
+                        client = new Calculator.Client(multiplex);
+                        await 
ExecuteCalculatorClientOperations(cancellationToken, (Calculator.Client)client);
+
+                        multiplex = new TMultiplexedProtocol(protocol, 
nameof(SharedService));
+                        client = new SharedService.Client(multiplex);
+                        await 
ExecuteSharedServiceClientOperations(cancellationToken, 
(SharedService.Client)client);
                     }
-
-                    Logger.LogInformation("GetStructAsync(1)");
-                    var log = await client.getStructAsync(1, 
cancellationToken);
-                    Logger.LogInformation($"Check log: {log.Value}");
-
-                    Logger.LogInformation("ZipAsync() with delay 100mc on 
server side");
-                    await client.zipAsync(cancellationToken);
                 }
                 catch (Exception ex)
                 {
-                    Logger.LogError(ex.ToString());
+                    Logger.LogError($"{client?.ClientId} " + ex);
                 }
                 finally
                 {
@@ -257,6 +269,71 @@ Sample:
             }
         }
 
+        private static async Task 
ExecuteCalculatorClientOperations(CancellationToken cancellationToken, 
Calculator.Client client)
+        {
+            await client.OpenTransportAsync(cancellationToken);
+
+            // Async version
+
+            Logger.LogInformation($"{client.ClientId} PingAsync()");
+            await client.pingAsync(cancellationToken);
+
+            Logger.LogInformation($"{client.ClientId} AddAsync(1,1)");
+            var sum = await client.addAsync(1, 1, cancellationToken);
+            Logger.LogInformation($"{client.ClientId} AddAsync(1,1)={sum}");
+
+            var work = new Work
+            {
+                Op = Operation.DIVIDE,
+                Num1 = 1,
+                Num2 = 0
+            };
+
+            try
+            {
+                Logger.LogInformation($"{client.ClientId} CalculateAsync(1)");
+                await client.calculateAsync(1, work, cancellationToken);
+                Logger.LogInformation($"{client.ClientId} Whoa we can divide 
by 0");
+            }
+            catch (InvalidOperation io)
+            {
+                Logger.LogInformation($"{client.ClientId} Invalid operation: " 
+ io);
+            }
+
+            work.Op = Operation.SUBTRACT;
+            work.Num1 = 15;
+            work.Num2 = 10;
+
+            try
+            {
+                Logger.LogInformation($"{client.ClientId} CalculateAsync(1)");
+                var diff = await client.calculateAsync(1, work, 
cancellationToken);
+                Logger.LogInformation($"{client.ClientId} 15-10={diff}");
+            }
+            catch (InvalidOperation io)
+            {
+                Logger.LogInformation($"{client.ClientId} Invalid operation: " 
+ io);
+            }
+
+            Logger.LogInformation($"{client.ClientId} GetStructAsync(1)");
+            var log = await client.getStructAsync(1, cancellationToken);
+            Logger.LogInformation($"{client.ClientId} Check log: {log.Value}");
+
+            Logger.LogInformation($"{client.ClientId} ZipAsync() with delay 
100mc on server side");
+            await client.zipAsync(cancellationToken);
+        }
+        private static async Task 
ExecuteSharedServiceClientOperations(CancellationToken cancellationToken, 
SharedService.Client client)
+        {
+            await client.OpenTransportAsync(cancellationToken);
+
+            // Async version
+
+            Logger.LogInformation($"{client.ClientId} SharedService 
GetStructAsync(1)");
+            var log = await client.getStructAsync(1, cancellationToken);
+            Logger.LogInformation($"{client.ClientId} SharedService Value: 
{log.Value}");
+        }
+
+
         private enum Transport
         {
             Tcp,
@@ -272,6 +349,7 @@ Sample:
             Binary,
             Compact,
             Json,
+            Multiplexed
         }
     }
 }
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/thrift/blob/b62247e0/tutorial/netcore/Client/Properties/launchSettings.json
----------------------------------------------------------------------
diff --git a/tutorial/netcore/Client/Properties/launchSettings.json 
b/tutorial/netcore/Client/Properties/launchSettings.json
index f351eeb..6b7b60d 100644
--- a/tutorial/netcore/Client/Properties/launchSettings.json
+++ b/tutorial/netcore/Client/Properties/launchSettings.json
@@ -2,7 +2,7 @@
   "profiles": {
     "Client": {
       "commandName": "Project",
-      "commandLineArgs": "-t:tcptls"
+      "commandLineArgs": "-p:multiplexed"
     }
   }
 }
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/thrift/blob/b62247e0/tutorial/netcore/README.md
----------------------------------------------------------------------
diff --git a/tutorial/netcore/README.md b/tutorial/netcore/README.md
index 18aac02..6b2f660 100644
--- a/tutorial/netcore/README.md
+++ b/tutorial/netcore/README.md
@@ -1,12 +1,35 @@
 # Building of samples for different platforms 
 
-Details: 
-    
-- [https://docs.microsoft.com/en-us/dotnet/articles/core/deploying/index 
](https://docs.microsoft.com/en-us/dotnet/articles/core/deploying/index  
"https://docs.microsoft.com/en-us/dotnet/articles/core/deploying/index ")
-- 
[https://docs.microsoft.com/en-us/dotnet/articles/core/rid-catalog](https://docs.microsoft.com/en-us/dotnet/articles/core/rid-catalog
 "https://docs.microsoft.com/en-us/dotnet/articles/core/rid-catalog";)
+# Reused components 
+- NET Core Standard 1.6 (SDK 1.0.0-preview2-003121)
+- NET Core App 1.1
 
-# Running of samples 
+# How to build
+- Download and install .NET Core SDK for your platform 
https://www.microsoft.com/net/core#windowsvs2015 (archive for SDK 
1.0.0-preview2-003121 located by: 
https://github.com/dotnet/core/blob/master/release-notes/download-archive.md)
+- Ensure that you have thrift.exe which supports netcore lib and it added to 
PATH 
+- Go to current folder 
+- Run **build.sh** or **build.cmd** from the root of cloned repository
+- Check tests in **src/Tests** folder
+- Continue with /tutorials/netcore 
+
+# How to run 
+
+Notes: dotnet run supports passing arguments to app after -- symbols 
(https://docs.microsoft.com/en-us/dotnet/articles/core/tools/dotnet-run) - 
example: **dotnet run -- -h** will show help for app
+
+- build 
+- go to folder (Client/Server) 
+- run with specifying of correct parameters **dotnet run -t:tcp 
-p:multiplexed**, **dotnet run -help** (later, after migration to csproj and 
latest SDK will be possibility to use more usable form **dotnet run -- 
arguments**)
+
+#Notes
+- Migration to .NET Standard 2.0 planned for later (Q1 2017) according to  
https://blogs.msdn.microsoft.com/dotnet/2016/09/26/introducing-net-standard/
+- Possible adding additional platforms after stabilization of .NET Core 
(runtimes, platforms (Red Hat Linux, OpenSuse, etc.) 
 
+#Known issues
+- In trace logging mode you can see some not important internal exceptions
+- Ubuntu 16.10 still not supported fully 
+- There is some problems with .NET Core CLI and usage specific -r|--runtime 
for building and publishing projects with different target frameworks 
(netstandard1.6 and netcoreapp1.1) 
+
+# Running of samples 
 Please install Thrift C# .NET Core library or copy sources and build them to 
correcly build and run samples 
 
 # NetCore Server
@@ -16,7 +39,7 @@ Usage:
     Server.exe -h
         will diplay help information 
 
-    Server.exe -t:<transport> -p:<protocol>
+    Server.exe -t:<transport> -p:<protocol> 
         will run server with specified arguments (tcp transport and binary 
protocol by default)
 
 Options:
@@ -27,12 +50,13 @@ Options:
         namedpipe - namedpipe transport will be used (pipe address - "".test"")
         http - http transport will be used (http address - ""localhost:9090"")
         tcptls - tcp transport with tls will be used (host - ""localhost"", 
port - 9090)
+        framed - tcp framed transport will be used (host - ""localhost"", port 
- 9090)
 
     -p (protocol): 
         binary - (default) binary protocol will be used
         compact - compact protocol will be used
         json - json protocol will be used
-
+               
 Sample:
 
     Server.exe -t:tcp
@@ -51,7 +75,7 @@ Usage:
     Client.exe -h
         will diplay help information 
 
-    Client.exe -t:<transport> -p:<protocol>
+    Client.exe -t:<transport> -p:<protocol> -mc:<numClients>
         will run client with specified arguments (tcp transport and binary 
protocol by default)
 
 Options:
@@ -62,15 +86,19 @@ Options:
         namedpipe - namedpipe transport will be used (pipe address - "".test"")
         http - http transport will be used (address - 
""http://localhost:9090"";)        
         tcptls - tcp tls transport will be used (host - ""localhost"", port - 
9090)
+        framed - tcp framed transport will be used (host - ""localhost"", port 
- 9090)
 
     -p (protocol): 
         binary - (default) binary protocol will be used
         compact - compact protocol will be used
         json - json protocol will be used
+        
+    -mc (multiple clients):
+        <numClients> - number of multiple clients to connect to server (max 
100, default 1)
 
 Sample:
 
-    Client.exe -t:tcp -p:binary
+    Client.exe -t:tcp -p:binary -mc:10
 
 Remarks:
 
@@ -250,4 +278,4 @@ if __name__ == '__main__':
     # You could do one of these for a multithreaded server
     # server = TServer.TThreadedServer(processor, transport, tfactory, 
pfactory)
     # server = TServer.TThreadPoolServer(processor, transport, tfactory, 
pfactory)
-```
\ No newline at end of file
+```

http://git-wip-us.apache.org/repos/asf/thrift/blob/b62247e0/tutorial/netcore/Server/Program.cs
----------------------------------------------------------------------
diff --git a/tutorial/netcore/Server/Program.cs 
b/tutorial/netcore/Server/Program.cs
index 6041924..aa86ae3 100644
--- a/tutorial/netcore/Server/Program.cs
+++ b/tutorial/netcore/Server/Program.cs
@@ -40,7 +40,7 @@ namespace Server
 {
     public class Program
     {
-        private static readonly ILogger Logger = new 
LoggerFactory().CreateLogger(nameof(Server));
+        private static readonly ILogger Logger = new 
LoggerFactory().AddConsole(LogLevel.Trace).AddDebug(LogLevel.Trace).CreateLogger(nameof(Server));
 
         public static void Main(string[] args)
         {
@@ -61,11 +61,13 @@ namespace Server
                 Console.ReadLine();
                 source.Cancel();
             }
+
+            Logger.LogInformation("Server stopped");
         }
 
         private static void DisplayHelp()
         {
-            Console.WriteLine(@"
+            Logger.LogInformation(@"
 Usage: 
     Server.exe -h
         will diplay help information 
@@ -80,11 +82,13 @@ Options:
         namedpipe - namedpipe transport will be used (pipe address - "".test"")
         http - http transport will be used (http address - ""localhost:9090"")
         tcptls - tcp transport with tls will be used (host - ""localhost"", 
port - 9090)
+        framed - tcp framed transport will be used (host - ""localhost"", port 
- 9090)
 
     -p (protocol): 
         binary - (default) binary protocol will be used
         compact - compact protocol will be used
         json - json protocol will be used
+        multiplexed - multiplexed protocol will be used
 
 Sample:
     Server.exe -t:tcp 
@@ -102,9 +106,7 @@ Sample:
             }
             else
             {
-                await
-                    RunSelectedConfigurationAsync(selectedTransport, 
selectedProtocol,
-                        cancellationToken);
+                await RunSelectedConfigurationAsync(selectedTransport, 
selectedProtocol, cancellationToken);
             }
         }
 
@@ -128,12 +130,11 @@ Sample:
             return selectedTransport;
         }
 
-        private static async Task RunSelectedConfigurationAsync(Transport 
transport,
-            Protocol protocol, CancellationToken cancellationToken)
+        private static async Task RunSelectedConfigurationAsync(Transport 
transport, Protocol protocol, CancellationToken cancellationToken)
         {
-            var fabric = new LoggerFactory();
+            var fabric = new 
LoggerFactory().AddConsole(LogLevel.Trace).AddDebug(LogLevel.Trace);
             var handler = new CalculatorAsyncHandler();
-            var processor = new Calculator.AsyncProcessor(handler);
+            ITAsyncProcessor processor = null;
 
             TServerTransport serverTransport = null;
 
@@ -143,15 +144,16 @@ Sample:
                     serverTransport = new TServerSocketTransport(9090);
                     break;
                 case Transport.TcpBuffered:
-                    serverTransport = new TServerSocketTransport(port: 9090, 
clientTimeout: 10000,
-                        useBufferedSockets: true);
+                    serverTransport = new TServerSocketTransport(port: 9090, 
clientTimeout: 10000, useBufferedSockets: true);
                     break;
                 case Transport.NamedPipe:
                     serverTransport = new TNamedPipeServerTransport(".test");
                     break;
                 case Transport.TcpTls:
-                    serverTransport = new TTlsServerSocketTransport(9090, 
false, GetCertificate(),
-                        ClientCertValidator, 
LocalCertificateSelectionCallback);
+                    serverTransport = new TTlsServerSocketTransport(9090, 
false, GetCertificate(), ClientCertValidator, 
LocalCertificateSelectionCallback);
+                    break;
+                case Transport.Framed:
+                    serverTransport = new TServerFramedTransport(9090);
                     break;
             }
 
@@ -164,18 +166,39 @@ Sample:
                 {
                     inputProtocolFactory = new TBinaryProtocol.Factory();
                     outputProtocolFactory = new TBinaryProtocol.Factory();
+                    processor = new Calculator.AsyncProcessor(handler);
                 }
                     break;
                 case Protocol.Compact:
                 {
                     inputProtocolFactory = new TCompactProtocol.Factory();
                     outputProtocolFactory = new TCompactProtocol.Factory();
+                    processor = new Calculator.AsyncProcessor(handler);
                 }
                     break;
                 case Protocol.Json:
                 {
                     inputProtocolFactory = new TJsonProtocol.Factory();
                     outputProtocolFactory = new TJsonProtocol.Factory();
+                    processor = new Calculator.AsyncProcessor(handler);
+                }
+                    break;
+                case Protocol.Multiplexed:
+                {
+                    inputProtocolFactory = new TBinaryProtocol.Factory();
+                    outputProtocolFactory = new TBinaryProtocol.Factory();
+
+                    var calcHandler = new CalculatorAsyncHandler();
+                    var calcProcessor = new 
Calculator.AsyncProcessor(calcHandler);
+
+                    var sharedServiceHandler = new SharedServiceAsyncHandler();
+                    var sharedServiceProcessor = new 
SharedService.AsyncProcessor(sharedServiceHandler);
+
+                    var multiplexedProcessor = new TMultiplexedProcessor();
+                    multiplexedProcessor.RegisterProcessor(nameof(Calculator), 
calcProcessor);
+                    
multiplexedProcessor.RegisterProcessor(nameof(SharedService), 
sharedServiceProcessor);
+
+                    processor = multiplexedProcessor;
                 }
                     break;
                 default:
@@ -185,10 +208,9 @@ Sample:
             try
             {
                 Logger.LogInformation(
-                    $"Selected TAsyncServer with {serverTransport} transport 
and {inputProtocolFactory} protocol factories");
+                    $"Selected TAsyncServer with {serverTransport} transport, 
{processor} processor and {inputProtocolFactory} protocol factories");
 
-                var server = new AsyncBaseServer(processor, serverTransport, 
inputProtocolFactory,
-                    outputProtocolFactory, fabric);
+                var server = new AsyncBaseServer(processor, serverTransport, 
inputProtocolFactory, outputProtocolFactory, fabric);
 
                 Logger.LogInformation("Starting the server...");
                 await server.ServeAsync(cancellationToken);
@@ -197,8 +219,6 @@ Sample:
             {
                 Logger.LogInformation(x.ToString());
             }
-
-            Logger.LogInformation("Server stopped.");
         }
 
         private static X509Certificate2 GetCertificate()
@@ -243,7 +263,8 @@ Sample:
             TcpBuffered,
             NamedPipe,
             Http,
-            TcpTls
+            TcpTls,
+            Framed
         }
 
         private enum Protocol
@@ -251,6 +272,7 @@ Sample:
             Binary,
             Compact,
             Json,
+            Multiplexed
         }
 
         public class HttpServerSample
@@ -305,11 +327,10 @@ Sample:
 
         public class CalculatorAsyncHandler : Calculator.IAsync
         {
-            Dictionary<int, SharedStruct> _log;
+            private readonly Dictionary<int, SharedStruct> _log = new 
Dictionary<int, SharedStruct>();
 
             public CalculatorAsyncHandler()
             {
-                _log = new Dictionary<int, SharedStruct>();
             }
 
             public async Task<SharedStruct> getStructAsync(int key,
@@ -347,7 +368,7 @@ Sample:
                         break;
 
                     case Operation.MULTIPLY:
-                        val = w.Num1*w.Num2;
+                        val = w.Num1 * w.Num2;
                         break;
 
                     case Operation.DIVIDE:
@@ -361,7 +382,7 @@ Sample:
 
                             throw io;
                         }
-                        val = w.Num1/w.Num2;
+                        val = w.Num1 / w.Num2;
                         break;
 
                     default:
@@ -393,5 +414,18 @@ Sample:
                 await Task.Delay(100, CancellationToken.None);
             }
         }
+
+        public class SharedServiceAsyncHandler : SharedService.IAsync
+        {
+            public async Task<SharedStruct> getStructAsync(int key, 
CancellationToken cancellationToken)
+            {
+                Logger.LogInformation("GetStructAsync({0})", key);
+                return await Task.FromResult(new SharedStruct()
+                {
+                    Key = key,
+                    Value = "GetStructAsync"
+                });
+            }
+        }
     }
 }
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/thrift/blob/b62247e0/tutorial/netcore/Server/Properties/launchSettings.json
----------------------------------------------------------------------
diff --git a/tutorial/netcore/Server/Properties/launchSettings.json 
b/tutorial/netcore/Server/Properties/launchSettings.json
index e23253d..78076ff 100644
--- a/tutorial/netcore/Server/Properties/launchSettings.json
+++ b/tutorial/netcore/Server/Properties/launchSettings.json
@@ -2,7 +2,7 @@
   "profiles": {
     "Server": {
       "commandName": "Project",
-      "commandLineArgs": "-t:tcptls"
+      "commandLineArgs": "-p:multiplexed"
     }
   }
 }
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/thrift/blob/b62247e0/tutorial/netcore/global.json
----------------------------------------------------------------------
diff --git a/tutorial/netcore/global.json b/tutorial/netcore/global.json
index 53f1811..5ecfc21 100644
--- a/tutorial/netcore/global.json
+++ b/tutorial/netcore/global.json
@@ -1,3 +1,6 @@
 {
-  "projects": [ "../../lib/netcore" ]
+  "projects": [ "../../lib/netcore" ],
+  "sdk": {
+    "version": "1.0.0-preview2-1-003177" // "1.0.0-preview2-003121", 
"1.0.0-preview4-004233"
+  }
 }
\ No newline at end of file

Reply via email to