THRIFT-2624: Add TServerEventHandler support to C#
Client: C#
Patch: ra
Adds the TServerEventHandler interface to the C# lib and adds
support in all C# servers.
diff --git a/lib/csharp/src/Server/TSimpleServer.cs b/lib/csharp/src/Server/TSimpleServer.cs
index 1099fc1..75f8241 100644
--- a/lib/csharp/src/Server/TSimpleServer.cs
+++ b/lib/csharp/src/Server/TSimpleServer.cs
@@ -27,122 +27,132 @@
namespace Thrift.Server
{
- /// <summary>
- /// Simple single-threaded server for testing
- /// </summary>
- public class TSimpleServer : TServer
- {
- private bool stop = false;
+ /// <summary>
+ /// Simple single-threaded server for testing
+ /// </summary>
+ public class TSimpleServer : TServer
+ {
+ private bool stop = false;
- public TSimpleServer(TProcessor processor,
- TServerTransport serverTransport)
- :base(processor, serverTransport, new TTransportFactory(), new TTransportFactory(), new TBinaryProtocol.Factory(), new TBinaryProtocol.Factory(), DefaultLogDelegate)
- {
- }
+ public TSimpleServer(TProcessor processor,
+ TServerTransport serverTransport)
+ : base(processor, serverTransport, new TTransportFactory(), new TTransportFactory(), new TBinaryProtocol.Factory(), new TBinaryProtocol.Factory(), DefaultLogDelegate)
+ {
+ }
- public TSimpleServer(TProcessor processor,
- TServerTransport serverTransport,
- LogDelegate logDel)
- : base(processor, serverTransport, new TTransportFactory(), new TTransportFactory(), new TBinaryProtocol.Factory(), new TBinaryProtocol.Factory(), logDel)
- {
- }
+ public TSimpleServer(TProcessor processor,
+ TServerTransport serverTransport,
+ LogDelegate logDel)
+ : base(processor, serverTransport, new TTransportFactory(), new TTransportFactory(), new TBinaryProtocol.Factory(), new TBinaryProtocol.Factory(), logDel)
+ {
+ }
- public TSimpleServer(TProcessor processor,
- TServerTransport serverTransport,
- TTransportFactory transportFactory)
- :base(processor,
- serverTransport,
- transportFactory,
- transportFactory,
- new TBinaryProtocol.Factory(),
- new TBinaryProtocol.Factory(),
- DefaultLogDelegate)
- {
- }
+ public TSimpleServer(TProcessor processor,
+ TServerTransport serverTransport,
+ TTransportFactory transportFactory)
+ : base(processor,
+ serverTransport,
+ transportFactory,
+ transportFactory,
+ new TBinaryProtocol.Factory(),
+ new TBinaryProtocol.Factory(),
+ DefaultLogDelegate)
+ {
+ }
- public TSimpleServer(TProcessor processor,
- TServerTransport serverTransport,
- TTransportFactory transportFactory,
- TProtocolFactory protocolFactory)
- :base(processor,
- serverTransport,
- transportFactory,
- transportFactory,
- protocolFactory,
- protocolFactory,
- DefaultLogDelegate)
- {
- }
+ public TSimpleServer(TProcessor processor,
+ TServerTransport serverTransport,
+ TTransportFactory transportFactory,
+ TProtocolFactory protocolFactory)
+ : base(processor,
+ serverTransport,
+ transportFactory,
+ transportFactory,
+ protocolFactory,
+ protocolFactory,
+ DefaultLogDelegate)
+ {
+ }
- public override void Serve()
- {
- try
- {
- serverTransport.Listen();
- }
- catch (TTransportException ttx)
- {
- logDelegate(ttx.ToString());
- return;
- }
+ public override void Serve()
+ {
+ try
+ {
+ serverTransport.Listen();
+ }
+ catch (TTransportException ttx)
+ {
+ logDelegate(ttx.ToString());
+ return;
+ }
- while (!stop)
- {
- TTransport client = null;
- TTransport inputTransport = null;
- TTransport outputTransport = null;
- TProtocol inputProtocol = null;
- TProtocol outputProtocol = null;
- try
- {
- using(client = serverTransport.Accept())
+ //Fire the preServe server event when server is up but before any client connections
+ if (serverEventHandler != null)
+ serverEventHandler.preServe();
+
+ while (!stop)
+ {
+ TTransport client = null;
+ TTransport inputTransport = null;
+ TTransport outputTransport = null;
+ TProtocol inputProtocol = null;
+ TProtocol outputProtocol = null;
+ Object connectionContext = null;
+ try
+ {
+ using (client = serverTransport.Accept())
{
if (client != null)
{
- using(inputTransport = inputTransportFactory.GetTransport(client))
+ using (inputTransport = inputTransportFactory.GetTransport(client))
{
using (outputTransport = outputTransportFactory.GetTransport(client))
{
inputProtocol = inputProtocolFactory.GetProtocol(inputTransport);
outputProtocol = outputProtocolFactory.GetProtocol(outputTransport);
- while (processor.Process(inputProtocol, outputProtocol)) { }
+
+ //Recover event handler (if any) and fire createContext server event when a client connects
+ if (serverEventHandler != null)
+ connectionContext = serverEventHandler.createContext(inputProtocol, outputProtocol);
+
+ //Process client requests until client disconnects
+ while (true)
+ {
+ //Fire processContext server event
+ //N.B. This is the pattern implemented in C++ and the event fires provisionally.
+ //That is to say it may be many minutes between the event firing and the client request
+ //actually arriving or the client may hang up without ever makeing a request.
+ if (serverEventHandler != null)
+ serverEventHandler.processContext(connectionContext, inputTransport);
+ //Process client request (blocks until transport is readable)
+ if (!processor.Process(inputProtocol, outputProtocol))
+ break;
+ }
}
}
}
}
}
- catch (TTransportException ttx)
+ catch (TTransportException)
{
- // Client died, just move on
- if (stop)
- {
- logDelegate("TSimpleServer was shutting down, caught " + ttx.GetType().Name);
- }
+ //Usually a client disconnect, expected
}
catch (Exception x)
{
+ //Unexpected
logDelegate(x.ToString());
}
+
+ //Fire deleteContext server event after client disconnects
+ if (serverEventHandler != null)
+ serverEventHandler.deleteContext(connectionContext, inputProtocol, outputProtocol);
}
+ }
- if (stop)
- {
- try
- {
- serverTransport.Close();
- }
- catch (TTransportException ttx)
- {
- logDelegate("TServerTranport failed on close: " + ttx.Message);
- }
- stop = false;
- }
- }
-
- public override void Stop()
- {
- stop = true;
- serverTransport.Close();
- }
- }
+ public override void Stop()
+ {
+ stop = true;
+ serverTransport.Close();
+ }
+ }
}