jWebSocket Forum

[Search] Search   [Recent Topics] Recent Topics   [Hottest Topics] Hottest Topics   [Members]  Member Listing   [Groups] Back to home page 
[Register] Register / 
[Login] Login 
PlugIn - Design philosophy behind routing asynchronous events - II  XML
Forum Index » Server side Plug-Ins, Apps, Listeners and Filters
Author Message
nirmalya

jWebSocket Forum User

Joined: 30/06/2010 14:21:43
Messages: 13
Offline

Hello Alex,

Here's a different question on the same topic.

In order to push multiple asynchronous events to a client, a bridge has to exist between the plugin(s) and the event generation layer (we have discussed this before). At various points in time, this layer will push events to a given client through PlugIn's send() method. Right?

Now what I am wondering is what happens if the pushing logic happens in different threads! Should I have to queue the events before one thread picks one event at a time and calls the send() method? Send() is not a synchronized method (and probably, it should not be). but what happens when multiple threads call it simultaneously?

Hope that I have been able to explain the situation well. What's your recommendation as a designer of the framework?

Will be very interested to hear your views.

Regards

Nirmalya
puran

jWebSocket Committer
[Avatar]

Joined: 16/03/2010 21:53:41
Messages: 61
Location: San Francisco
Offline

Hi,

You are right send is not a synchronized method and it shouldn't be too. If i understood the question right then it shouldn't be a problem even if we do send() using multiple threads because send() method of plugin delegates the send to server which in turn uses the underlying engine or say connector to do the actual write. Here, I am not sure about the TCP engine but Netty engine which is NIO based should handle it all and it's all asynchronous write to the actual socket.

Regards
[Email] [WWW]
nirmalya

jWebSocket Forum User

Joined: 30/06/2010 14:21:43
Messages: 13
Offline

Puran,

Thanks for the explanation.

Though it is not explicitly mentioned anywhere so far, I presume that if multiple Send()s from multiple plugins are directed to the same Connection (a client connected to the server) simultaneously, the Server and in turn, the TCP engine (I am using this, not Netty) must queue individual Send() requests and process them one at a time. This will help plugin.Send() call to return immediately to the caller application thread and will also ensure that there is no intermingling of data being sent through more than one Send() calls.

This is how - from a very high level - all of us have been trying to handle TCP-based. multi-threaded software from 'C'/'C++' days . Object Request Brokers of yesteryears to present-day MINA based network - all follow same principle.

