#1 2013-05-18 20:48:07

ah
Member
Registered: 2013-05-17
Posts: 9

Client Driven objects not working

I'm trying to use interface-based services using sicClientDriven mode, but it seems it's not working.
Once I create an object from the client, the server will stop working after the timeout (server object expires). It's "hard" to get this bug just by testing because the timeout is big (default is 30 min). But it's easy to check if you change the timeout to a value small enough to test (like 15 seconds).
This problem can easily be reproduced using your own sample (sample 16, execute SQL via services). Steps to reproduce:

Using Sample 16:
1. Run the server
2. Run the client, execute some SQL, close the client
3. Wait for the timeout expires (31 minutes, or if you changed mormot source code, any timeout you specified)
4. Run the client again - you get AV on the server.

is this a known bug, a bug in framework, or a bug in the sample? Nevertheless, I can't make my server to be stable, it just crashes after timeout period passed.

Side question, is there a way to define a smaller timeout without changing mormot source code? I had to change this line in mormot.pas:

{TServiceFactoryServer}
    constructor Create(aRestServer: TSQLRestServer; aInterface: PTypeInfo;
      aInstanceCreation: TServiceInstanceImplementation;
      aImplementationClass: TInterfacedClass; const aContractExpected: RawUTF8='';
      aTimeOutSec: cardinal=30*60); reintroduce; //<<--- THIS LINE, replaced 30*60 by 15

Offline

#2 2013-05-19 12:03:22

ab
Administrator
From: France
Registered: 2010-06-21
Posts: 14,242
Website

Re: Client Driven objects not working

I've just added the TServiceFactoryServer.TimeoutSec customizable property, to change the timeout per service easily, when registering it.
TSQLRestServer.ServiceRegister() returns the TServiceFactoryServer instance  corresponding of the service, and the new property is customizable.
See http://synopse.info/fossil/info/82335f2683
Thanks for the feedback.

About execution issue, are you using latest 1.18 unstable version?

Offline

#3 2013-05-20 11:06:44

ah
Member
Registered: 2013-05-17
Posts: 9

Re: Client Driven objects not working

Yes, using 1.18. This mentioned sample doesn't even exist in stable version, and the unit names are totally different. I'm starting a new project, doesn't make much sense to me to use a stable version if I will have to change a lot of things to use the next one.
Anyway, as I said, the sample is only available in version 1.18, so maybe it was never tested?

Offline

#4 2013-05-20 11:19:00

ab
Administrator
From: France
Registered: 2010-06-21
Posts: 14,242
Website

Re: Client Driven objects not working

We did not test the timeout feature itself.

I just tested it, and we did not get any access violation at first.

The server raised the following event:

13:24:25	Server	    POST root/RemoteSQL.Execute/1 ERROR=400 (Client driven instance not found or deprecated)

Which sounds pretty much correct.

But I discovered that if you resend the same Client request one more time, there is indeed an Access Violation problem on the server side.
Previous instance is tried to be deleted twice from the list.

It has been fixed by http://synopse.info/fossil/info/ea2fb7889d

Thanks for the feedback.

Offline

#5 2013-05-20 13:56:08

ah
Member
Registered: 2013-05-17
Posts: 9

Re: Client Driven objects not working

The problem happens if you open a *different* client after timeout occurs. In the same client, you get the message you mentioned indeed. I will test your fix to see if it solves my problem as well.

By the way, about the message you mentioned: it's expected, yes, if I create a server object and take too much time to use it, it will expire and I get that message. But, what is the correct way to "recreate" the object without having that message? For example, I create an object IFoo on the server and I have the method DoSomething. Then I take too much time (timeout occurs). But nevertheless, my client calls IFoo.DoSomething and I get that message (instance not found). What is the best way to avoid this message and just reinstantiate a client object in case it happens and make DoSomething to run smoothly (reassign a newly created object to the same interface)?

Offline

#6 2013-05-21 05:38:55

ab
Administrator
From: France
Registered: 2010-06-21
Posts: 14,242
Website

Re: Client Driven objects not working

Purpose of this timeout is to clean instances on server side in case of a client unexpected close (i.e. client process killed with no call to proper _free virtual method).
So automatic re-creation of the instance does not make much sense, IMHO.

Timeout values is by default of 30 minutes.
Perhaps it is not enough.
This is the purpose of the new TServiceFactoryServer.TimeoutSec customizable property, and its SetTimeoutSec() fluent method.

It is up to the server to set the corresponding timeout value, according to the expected maximum instance life time.
You can set days as timeout, if necessary, or completely disable it by setting a value of 0.

Offline

#7 2013-12-30 12:25:38

wai-kit
Member
From: Amsterdam, the Netherlands
Registered: 2012-11-27
Posts: 90

Re: Client Driven objects not working

I have this situation where a client connects (sicClientDriven) to the server (to consume a interface based webservice) and possibly stays idle for a couple of hours resulting in a timeout at the server.

What is the best thing to do in this case?

I tried to free the client (TSQLHTTPClient) and create a new instance, but then I get an Acces Violation when I try to use the interface.

Just did some RTFM :-) and did the following:
Release the interface by setting it to nil and call client.ServiceRegister() again.

For testing purposes the TImeout is set to 1 sec. In the log I see 'client instance not found or deprecated' and now when the client needs data it starts a new connection to the server.
So far so good ...

Last edited by wai-kit (2013-12-30 14:02:36)


fpcdeluxe, FPC 3.2 / Lazarus 2.0, mORMot on Windows 10 ...

Offline

#8 2013-12-30 14:46:34

ab
Administrator
From: France
Registered: 2010-06-21
Posts: 14,242
Website

Re: Client Driven objects not working

wai-kit wrote:

Release the interface by setting it to nil and call client.ServiceRegister() again.

In this case, a new session will be created.
sad

Perhaps we may implement:
- Session recovery (from its ID);
and/or
- Auto-reconnection to the server at HTTP level;
- any other idea...

Offline

#9 2013-12-30 15:31:23

wai-kit
Member
From: Amsterdam, the Netherlands
Registered: 2012-11-27
Posts: 90

Re: Client Driven objects not working

Oops!
In my case, I just have a few clients connecting to the server. If it was a couple of hundreds (or more) I'd start worrying.

IMHO, I think auto reconnection to the server is a good choice, assuming that the server has already cleanup the old session. It is then 'transparent' to the user
of the client.


fpcdeluxe, FPC 3.2 / Lazarus 2.0, mORMot on Windows 10 ...

Offline

#10 2013-12-30 17:15:42

wai-kit
Member
From: Amsterdam, the Netherlands
Registered: 2012-11-27
Posts: 90

Re: Client Driven objects not working

So, now what I did is to add an extra routine (called Ping) to my interface. 
In my client, when a call to Ping fails, the client instance and the interface is freed so I can create again.


fpcdeluxe, FPC 3.2 / Lazarus 2.0, mORMot on Windows 10 ...

Offline

Board footer

Powered by FluxBB