thrift-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From "James E. King, III (JIRA)" <>
Subject [jira] [Commented] (THRIFT-3593) Enable server-side to issue requests to clients on the same connection (push notifications)
Date Sun, 05 Feb 2017 17:42:41 GMT


James E. King, III commented on THRIFT-3593:

[~sebastian.zenker] The notion of having the code generator make a signal handler for push
events is interesting; I would treat that as a separate request from allowing bi-directional
request/response with multiple outstanding requests going either way.

> Enable server-side to issue requests to clients on the same connection (push notifications)
> -------------------------------------------------------------------------------------------
>                 Key: THRIFT-3593
>                 URL:
>             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
>              Labels: push
> 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. 
> {code}
> service FanController
> {
>   void setTargetTemperature(int t);
>   int getTargetTemperature();
>   int getActualTemperature();
>   int getActualRPM();
> }
> {code}
> 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
> 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.
> {code}
> 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);
> }
> {code}
> 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
>  * 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
> 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:
> {code}
> service FanController
> {
>   void setTargetTemperature(int t);
>   signal void targetTemperatureChanged(int t);
>   signal void actualTemperatureChanged(int t);
>   signal actualRPMChanged(int t);
> }
> {code}
> E.g. DBus (a IPC framework very often used in Linux environments) allows to specify signals
in their interfaces. See also:
> 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

View raw message