For example: I am trying to build a PlugIn-based application (let's call is MyPlugIn) of my own following the example of 'SamplePlugin.java'. It makes use of TokenServer and so does my application. A call to SamplePlugIn.ProcessToken() is made by the Server (to which the PlugIn is registered). This is done in a thread owned by the Server. According to the example, in the body of i]SamplePlugIn.ProcessToken()[/i] a response is sent back through a ResponseToken through Server.sendToken() call. Obviously, this Server.sendToken() happens at the same calling thread.

But in my application - MyPlugIn - I want to simply accept and store the request in an internal data structure and let the calling thread to return from MyPlugIn.ProcessToken(). Later, depending on what the request contains, MyPlugIn (and other related classes) creates multiple responses to be sent to the same Connector. These responses are all asynchronously generated and they are pushed to the Connector through Server.sendToken() by different threads. I have no control over when these threads get into action. Therefore, I have no control over what happens when Thread[1] pushes Response[1] through Server.sendToken(), is pre-empted by JVM before it can return, and in the meantime, Thread[2] pushes Response[2] through same Server.sendToken(). Unless Server.sendToken() gives me the guarantee that under no circumstances, consistence of data being sent will never be compromised, I have to be careful before calling Server.sendToken() (may be by putting a synchronised Wrapper call over Server.sendToken()).

My question is whether my understanding of how my application should behave is correct. What are my responsibilities and what are the framework's responsibilities.

I hope that I have been able to elaborate my problem. Would like to hear from you guys.

Many thanks in advance.

Nirmalya

puran

jWebSocket Committer
[Avatar]

Joined: 16/03/2010 21:53:41
Messages: 61
Location: San Francisco
Offline

Hi Nirmalaya,

I think you raised a very good point here about the Plugin architecture. I sort of see where you are going with this and it makes perfect sense.

So i see here two places where we have to maintain the asynchronous data send operation.

1. Connector Level by TCP or Netty (which netty already does)
2. Plugin Level which isn't there right now as you pointed out.

I think jWebSocket framework should maintain the queue and also return some kind of Future object or handler immediately when we call SamplePlugIn.ProcessToken() that we can use to piggy back on that send operation. This will avoid the need of synchronization wrapper which i don't think is a good idea.

If you have a good implementation idea on this then we would love to have you contribute to our plugin architecture But this is something we would definitely try to improve.

Regards
[Email] [WWW]
nirmalya

jWebSocket Forum User

Joined: 30/06/2010 14:21:43
Messages: 13
Offline

Puran,

Thanks for your viewpoints.

I intend to use jWebSocket in the way I have elaborated, and therefore, I will try and find some way to deal with asynchronous events being generated at the server side. I will get back to you guys with my solution surely, whether or not, that is going to be elegant.

Meanwhile, I would suggest that this issue is taken up in jWebSocket's design discussions. Please keep me posted if you guys plan for something in this regard.

Many thanks in advance,

Nirmalya
puran

jWebSocket Committer
[Avatar]

Joined: 16/03/2010 21:53:41
Messages: 61
Location: San Francisco
Offline

Thanks Nirmalaya,

This is a very good concern so we have to work on this. We'll keep you on the loop.
[Email] [WWW]
nirmalya

jWebSocket Forum User

Joined: 30/06/2010 14:21:43
Messages: 13
Offline

Puran,

A small request: my name is Nirmalya, not Nirmalaya . Not that it really matters, but I thought a correction will save you from an extra key-stroke.

I have not used Netty! But, I know that socket.send()/receive() [ from my Unix/C programming days ] and SocketChannel.read()/write() [ from my Java NIO days] are thread-safe. MINA offers same facility in an abstracted way. I am reasonably sure that Netty ensures thread-safety too and you are guys have taken the matter into consideration. However, higher-level APIs and Constructes (like Connection object of jWebSocket) need to declare presence or absence of this guarantee explicitly. This is all the more important because these APIs are going to become public.

My 2 cents.

Nirmalya
puran

jWebSocket Committer
[Avatar]

Joined: 16/03/2010 21:53:41
Messages: 61
Location: San Francisco
Offline

oops my bad Nirmalya . You are right!! we hope to improve on that. Thanks for all the feedback and improvement suggestions. Much appreciated
[Email] [WWW]
aschulze

jWebSocket Owner
[Avatar]

Joined: 16/03/2010 18:15:55
Messages: 375
Location: Germany, Herzogenrath
Offline

Hi Nirmalya,

first off, thanks for your valuable suggestions. In the TCPConnector the sendPacket method is ultimately responsible to "physically" send the packet to the client. The packet is “composed” by three os.write operations followed by a flush operation.

You are right. This method is not yet thread safe and thus will be updated to synchronized. Since packets necessarily need to be send subsequently per connector anyway (i.e. per client thread) it wouldn’t block anything else other than the connector.

It will be part of the next update to guarantee to not comprise any packets in multithreaded environments like yours.
Thanks again for your hint.

Best Regards
Alex

This message was edited 1 time. Last update was at 30/07/2010 22:24:23

[WWW]
nirmalya

jWebSocket Forum User

Joined: 30/06/2010 14:21:43
Messages: 13
Offline

Hello Alex and Puran,

Here I am back again, with another question.

Going by existing example code (and of course, the documents), I understand that TokenID is an important part of the Client-Server-Client interaction. In particular, the Server needs to 'know', which TokenID must accompany a response to the Client so that the Client can identify a response and associate it with a (previously sent) request. Right?

Now, I see a problem:

What happens when the Server sends an asynchronous response back to the Client? In all likelihood, this response is generated by Server either because of a previous request from the Client or because of an occurrence of an event on the Server side that the Client needs to know about but hasn't asked for.

As an example:
* Client sends Request RQ1 with TokenID '99' to Server.
* Server processes the request and sends a response RS1 with TokenID '99' to the Client.
* A few minutes later, Server needs to send two more asynchronous responses ARS1 and ARS2 to the Client.

Now, what should the TokenID for these responses be? Sending '99' is incorrect because strictly speaking, it is not a response to the request RQ1. Moreover, the once the Client had received RS1, it probably has gotten itself rid of TokenID '99' and hence is not in a position to identify '99' as a known token. Furthermore, perhaps the Client wants to reuse '99' for other messages by now. After all, the Client owns the value '99' and it is free to reuse it whenever it wants. At this point in time, if the ID of the Token sent by the Server is '99', the Client may be confused.

Not sure if the question is exposing a gap in my understanding, or it it is a genuine gap in the design. Please enlighten me.

Warm regards

Nirmalya
aschulze

jWebSocket Owner
[Avatar]

Joined: 16/03/2010 18:15:55
Messages: 375
Location: Germany, Herzogenrath
Offline

Hi Nirmalya,

welcome back

You are right: The Token-Id plays an important role in the client/server communication. Because of the optional multi-threaded processing of requests their results can be passed back to the client in a different order than the requests have been sent. So yes, when using the OnResponse callback the client requires the Token-Id to be able to assign a response to a particular previous request.

Currently the client releases its OnResponse callback for a certain request as soon as the response from the Server is received - or the given timeout is exceeded (to release the resources and allow JS to run its garbage collection). A "Request/Multiple Responses" Mechanism is not (yet) supported by the client. Server events always are asynchronous and do not relate to a previous request (however, they might have been triggered by a client), so these do neither require a Token-Id nor they need to be answered.

If you want to implement a "Single Request/Multipart Response" mechanism simply do not use the OnResponse callback but evaluate the incoming tokens in the OnMessage callback. You could create an Object that (temporarily) stores your requests (e.g. by using "field_<TokenId>" as field names and referring to what ever object instance you require for a particular request). In case of incoming tokens with the same repeating token-id you can assign them by using our own "assignment-object".

I hope this helped.

Best Regards
Alex
[WWW]
 
Forum Index » Server side Plug-Ins, Apps, Listeners and Filters
Go to:   
Powered by JForum 2.1.9 © JForum Team