Repository: thrift Updated Branches: refs/heads/master 54beb80de -> 2bfd7df93
THRIFT-3397 Implement TProcessorFactory in C# to enable per-client processors Client: C# Patch: Jonathan Heard This closes #663 Project: http://git-wip-us.apache.org/repos/asf/thrift/repo Commit: http://git-wip-us.apache.org/repos/asf/thrift/commit/2bfd7df9 Tree: http://git-wip-us.apache.org/repos/asf/thrift/tree/2bfd7df9 Diff: http://git-wip-us.apache.org/repos/asf/thrift/diff/2bfd7df9 Branch: refs/heads/master Commit: 2bfd7df93e5e2c1195a5cb2bcde42820f24b642f Parents: 54beb80 Author: Jonathan Heard <[email protected]> Authored: Wed Oct 28 17:34:27 2015 +0000 Committer: Jens Geyer <[email protected]> Committed: Thu Oct 29 22:40:58 2015 +0200 ---------------------------------------------------------------------- lib/csharp/Makefile.am | 4 + lib/csharp/src/Server/TServer.cs | 48 ++++- lib/csharp/src/Server/TSimpleServer.cs | 18 +- lib/csharp/src/Server/TThreadPoolServer.cs | 23 ++- lib/csharp/src/Server/TThreadedServer.cs | 21 ++- lib/csharp/src/TControllingHandler.cs | 29 +++ lib/csharp/src/TProcessorFactory.cs | 30 +++ lib/csharp/src/TPrototypeProcessorFactory.cs | 55 ++++++ lib/csharp/src/TSingletonProcessorFactory.cs | 43 +++++ lib/csharp/src/Thrift.csproj | 6 +- lib/csharp/test/ThriftTest/Program.cs | 9 + lib/csharp/test/ThriftTest/TestClient.cs | 12 +- lib/csharp/test/ThriftTest/TestServer.cs | 215 ++++++++++++++-------- 13 files changed, 414 insertions(+), 99 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/thrift/blob/2bfd7df9/lib/csharp/Makefile.am ---------------------------------------------------------------------- diff --git a/lib/csharp/Makefile.am b/lib/csharp/Makefile.am index a8b275e..2ecc5fe 100644 --- a/lib/csharp/Makefile.am +++ b/lib/csharp/Makefile.am @@ -66,6 +66,10 @@ THRIFTCODE= \ src/Transport/TTLSSocket.cs \ src/Transport/TTLSServerSocket.cs \ src/TProcessor.cs \ + src/TProcessorFactory.cs \ + src/TSingletonProcessorFactory.cs \ + src/TPrototypeProcessorFactory.cs \ + src/TControllingHandler.cs \ src/TException.cs \ src/TApplicationException.cs http://git-wip-us.apache.org/repos/asf/thrift/blob/2bfd7df9/lib/csharp/src/Server/TServer.cs ---------------------------------------------------------------------- diff --git a/lib/csharp/src/Server/TServer.cs b/lib/csharp/src/Server/TServer.cs index a2631a9..cee2ae3 100644 --- a/lib/csharp/src/Server/TServer.cs +++ b/lib/csharp/src/Server/TServer.cs @@ -31,7 +31,7 @@ namespace Thrift.Server public abstract class TServer { //Attributes - protected TProcessor processor; + protected TProcessorFactory processorFactory; protected TServerTransport serverTransport; protected TTransportFactory inputTransportFactory; protected TTransportFactory outputTransportFactory; @@ -65,14 +65,25 @@ namespace Thrift.Server //Construction public TServer(TProcessor processor, TServerTransport serverTransport) - : this(processor, serverTransport, new TTransportFactory(), new TTransportFactory(), new TBinaryProtocol.Factory(), new TBinaryProtocol.Factory(), DefaultLogDelegate) + : this(processor, serverTransport, + new TTransportFactory(), + new TTransportFactory(), + new TBinaryProtocol.Factory(), + new TBinaryProtocol.Factory(), + DefaultLogDelegate) { } public TServer(TProcessor processor, TServerTransport serverTransport, LogDelegate logDelegate) - : this(processor, serverTransport, new TTransportFactory(), new TTransportFactory(), new TBinaryProtocol.Factory(), new TBinaryProtocol.Factory(), DefaultLogDelegate) + : this(processor, + serverTransport, + new TTransportFactory(), + new TTransportFactory(), + new TBinaryProtocol.Factory(), + new TBinaryProtocol.Factory(), + logDelegate) { } @@ -104,6 +115,23 @@ namespace Thrift.Server } public TServer(TProcessor processor, + TServerTransport serverTransport, + TTransportFactory inputTransportFactory, + TTransportFactory outputTransportFactory, + TProtocolFactory inputProtocolFactory, + TProtocolFactory outputProtocolFactory, + LogDelegate logDelegate) + { + this.processorFactory = new TSingletonProcessorFactory(processor); + this.serverTransport = serverTransport; + this.inputTransportFactory = inputTransportFactory; + this.outputTransportFactory = outputTransportFactory; + this.inputProtocolFactory = inputProtocolFactory; + this.outputProtocolFactory = outputProtocolFactory; + this.logDelegate = (logDelegate != null) ? logDelegate : DefaultLogDelegate; + } + + public TServer(TProcessorFactory processorFactory, TServerTransport serverTransport, TTransportFactory inputTransportFactory, TTransportFactory outputTransportFactory, @@ -111,13 +139,13 @@ namespace Thrift.Server TProtocolFactory outputProtocolFactory, LogDelegate logDelegate) { - this.processor = processor; - this.serverTransport = serverTransport; - this.inputTransportFactory = inputTransportFactory; - this.outputTransportFactory = outputTransportFactory; - this.inputProtocolFactory = inputProtocolFactory; - this.outputProtocolFactory = outputProtocolFactory; - this.logDelegate = (logDelegate != null) ? logDelegate : DefaultLogDelegate; + this.processorFactory = processorFactory; + this.serverTransport = serverTransport; + this.inputTransportFactory = inputTransportFactory; + this.outputTransportFactory = outputTransportFactory; + this.inputProtocolFactory = inputProtocolFactory; + this.outputProtocolFactory = outputProtocolFactory; + this.logDelegate = (logDelegate != null) ? logDelegate : DefaultLogDelegate; } //Abstract Interface http://git-wip-us.apache.org/repos/asf/thrift/blob/2bfd7df9/lib/csharp/src/Server/TSimpleServer.cs ---------------------------------------------------------------------- diff --git a/lib/csharp/src/Server/TSimpleServer.cs b/lib/csharp/src/Server/TSimpleServer.cs index 267b470..c73fecf 100644 --- a/lib/csharp/src/Server/TSimpleServer.cs +++ b/lib/csharp/src/Server/TSimpleServer.cs @@ -61,10 +61,24 @@ namespace Thrift.Server } public TSimpleServer(TProcessor processor, + TServerTransport serverTransport, + TTransportFactory transportFactory, + TProtocolFactory protocolFactory) + : base(processor, + serverTransport, + transportFactory, + transportFactory, + protocolFactory, + protocolFactory, + DefaultLogDelegate) + { + } + + public TSimpleServer(TProcessorFactory processorFactory, TServerTransport serverTransport, TTransportFactory transportFactory, TProtocolFactory protocolFactory) - : base(processor, + : base(processorFactory, serverTransport, transportFactory, transportFactory, @@ -92,6 +106,7 @@ namespace Thrift.Server while (!stop) { + TProcessor processor = null; TTransport client = null; TTransport inputTransport = null; TTransport outputTransport = null; @@ -102,6 +117,7 @@ namespace Thrift.Server { using (client = serverTransport.Accept()) { + processor = processorFactory.GetProcessor(client); if (client != null) { using (inputTransport = inputTransportFactory.GetTransport(client)) http://git-wip-us.apache.org/repos/asf/thrift/blob/2bfd7df9/lib/csharp/src/Server/TThreadPoolServer.cs ---------------------------------------------------------------------- diff --git a/lib/csharp/src/Server/TThreadPoolServer.cs b/lib/csharp/src/Server/TThreadPoolServer.cs index 4c201e9..f0c7fe4 100644 --- a/lib/csharp/src/Server/TThreadPoolServer.cs +++ b/lib/csharp/src/Server/TThreadPoolServer.cs @@ -38,7 +38,7 @@ namespace Thrift.Server private volatile bool stop = false; public TThreadPoolServer(TProcessor processor, TServerTransport serverTransport) - : this(processor, serverTransport, + : this(new TSingletonProcessorFactory(processor), serverTransport, new TTransportFactory(), new TTransportFactory(), new TBinaryProtocol.Factory(), new TBinaryProtocol.Factory(), DEFAULT_MIN_THREADS, DEFAULT_MAX_THREADS, DefaultLogDelegate) @@ -46,33 +46,43 @@ namespace Thrift.Server } public TThreadPoolServer(TProcessor processor, TServerTransport serverTransport, LogDelegate logDelegate) - : this(processor, serverTransport, + : this(new TSingletonProcessorFactory(processor), serverTransport, new TTransportFactory(), new TTransportFactory(), new TBinaryProtocol.Factory(), new TBinaryProtocol.Factory(), DEFAULT_MIN_THREADS, DEFAULT_MAX_THREADS, logDelegate) { } - public TThreadPoolServer(TProcessor processor, + TServerTransport serverTransport, + TTransportFactory transportFactory, + TProtocolFactory protocolFactory) + : this(new TSingletonProcessorFactory(processor), serverTransport, + transportFactory, transportFactory, + protocolFactory, protocolFactory, + DEFAULT_MIN_THREADS, DEFAULT_MAX_THREADS, DefaultLogDelegate) + { + } + + public TThreadPoolServer(TProcessorFactory processorFactory, TServerTransport serverTransport, TTransportFactory transportFactory, TProtocolFactory protocolFactory) - : this(processor, serverTransport, + : this(processorFactory, serverTransport, transportFactory, transportFactory, protocolFactory, protocolFactory, DEFAULT_MIN_THREADS, DEFAULT_MAX_THREADS, DefaultLogDelegate) { } - public TThreadPoolServer(TProcessor processor, + public TThreadPoolServer(TProcessorFactory processorFactory, TServerTransport serverTransport, TTransportFactory inputTransportFactory, TTransportFactory outputTransportFactory, TProtocolFactory inputProtocolFactory, TProtocolFactory outputProtocolFactory, int minThreadPoolThreads, int maxThreadPoolThreads, LogDelegate logDel) - : base(processor, serverTransport, inputTransportFactory, outputTransportFactory, + : base(processorFactory, serverTransport, inputTransportFactory, outputTransportFactory, inputProtocolFactory, outputProtocolFactory, logDel) { lock (typeof(TThreadPoolServer)) @@ -149,6 +159,7 @@ namespace Thrift.Server private void Execute(Object threadContext) { TTransport client = (TTransport)threadContext; + TProcessor processor = processorFactory.GetProcessor(client, this); TTransport inputTransport = null; TTransport outputTransport = null; TProtocol inputProtocol = null; http://git-wip-us.apache.org/repos/asf/thrift/blob/2bfd7df9/lib/csharp/src/Server/TThreadedServer.cs ---------------------------------------------------------------------- diff --git a/lib/csharp/src/Server/TThreadedServer.cs b/lib/csharp/src/Server/TThreadedServer.cs index f8ed8e2..fe13dfd 100644 --- a/lib/csharp/src/Server/TThreadedServer.cs +++ b/lib/csharp/src/Server/TThreadedServer.cs @@ -45,7 +45,7 @@ namespace Thrift.Server } public TThreadedServer(TProcessor processor, TServerTransport serverTransport) - : this(processor, serverTransport, + : this(new TSingletonProcessorFactory(processor), serverTransport, new TTransportFactory(), new TTransportFactory(), new TBinaryProtocol.Factory(), new TBinaryProtocol.Factory(), DEFAULT_MAX_THREADS, DefaultLogDelegate) @@ -53,7 +53,7 @@ namespace Thrift.Server } public TThreadedServer(TProcessor processor, TServerTransport serverTransport, LogDelegate logDelegate) - : this(processor, serverTransport, + : this(new TSingletonProcessorFactory(processor), serverTransport, new TTransportFactory(), new TTransportFactory(), new TBinaryProtocol.Factory(), new TBinaryProtocol.Factory(), DEFAULT_MAX_THREADS, logDelegate) @@ -65,21 +65,31 @@ namespace Thrift.Server TServerTransport serverTransport, TTransportFactory transportFactory, TProtocolFactory protocolFactory) - : this(processor, serverTransport, + : this(new TSingletonProcessorFactory(processor), serverTransport, transportFactory, transportFactory, protocolFactory, protocolFactory, DEFAULT_MAX_THREADS, DefaultLogDelegate) { } - public TThreadedServer(TProcessor processor, + public TThreadedServer(TProcessorFactory processorFactory, + TServerTransport serverTransport, + TTransportFactory transportFactory, + TProtocolFactory protocolFactory) + : this(processorFactory, serverTransport, + transportFactory, transportFactory, + protocolFactory, protocolFactory, + DEFAULT_MAX_THREADS, DefaultLogDelegate) + { + } + public TThreadedServer(TProcessorFactory processorFactory, TServerTransport serverTransport, TTransportFactory inputTransportFactory, TTransportFactory outputTransportFactory, TProtocolFactory inputProtocolFactory, TProtocolFactory outputProtocolFactory, int maxThreads, LogDelegate logDel) - : base(processor, serverTransport, inputTransportFactory, outputTransportFactory, + : base(processorFactory, serverTransport, inputTransportFactory, outputTransportFactory, inputProtocolFactory, outputProtocolFactory, logDel) { this.maxThreads = maxThreads; @@ -183,6 +193,7 @@ namespace Thrift.Server private void ClientWorker(Object context) { TTransport client = (TTransport)context; + TProcessor processor = processorFactory.GetProcessor(client); TTransport inputTransport = null; TTransport outputTransport = null; TProtocol inputProtocol = null; http://git-wip-us.apache.org/repos/asf/thrift/blob/2bfd7df9/lib/csharp/src/TControllingHandler.cs ---------------------------------------------------------------------- diff --git a/lib/csharp/src/TControllingHandler.cs b/lib/csharp/src/TControllingHandler.cs new file mode 100644 index 0000000..7b5203a --- /dev/null +++ b/lib/csharp/src/TControllingHandler.cs @@ -0,0 +1,29 @@ +/* + * 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 Thrift.Server; + +namespace Thrift +{ + public interface TControllingHandler + { + TServer server { get; set; } + } +} http://git-wip-us.apache.org/repos/asf/thrift/blob/2bfd7df9/lib/csharp/src/TProcessorFactory.cs ---------------------------------------------------------------------- diff --git a/lib/csharp/src/TProcessorFactory.cs b/lib/csharp/src/TProcessorFactory.cs new file mode 100644 index 0000000..fdf631b --- /dev/null +++ b/lib/csharp/src/TProcessorFactory.cs @@ -0,0 +1,30 @@ +/* + * 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 Thrift.Server; +using Thrift.Transport; + +namespace Thrift +{ + public interface TProcessorFactory + { + TProcessor GetProcessor(TTransport trans, TServer server = null); + } +} http://git-wip-us.apache.org/repos/asf/thrift/blob/2bfd7df9/lib/csharp/src/TPrototypeProcessorFactory.cs ---------------------------------------------------------------------- diff --git a/lib/csharp/src/TPrototypeProcessorFactory.cs b/lib/csharp/src/TPrototypeProcessorFactory.cs new file mode 100644 index 0000000..d15b2d9 --- /dev/null +++ b/lib/csharp/src/TPrototypeProcessorFactory.cs @@ -0,0 +1,55 @@ +/* + * 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.Collections.Generic; +using System.Linq; +using System.Text; +using Thrift.Server; +using Thrift.Transport; + +namespace Thrift +{ + public class TPrototypeProcessorFactory<P, H> : TProcessorFactory where P : TProcessor + { + object[] handlerArgs = null; + + public TPrototypeProcessorFactory() + { + handlerArgs = new object[0]; + } + + public TPrototypeProcessorFactory(params object[] handlerArgs) + { + this.handlerArgs = handlerArgs; + } + + public TProcessor GetProcessor(TTransport trans, TServer server = null) + { + H handler = (H) Activator.CreateInstance(typeof(H), handlerArgs); + + TControllingHandler handlerServerRef = handler as TControllingHandler; + if (handlerServerRef != null) + { + handlerServerRef.server = server; + } + return Activator.CreateInstance(typeof(P), new object[] { handler }) as TProcessor; + } + } +} http://git-wip-us.apache.org/repos/asf/thrift/blob/2bfd7df9/lib/csharp/src/TSingletonProcessorFactory.cs ---------------------------------------------------------------------- diff --git a/lib/csharp/src/TSingletonProcessorFactory.cs b/lib/csharp/src/TSingletonProcessorFactory.cs new file mode 100644 index 0000000..40dc44c --- /dev/null +++ b/lib/csharp/src/TSingletonProcessorFactory.cs @@ -0,0 +1,43 @@ +/* + * 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.Collections.Generic; +using System.Linq; +using System.Text; +using Thrift.Server; +using Thrift.Transport; + +namespace Thrift +{ + public class TSingletonProcessorFactory : TProcessorFactory + { + private readonly TProcessor processor_; + + public TSingletonProcessorFactory(TProcessor processor) + { + processor_ = processor; + } + + public TProcessor GetProcessor(TTransport trans, TServer server = null) + { + return processor_; + } + } +} http://git-wip-us.apache.org/repos/asf/thrift/blob/2bfd7df9/lib/csharp/src/Thrift.csproj ---------------------------------------------------------------------- diff --git a/lib/csharp/src/Thrift.csproj b/lib/csharp/src/Thrift.csproj index 195005a..99c6b46 100644 --- a/lib/csharp/src/Thrift.csproj +++ b/lib/csharp/src/Thrift.csproj @@ -79,6 +79,8 @@ <ItemGroup> <Compile Include="Collections\TCollections.cs" /> <Compile Include="Collections\THashSet.cs" /> + <Compile Include="TControllingHandler.cs" /> + <Compile Include="TProcessorFactory.cs" /> <Compile Include="Properties\AssemblyInfo.cs" /> <Compile Include="Protocol\TAbstractBase.cs" /> <Compile Include="Protocol\TBase.cs" /> @@ -101,6 +103,8 @@ <Compile Include="Protocol\TSet.cs" /> <Compile Include="Protocol\TStruct.cs" /> <Compile Include="Protocol\TType.cs" /> + <Compile Include="TPrototypeProcessorFactory.cs" /> + <Compile Include="TSingletonProcessorFactory.cs" /> <Compile Include="Server\TThreadedServer.cs" /> <Compile Include="Server\TServer.cs" /> <Compile Include="Server\TServerEventHandler.cs" /> @@ -147,4 +151,4 @@ <ProjectExtensions> <VisualStudio AllowExistingFolder="true" /> </ProjectExtensions> -</Project> +</Project> \ No newline at end of file http://git-wip-us.apache.org/repos/asf/thrift/blob/2bfd7df9/lib/csharp/test/ThriftTest/Program.cs ---------------------------------------------------------------------- diff --git a/lib/csharp/test/ThriftTest/Program.cs b/lib/csharp/test/ThriftTest/Program.cs index 2bfc73e..8ec00e3 100644 --- a/lib/csharp/test/ThriftTest/Program.cs +++ b/lib/csharp/test/ThriftTest/Program.cs @@ -39,6 +39,15 @@ namespace Test return -1; } + try + { + Console.SetBufferSize(Console.BufferWidth, 4096); + } + catch (Exception) + { + Console.WriteLine("Failed to grow scroll-back buffer"); + } + string[] subArgs = new string[args.Length - 1]; for(int i = 1; i < args.Length; i++) { http://git-wip-us.apache.org/repos/asf/thrift/blob/2bfd7df9/lib/csharp/test/ThriftTest/TestClient.cs ---------------------------------------------------------------------- diff --git a/lib/csharp/test/ThriftTest/TestClient.cs b/lib/csharp/test/ThriftTest/TestClient.cs index f0297d0..4c42ef7 100644 --- a/lib/csharp/test/ThriftTest/TestClient.cs +++ b/lib/csharp/test/ThriftTest/TestClient.cs @@ -43,6 +43,8 @@ namespace Test public bool framed; public string protocol; public bool encrypted = false; + protected bool _isFirstTransport = true; + public TTransport CreateTransport() { @@ -72,9 +74,13 @@ namespace Test if (framed) trans = new TFramedTransport(trans); - //ensure proper open/close of transport - trans.Open(); - trans.Close(); + if (_isFirstTransport) + { + //ensure proper open/close of transport + trans.Open(); + trans.Close(); + _isFirstTransport = false; + } return trans; } else http://git-wip-us.apache.org/repos/asf/thrift/blob/2bfd7df9/lib/csharp/test/ThriftTest/TestServer.cs ---------------------------------------------------------------------- diff --git a/lib/csharp/test/ThriftTest/TestServer.cs b/lib/csharp/test/ThriftTest/TestServer.cs index b3a8e42..4c8fc3b 100644 --- a/lib/csharp/test/ThriftTest/TestServer.cs +++ b/lib/csharp/test/ThriftTest/TestServer.cs @@ -29,11 +29,17 @@ using Thrift.Test; //generated code using Thrift.Transport; using Thrift.Protocol; using Thrift.Server; +using Thrift; +using System.Threading; +using System.Text; namespace Test { public class TestServer { + public static int _clientID = -1; + public delegate void TestLogDelegate(string msg, params object[] values); + public class TradeServerEventHandler : TServerEventHandler { public int callCount = 0; @@ -56,86 +62,100 @@ namespace Test } }; - public class TestHandler : ThriftTest.Iface + public class TestHandler : ThriftTest.Iface, Thrift.TControllingHandler { - public TServer server; + public TServer server { get; set; } + private int handlerID; + private StringBuilder reusableStringBuilder = new StringBuilder(); + private TestLogDelegate testLogDelegate; + + public TestHandler() + { + handlerID = Interlocked.Increment(ref _clientID); + testLogDelegate += testConsoleLogger; + testLogDelegate.Invoke("New TestHandler instance created"); + } - public TestHandler() { } + public void testConsoleLogger(string msg, params object[] values) + { + reusableStringBuilder.Clear(); + reusableStringBuilder.AppendFormat("handler{0:D3}:",handlerID); + reusableStringBuilder.AppendFormat(msg, values); + reusableStringBuilder.AppendLine(); + Console.Write( reusableStringBuilder.ToString() ); + } public void testVoid() { - Console.WriteLine("testVoid()"); + testLogDelegate.Invoke("testVoid()"); } public string testString(string thing) { - Console.WriteLine("testString(\"" + thing + "\")"); + testLogDelegate.Invoke("testString({0})", thing); return thing; } public bool testBool(bool thing) { - Console.WriteLine("testBool(" + thing + ")"); + testLogDelegate.Invoke("testBool({0})", thing); return thing; } public sbyte testByte(sbyte thing) { - Console.WriteLine("testByte(" + thing + ")"); + testLogDelegate.Invoke("testByte({0})", thing); return thing; } public int testI32(int thing) { - Console.WriteLine("testI32(" + thing + ")"); + testLogDelegate.Invoke("testI32({0})", thing); return thing; } public long testI64(long thing) { - Console.WriteLine("testI64(" + thing + ")"); + testLogDelegate.Invoke("testI64({0})", thing); return thing; } public double testDouble(double thing) { - Console.WriteLine("testDouble(" + thing + ")"); + testLogDelegate.Invoke("testDouble({0})", thing); return thing; } public byte[] testBinary(byte[] thing) { string hex = BitConverter.ToString(thing).Replace("-", string.Empty); - Console.WriteLine("testBinary(" + hex + ")"); + testLogDelegate.Invoke("testBinary({0:X})", hex); return thing; } public Xtruct testStruct(Xtruct thing) { - Console.WriteLine("testStruct({" + - "\"" + thing.String_thing + "\", " + - thing.Byte_thing + ", " + - thing.I32_thing + ", " + - thing.I64_thing + "})"); + testLogDelegate.Invoke("testStruct({{\"{0}\", {1}, {2}, {3}}})", thing.String_thing, thing.Byte_thing, thing.I32_thing, thing.I64_thing); return thing; } public Xtruct2 testNest(Xtruct2 nest) { Xtruct thing = nest.Struct_thing; - Console.WriteLine("testNest({" + - nest.Byte_thing + ", {" + - "\"" + thing.String_thing + "\", " + - thing.Byte_thing + ", " + - thing.I32_thing + ", " + - thing.I64_thing + "}, " + - nest.I32_thing + "})"); + testLogDelegate.Invoke("testNest({{{0}, {{\"{1}\", {2}, {3}, {4}, {5}}}}})", + nest.Byte_thing, + thing.String_thing, + thing.Byte_thing, + thing.I32_thing, + thing.I64_thing, + nest.I32_thing); return nest; } public Dictionary<int, int> testMap(Dictionary<int, int> thing) { - Console.WriteLine("testMap({"); + reusableStringBuilder.Clear(); + reusableStringBuilder.Append("testMap({{"); bool first = true; foreach (int key in thing.Keys) { @@ -145,17 +165,19 @@ namespace Test } else { - Console.Write(", "); + reusableStringBuilder.Append(", "); } - Console.Write(key + " => " + thing[key]); + reusableStringBuilder.AppendFormat("{0} => {1}", key, thing[key]); } - Console.WriteLine("})"); + reusableStringBuilder.Append("}})"); + testLogDelegate.Invoke(reusableStringBuilder.ToString()); return thing; } public Dictionary<string, string> testStringMap(Dictionary<string, string> thing) { - Console.WriteLine("testStringMap({"); + reusableStringBuilder.Clear(); + reusableStringBuilder.Append("testStringMap({{"); bool first = true; foreach (string key in thing.Keys) { @@ -165,17 +187,19 @@ namespace Test } else { - Console.Write(", "); + reusableStringBuilder.Append(", "); } - Console.Write(key + " => " + thing[key]); + reusableStringBuilder.AppendFormat("{0} => {1}", key, thing[key]); } - Console.WriteLine("})"); + reusableStringBuilder.Append("}})"); + testLogDelegate.Invoke(reusableStringBuilder.ToString()); return thing; } public THashSet<int> testSet(THashSet<int> thing) { - Console.WriteLine("testSet({"); + reusableStringBuilder.Clear(); + reusableStringBuilder.Append("testSet({{"); bool first = true; foreach (int elem in thing) { @@ -185,17 +209,19 @@ namespace Test } else { - Console.Write(", "); + reusableStringBuilder.Append(", "); } - Console.Write(elem); + reusableStringBuilder.AppendFormat("{0}", elem); } - Console.WriteLine("})"); + reusableStringBuilder.Append("}})"); + testLogDelegate.Invoke(reusableStringBuilder.ToString()); return thing; } public List<int> testList(List<int> thing) { - Console.WriteLine("testList({"); + reusableStringBuilder.Clear(); + reusableStringBuilder.Append("testList({{"); bool first = true; foreach (int elem in thing) { @@ -205,29 +231,30 @@ namespace Test } else { - Console.Write(", "); + reusableStringBuilder.Append(", "); } - Console.Write(elem); + reusableStringBuilder.AppendFormat("{0}", elem); } - Console.WriteLine("})"); + reusableStringBuilder.Append("}})"); + testLogDelegate.Invoke(reusableStringBuilder.ToString()); return thing; } public Numberz testEnum(Numberz thing) { - Console.WriteLine("testEnum(" + thing + ")"); + testLogDelegate.Invoke("testEnum({0})", thing); return thing; } public long testTypedef(long thing) { - Console.WriteLine("testTypedef(" + thing + ")"); + testLogDelegate.Invoke("testTypedef({0})", thing); return thing; } public Dictionary<int, Dictionary<int, int>> testMapMap(int hello) { - Console.WriteLine("testMapMap(" + hello + ")"); + testLogDelegate.Invoke("testMapMap({0})", hello); Dictionary<int, Dictionary<int, int>> mapmap = new Dictionary<int, Dictionary<int, int>>(); @@ -247,7 +274,7 @@ namespace Test public Dictionary<long, Dictionary<Numberz, Insanity>> testInsanity(Insanity argument) { - Console.WriteLine("testInsanity()"); + testLogDelegate.Invoke("testInsanity()"); Xtruct hello = new Xtruct(); hello.String_thing = "Hello2"; @@ -289,7 +316,7 @@ namespace Test public Xtruct testMulti(sbyte arg0, int arg1, long arg2, Dictionary<short, string> arg3, Numberz arg4, long arg5) { - Console.WriteLine("testMulti()"); + testLogDelegate.Invoke("testMulti()"); Xtruct hello = new Xtruct(); ; hello.String_thing = "Hello2"; @@ -308,7 +335,7 @@ namespace Test */ public void testException(string arg) { - Console.WriteLine("testException(" + arg + ")"); + testLogDelegate.Invoke("testException({0})", arg); if (arg == "Xception") { Xception x = new Xception(); @@ -325,7 +352,7 @@ namespace Test public Xtruct testMultiException(string arg0, string arg1) { - Console.WriteLine("testMultiException(" + arg0 + ", " + arg1 + ")"); + testLogDelegate.Invoke("testMultiException({0}, {1})", arg0,arg1); if (arg0 == "Xception") { Xception x = new Xception(); @@ -357,18 +384,33 @@ namespace Test public void testOneway(int arg) { - Console.WriteLine("testOneway(" + arg + "), sleeping..."); + testLogDelegate.Invoke("testOneway({0}), sleeping...", arg); System.Threading.Thread.Sleep(arg * 1000); - Console.WriteLine("testOneway finished"); + testLogDelegate.Invoke("testOneway finished"); } } // class TestHandler + private enum ServerType + { + TSimpleServer, + TThreadedServer, + TThreadPoolServer, + } + + private enum ProcessorFactoryType + { + TSingletonProcessorFactory, + TPrototypeProcessorFactory, + } + public static bool Execute(string[] args) { try { bool useBufferedSockets = false, useFramed = false, useEncryption = false, compact = false, json = false; + ServerType serverType = ServerType.TSimpleServer; + ProcessorFactoryType processorFactoryType = ProcessorFactoryType.TSingletonProcessorFactory; int port = 9090; string pipe = null; for (int i = 0; i < args.Length; i++) @@ -379,13 +421,13 @@ namespace Test } else if (args[i].Contains("--port=")) { - port = int.Parse(args[i].Substring(args[i].IndexOf("=")+1)); + port = int.Parse(args[i].Substring(args[i].IndexOf("=") + 1)); } else if (args[i] == "-b" || args[i] == "--buffered" || args[i] == "--transport=buffered") { useBufferedSockets = true; } - else if (args[i] == "-f" || args[i] == "--framed" || args[i] == "--transport=framed") + else if (args[i] == "-f" || args[i] == "--framed" || args[i] == "--transport=framed") { useFramed = true; } @@ -397,19 +439,27 @@ namespace Test { json = true; } + else if (args[i] == "--threaded" || args[i] == "--server-type=threaded") + { + serverType = ServerType.TThreadedServer; + } + else if (args[i] == "--threadpool" || args[i] == "--server-type=threadpool") + { + serverType = ServerType.TThreadPoolServer; + } + else if (args[i] == "--prototype" || args[i] == "--processor=prototype") + { + processorFactoryType = ProcessorFactoryType.TPrototypeProcessorFactory; + } else if (args[i] == "--ssl") { useEncryption = true; } } - // Processor - TestHandler testHandler = new TestHandler(); - ThriftTest.Processor testProcessor = new ThriftTest.Processor(testHandler); - // Transport TServerTransport trans; - if( pipe != null) + if (pipe != null) { trans = new TNamedPipeServerTransport(pipe); } @@ -427,35 +477,54 @@ namespace Test } TProtocolFactory proto; - if ( compact ) + if (compact) proto = new TCompactProtocol.Factory(); - else if ( json ) + else if (json) proto = new TJSONProtocol.Factory(); else proto = new TBinaryProtocol.Factory(); - // Simple Server - TServer serverEngine; - if ( useFramed ) - serverEngine = new TSimpleServer(testProcessor, trans, new TFramedTransport.Factory(), proto); + TProcessorFactory processorFactory; + if (processorFactoryType == ProcessorFactoryType.TPrototypeProcessorFactory) + { + processorFactory = new TPrototypeProcessorFactory<ThriftTest.Processor, TestHandler>(); + } else - serverEngine = new TSimpleServer(testProcessor, trans, new TTransportFactory(), proto); - - // ThreadPool Server - // serverEngine = new TThreadPoolServer(testProcessor, tServerSocket); + { + // Processor + TestHandler testHandler = new TestHandler(); + ThriftTest.Processor testProcessor = new ThriftTest.Processor(testHandler); + processorFactory = new TSingletonProcessorFactory(testProcessor); + } - // Threaded Server - // serverEngine = new TThreadedServer(testProcessor, tServerSocket); + TTransportFactory transFactory; + if (useFramed) + transFactory = new TFramedTransport.Factory(); + else + transFactory = new TTransportFactory(); - //Server event handler - TradeServerEventHandler serverEvents = new TradeServerEventHandler(); - serverEngine.setEventHandler(serverEvents); + TServer serverEngine; + switch (serverType) + { + case ServerType.TThreadPoolServer: + serverEngine = new TThreadPoolServer(processorFactory, trans, transFactory, proto); + break; + case ServerType.TThreadedServer: + serverEngine = new TThreadedServer(processorFactory, trans, transFactory, proto); + break; + default: + serverEngine = new TSimpleServer(processorFactory, trans, transFactory, proto); + break; + } - testHandler.server = serverEngine; + //Server event handler + TradeServerEventHandler serverEvents = new TradeServerEventHandler(); + serverEngine.setEventHandler(serverEvents); // Run it - string where = ( pipe != null ? "on pipe "+pipe : "on port " + port); - Console.WriteLine("Starting the server " + where + + string where = (pipe != null ? "on pipe " + pipe : "on port " + port); + Console.WriteLine("Starting the " + serverType.ToString() + " " + where + + (processorFactoryType == ProcessorFactoryType.TPrototypeProcessorFactory ? " with processor prototype factory " : "") + (useBufferedSockets ? " with buffered socket" : "") + (useFramed ? " with framed transport" : "") + (useEncryption ? " with encryption" : "") +
