Exception signaling and processes

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
4 messages Options
Reply | Threaded
Open this post in threaded view
|

Exception signaling and processes

NorbertHartl
I'm doing a project using WebSockets at the moment and I have trouble making it work. I'm not sure I fully understand the problem. So here is my attempt in explaining what happens:

A tablet computer connects via WebSocket to a pharo image. On connection time a session object is created and a little later a user is associated to that session object. On login time I check if the user is already logged in to another tablet. This is by checking any session that has a user associated. So far so good.

In order to make the service reliable I test it by switching on/off the flight mode of the tablet just to simulate network problems. WebSockets use TCP and the problem appears that the server does not get notice that the connection went away. At the time the client reconnects it detects that there is an active session with a user and complains about it.

Handling of sessions is automatic. There are exception handlers that remove bogus sessions automatically. In order to solve the inactive session problem I do the following: If I find a session with a particular user I try to access the socket so an exception will be triggered if the connection isn't valid anymore. Theoretically it would work.

When accessing the socket the exception isn't signalled in my current process but in the process that created the socket (I'm not 100% sure of this). The other process is suspended so the signalling does not occur. My second check for a session therefor sees that it is still there. But shortly after my process returns control the other process runs and removes the session from the list while handling the exception.

What would be a good way to tackle this? I tried a bit using yielding the active process, resuming the other process but all doesn't feel to be quite right to solve the problem. Is there a way to let the other process run or can I have the signalled exception in my current process? Anything else?

Any hints appreciated. Thanks,

Norbert
Reply | Threaded
Open this post in threaded view
|

Re: Exception signaling and processes

Sven Van Caekenberghe-2
Hi Norbert,

[ Continuing our private email conversation ]

On 18 Feb 2013, at 17:55, Norbert Hartl <[hidden email]> wrote:

> I'm doing a project using WebSockets at the moment and I have trouble making it work. I'm not sure I fully understand the problem. So here is my attempt in explaining what happens:
>
> A tablet computer connects via WebSocket to a pharo image. On connection time a session object is created and a little later a user is associated to that session object. On login time I check if the user is already logged in to another tablet. This is by checking any session that has a user associated. So far so good.
>
> In order to make the service reliable I test it by switching on/off the flight mode of the tablet just to simulate network problems. WebSockets use TCP and the problem appears that the server does not get notice that the connection went away. At the time the client reconnects it detects that there is an active session with a user and complains about it.
>
> Handling of sessions is automatic. There are exception handlers that remove bogus sessions automatically. In order to solve the inactive session problem I do the following: If I find a session with a particular user I try to access the socket so an exception will be triggered if the connection isn't valid anymore. Theoretically it would work.
>
> When accessing the socket the exception isn't signalled in my current process but in the process that created the socket (I'm not 100% sure of this). The other process is suspended so the signalling does not occur. My second check for a session therefor sees that it is still there. But shortly after my process returns control the other process runs and removes the session from the list while handling the exception.
>
> What would be a good way to tackle this? I tried a bit using yielding the active process, resuming the other process but all doesn't feel to be quite right to solve the problem. Is there a way to let the other process run or can I have the signalled exception in my current process? Anything else?
>
> Any hints appreciated. Thanks,
>
> Norbert

The WebSocket protocol starts as a regular HTTP request/response that gets 'upgraded', which is fancy speak for the fact that the existing TCP connection used for that request/response is now being used as it is, with a new protocol. That means that in this initial request/response you can do anything that you can do with a normal HTTP request/response, including normal authentication and HTTP session management (typically using cookies).

The main Zinc HTTP server spawns a new worker process for each HTTP connection. The WebSocket handler typically keeps on using that process by means of WebSocket>>#runWith: (but strictly speaking this does not have to be so, although any other approach is experimental).

So yes, in the ZnWebSocketChatroomHandler example, and in your code as you describe it, at one point there will be two processes accessing a web socket: one reading, one writing. I don't think that has to be a problem, I have never seen exception being handled in the other process, but I can imagine that it could happen (who knows what's going on in the socket plugin, it certainly is different on all 3 major platforms). Since both will probably have a handler doing a cleanup, the result should be the same.

Now, I think, from your descriptions, that you try to make too much of a problem from trying to control one client accessing the server twice. If the previous connection died somehow (and is cleaned up eventually), who cares ? This should be the same as a normal web app with a session and login semantics. HTTP semantics are typically such that the switch from one kept-alive connection to the next, or one session to the next happens transparently.

The same should be possible with WebSockets. The initiative to create one lies with the client. An established connection can always disappear for any number of reasons. Just clean up and start over. The main trick/problem to me seems to be that you have to make this transparent in the client GUI. At the protocol level, I can't immediately see a problem. Like in any app, the same user could theoretically log in twice - as long as s/he is authenticated and access to internal shared data is dealt with correctly.

Sven

--
Sven Van Caekenberghe
http://stfx.eu
Smalltalk is the Red Pill


