Sebastian Zenker created THRIFT-3593:
----------------------------------------

             Summary: Add new IDL keyword 'signal' to be able that a server can 
actively send messages to all its connected clients to prevent polling
                 Key: THRIFT-3593
                 URL: https://issues.apache.org/jira/browse/THRIFT-3593
             Project: Thrift
          Issue Type: Wish
          Components: AS3 - Compiler, AS3 - Library, C glib - Compiler, C glib 
- Library, C# - Compiler, C# - Library, C++ - Compiler, C++ - Library, Cocoa - 
Compiler, Cocoa - Library, Compiler (General), D - Compiler, D - Library, Dart 
- Compiler, Dart - Library, Delphi - Compiler, Delphi - Library, Documentation, 
Erlang - Compiler, Erlang - Library, Go - Compiler, Go - Library, Haskell - 
Compiler, Haskell - Library, Haxe - Compiler, Haxe - Library, Java - Compiler, 
Java - Library, JavaScript - Compiler, JavaScript - Library, Lua - Compiler, 
Lua - Library, Node.js - Compiler, Node.js - Library, Perl - Compiler, Perl - 
Library, PHP - Compiler, PHP - Library, Python - Compiler, Python - Library, 
Ruby - Compiler, Ruby - Library, Smalltalk - Compiler, Smalltalk - Library, 
Swift - Compiler, Test Suite, Tutorial
            Reporter: Sebastian Zenker


In our applications, we have very often the use case, that we actively want to 
inform all connected Thrift clients about state changes on the server side. Let 
me use a stupid example to explain what I whish. Let's assume we have service 
which represents a fan controller. This service allows to configure a target 
temperature and can be requested for the actual temperature and actual RPM. 

service FanController
{
  void setTargetTemperature(int t);
  int getTargetTemperature();
  int getActualTemperature();
  int getActualRPM();
}

Our client application allows the user to set the target temperature and 
display the actual temperature and RPM. 

To implement such an application, we currently have two options when using the 
Thrift framework:

1.) Every client requests the actual temperature and RPM once per second. With 
other words: every client implements polling.

2.) We split service FanController into two different Thrift services. One 
which allows to configure the fan controller and a second one which is used by 
the server to notify all its clients about state changes. The first one is 
implemented by the "real" server and the second one is implemented by all 
clients and consists of some oneway methods only. So from a Thrift point of 
view, both sides are server & client. E.g.

service FanController
{
  void setTargetTemperature(int t);
  int getTargetTemperature();
  void RegisterEvents(string hostname, int port); //use to tell the server, 
that it should establish a connection to hostname+port which implements 
FanControllerEvents
  void UnregisterEvents(string hostname, int port);
}

service FanControllerEvents
{
  oneway void targetTemperatureChanged(int t);
  oneway void actualTemperatureChanged(int t);
  oneway void actualRPMChanged(int rpm);
}

Both approaches have massive drawbacks. I think it is not worth the effort to 
explain why solution #1 (polling) sucks. But also solution #2 doesn't work 
well, because:
*) It requires every client to register its FanControllerEvents service at the 
server side by using FanController::RegisterEvents(). This doesn't work, in 
case the client resides behind a NAT-router, because so the "real" server 
cannot establish a TCP connection to the client.
*) It always requires at least two TCP connections which makes firewall 
configurations more complex.
*) The "real" server needs to maintain a list with all connected clients in the 
application logic. In case the actual RPM or temperature changes, the server 
needs to iterate over the list of all connected clients and call the 
corresponding function. Maintaining the list in the application logic adds 
extra complexity at the server side, which can be avoided and may be better 
part of the Thrift framework.
*) How to handle the case, if only 1 of the 2 TCP connections gets interrupted?
*) The fan controller service - which is logically one thing - gets splitted 
into two Thrift services: FanController + FanControllerEvents which decreases 
readability of the IDL file.

To solve such a use case, my recommendation is the following: Add a new keyword 
like "signal" to the IDL language. Wouldn't it be cool to be able to define 
something like:

service FanController
{
  void setTargetTemperature(int t);
  signal void targetTemperatureChanged(int t);
  signal void actualTemperatureChanged(int t);
  signal actualRPMChanged(int t);
}

E.g. DBus (a IPC framework very often used in Linux environments) allows to 
specify signals in their interfaces. See also: 
http://dbus.freedesktop.org/doc/dbus-tutorial.html#signalprocedure

It's a very intrusive wish, as it will effect all code generators and runtime 
libraries. What do you think?



--
This message was sent by Atlassian JIRA
(v6.3.4#6332)

Reply via email to