#1 2015-09-07 08:30:43

edwinsn
Member
Registered: 2010-07-02
Posts: 1,215

OmniThreadLibrary's not working in mORMot's server-side method?

Update 1: This post has been updated to reflect the latest findings, it seems that the OmniThreadLibrary's CreateTask() is in a way not compatible with mORMot, please do directly to http://synopse.info/forum/viewtopic.php?id=2852#p17618 for more info.

Hi Arnaud,

In my program there is a background thread which creates a TSQLHttpClient and calls the ServerTimeStampSynchronize() method test the connection, and while it's reasonable that it emits the "EWinHTTP exception with message 'winhttp.dll error 12002 (timeout)'" when connecting to a computer where the server software is not running, I found it's strange that it hang the entire program, ie. the UI of the program is not responding, when calling the ServerTimeStampSynchronize() or other methods such as ServiceRegister().

Is there a fix? If I understand it correctly, a http connection in a background thread (not the main thread) should not lock up the UI. Thanks.

Last edited by edwinsn (2015-09-07 12:36:28)


Delphi XE4 Pro on Windows 7 64bit.
Lazarus trunk built with fpcupdelux on Windows with cross-compile for Linux 64bit.

Offline

#2 2015-09-07 09:29:50

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

Re: OmniThreadLibrary's not working in mORMot's server-side method?

For a background thread, it would NOT block the main thread.
I guess there is something wrong in your program.
If you initialize the TSQLHttpClient in the background thread, you may perhaps call ServerTimeStampSynchronize in the main thread: in this case, the background thread is not used - this is why it hangs.

Did you follow what is written in http://synopse.info/files/html/Synopse% … #TITLE_276 ?
This is the supported way of creating clients.

Offline

#3 2015-09-07 12:12:23

edwinsn
Member
Registered: 2010-07-02
Posts: 1,215

Re: OmniThreadLibrary's not working in mORMot's server-side method?

Well, after some more testing, it turned out the problem has nothing to do with TSQLHttpClient (because I replaced the http client connection with Sleep(5000) to rule it out), but there seems to be some incompatibility between OmniThreadLibrary (latest github SVN) and mORMot (I'm using the latest version about 1 day ago).

My server is configured like this:

  FDbSvr := TDbServer.Create(FDataModel, GetDbFileName, False);
  SetupServerLogging;
  FDBSvr.PublishAllServices;

  (*
    WAL might increase the risk of data losses!
    http://liferea.blogspot.jp/2012/03/morpheus-suggested-in-comment-to-check.html
    http://www.sqlabs.com/sqlitedoctor_details.php
    http://stackoverflow.com/a/20970876/133516
  *)
  FDbSvr.DB.WALMode := False;
  FDbSvr.DB.Synchronous := smFull;//ensure max data stability!

  FHttpSvr := TSQLHttpServer.Create(IntToStr(gServerPort), [FDbSvr], '+', HTTP_DEFAULT_MODE);
  FHttpSvr.AccessControlAllowOrigin := '*'; // allow cross-site AJAX queries;

and I have an interface-based service on the server side, with default configuration:

  /// this is the main interface exposed by the server
  TServerApi = class(TInterfacedObject, IServerApi)
  public
    function StartCommonDataDownload(aManualCall: Boolean): Boolean;
  end;

And in this StartCommonDataDownload() method, a thread will be started, like this:

/// approach A, the method will not return until 5 seconds are passed
function TServerApi.StartCommonDataDownload(aManualCall: Boolean): Boolean;
begin
  OtlTaskControl.CreateTask(
    procedure (const task: IOmniTask)
    begin
        Sleep(5000);
    end
  ).Run;
end;

/// approach B, the method will not return until 5 seconds are passed
function TServerApi.StartCommonDataDownload(aManualCall: Boolean): Boolean;
begin
    TThread.Queue(nil, procedure
      begin
        Sleep(5000);
      end
    );
end;

  /// approach C, works!
  Parallel.Async(procedure
  begin
      Sleep(5000);
  end);

Only approach C worked. Does it have anything to do with the way the TSQLHttpServer is running in? I run it with administrator and I guess it runs in the http.sys mode? (update: : tried useBidirSocket just now, same problem...) I also noticed the OmniThreadLibrary 's communication sub-system also is not working inside an interfaced service method...

Thanks for any help.

Last edited by edwinsn (2015-09-07 12:26:52)


Delphi XE4 Pro on Windows 7 64bit.
Lazarus trunk built with fpcupdelux on Windows with cross-compile for Linux 64bit.

Offline

#4 2015-09-07 13:26:05

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

Re: OmniThreadLibrary's not working in mORMot's server-side method?

I do not know anything about OTL internals.

Isn't there a global message queue to be pumped, somewhere?
Or some code to run from any new thread?

You may better ask OTL for support.

Offline

#5 2015-09-07 14:43:47

edwinsn
Member
Registered: 2010-07-02
Posts: 1,215

Re: OmniThreadLibrary's not working in mORMot's server-side method?

The related OTL community post: https://plus.google.com/u/0/11514338247 … Ys5?cfem=1

Last edited by edwinsn (2015-09-07 14:44:14)


Delphi XE4 Pro on Windows 7 64bit.
Lazarus trunk built with fpcupdelux on Windows with cross-compile for Linux 64bit.

Offline

#6 2015-09-07 17:21:44

edwinsn
Member
Registered: 2010-07-02
Posts: 1,215

Re: OmniThreadLibrary's not working in mORMot's server-side method?

Thanks to the help by the author of OTL Primoz, problem's fixed for approach A, OtlTaskControl.CreateTask needs the .Unobserved modifier!


Delphi XE4 Pro on Windows 7 64bit.
Lazarus trunk built with fpcupdelux on Windows with cross-compile for Linux 64bit.

Offline

Board footer

Powered by FluxBB