Reply | Threaded
Open this post in threaded view
|

Re: Exception signaling and processes

NorbertHartl
Sven,

thanks for the answer. Comments inline!

Am 18.02.2013 um 23:38 schrieb Sven Van Caekenberghe <[hidden email]>:

> Hi Norbert,
>
> [ Continuing our private email conversation ]
>
> On 18 Feb 2013, at 17:55, Norbert Hartl <[hidden email]> wrote:
>
>> I'm doing a project using WebSockets at the moment and I have trouble making it work. I'm not sure I fully understand the problem. So here is my attempt in explaining what happens:
>>
>> A tablet computer connects via WebSocket to a pharo image. On connection time a session object is created and a little later a user is associated to that session object. On login time I check if the user is already logged in to another tablet. This is by checking any session that has a user associated. So far so good.
>>
>> In order to make the service reliable I test it by switching on/off the flight mode of the tablet just to simulate network problems. WebSockets use TCP and the problem appears that the server does not get notice that the connection went away. At the time the client reconnects it detects that there is an active session with a user and complains about it.
>>
>> Handling of sessions is automatic. There are exception handlers that remove bogus sessions automatically. In order to solve the inactive session problem I do the following: If I find a session with a particular user I try to access the socket so an exception will be triggered if the connection isn't valid anymore. Theoretically it would work.
>>
>> When accessing the socket the exception isn't signalled in my current process but in the process that created the socket (I'm not 100% sure of this). The other process is suspended so the signalling does not occur. My second check for a session therefor sees that it is still there. But shortly after my process returns control the other process runs and removes the session from the list while handling the exception.
>>
>> What would be a good way to tackle this? I tried a bit using yielding the active process, resuming the other process but all doesn't feel to be quite right to solve the problem. Is there a way to let the other process run or can I have the signalled exception in my current process? Anything else?
>>
>> Any hints appreciated. Thanks,
>>
>> Norbert
>
> The WebSocket protocol starts as a regular HTTP request/response that gets 'upgraded', which is fancy speak for the fact that the existing TCP connection used for that request/response is now being used as it is, with a new protocol. That means that in this initial request/response you can do anything that you can do with a normal HTTP request/response, including normal authentication and HTTP session management (typically using cookies).
>
> The main Zinc HTTP server spawns a new worker process for each HTTP connection. The WebSocket handler typically keeps on using that process by means of WebSocket>>#runWith: (but strictly speaking this does not have to be so, although any other approach is experimental).
>
> So yes, in the ZnWebSocketChatroomHandler example, and in your code as you describe it, at one point there will be two processes accessing a web socket: one reading, one writing. I don't think that has to be a problem, I have never seen exception being handled in the other process, but I can imagine that it could happen (who knows what's going on in the socket plugin, it certainly is different on all 3 major platforms). Since both will probably have a handler doing a cleanup, the result should be the same.
>
I'm not even sure that it is the case what I've described. It is really hard to debug and/or the be sure to draw the right conclusions. But at least I can read from your mail that you would expect the exception just to signal in the current process. That is what I've expected, too. It just doesn't happen. Anyone has some insights how this can happen?

> Now, I think, from your descriptions, that you try to make too much of a problem from trying to control one client accessing the server twice. If the previous connection died somehow (and is cleaned up eventually), who cares ? This should be the same as a normal web app with a session and login semantics. HTTP semantics are typically such that the switch from one kept-alive connection to the next, or one session to the next happens transparently.
>
> The same should be possible with WebSockets. The initiative to create one lies with the client. An established connection can always disappear for any number of reasons. Just clean up and start over. The main trick/problem to me seems to be that you have to make this transparent in the client GUI. At the protocol level, I can't immediately see a problem. Like in any app, the same user could theoretically log in twice - as long as s/he is authenticated and access to internal shared data is dealt with correctly.
>
Agreed. Except the fact that having each user logged in only once is a requirement :) And I think that WebSockets being permanent are quite different from normal http connects.

So, after seeing the odd signalling behaviour I wasn't sure if there are conditions where exceptions are signalled that way. At the moment I solve it in a way that in the conflict case the client is instructed to resend the logon command. In the meantime other processes run the signalling happens and on resend the bogus socket is gone. I just would like to do the same without reconnecting. Ah..and yes I would like to understand how this works/misbehaves.

thanks,

Norbert


Reply | Threaded
Open this post in threaded view
|

Re: Exception signaling and processes

NorbertHartl
In reply to this post by Sven Van Caekenberghe-2

Am 18.02.2013 um 23:38 schrieb Sven Van Caekenberghe <[hidden email]>:

An established connection can always disappear for any number of reasons. Just clean up and start over.

One extra note. I think that is exactly what I'm trying to achieve. In order to cleanup you have to know when or you do it all the time. As I don't get a notice when the connection is no longer valid I try at certain moments to check the validity of the server socket. At that moment I like to have the chance to see it, clean up and start over.

Norbert