[ 
https://issues.apache.org/jira/browse/THRIFT-3593?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=15131254#comment-15131254
 ] 

Jens Geyer commented on THRIFT-3593:
------------------------------------

Thanks for the link. However, the below section reads just like your option 2 
above: Publish/Subscribe. 

{quote}
**Any process on the message bus can register** "match rules" indicating which 
signals it is interested in. The bus has a list of registered match rules. 
* The bus daemon examines the signal and determines which processes are 
interested in it. **It sends the signal message to these processes.** 
* Each process receiving the signal decides what to do with it; if using a 
binding, the binding may choose to emit a native signal on a proxy object. If 
using the low-level API, the process may just look at the signal sender and 
name and decide what to do based on that. 
{quote}

Technically, even DBus needs a server-kind of thing on the client side that can 
act as a target for incoming calls. They hide the cross-machine and 
cross-session stuff very well within the various daemon instances, but it is 
still there, and [applications will have to register themselves to receive 
signals|http://dbus.freedesktop.org/doc/dbus-python/doc/tutorial.html#receiving-signals].
 

I might add, that such a feature is clearly on the list of the top 10 feature 
wishes. So if there is any chance to get it done in a nice, clean and 
maintainable way that provides additional value (such as hiding complexities) 
but [without sacrificing simplicity, transparency, consistency and performance 
etc.|http://thrift.apache.org/about], I'm in the boat.

{quote}
It still requires to define two separate Thrift services which should be 
actually defined in one service / interface in my opinion.
{quote}

That's a matter of taste, and (I can only speak for myself) are using the one 
or the other form depending on context and requirements. Glueing things 
together this way will prevent you from reusing stuff (or at least make it 
harder), but sometimes stuff does not need to be reused at all. So it depends, 
IMHO. 

However, if having a slighty (and debatable) "cleaner" IDL is the only thing we 
get from introducing a new keyword ... mmmh. Frankly speaking, the keyword is 
probably one of the least problems that will pop up when we start implementing 
that whole task. 



> 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
>              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 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.
> {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 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:
> {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: 
> 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