#1 2013-04-12 08:18:49

sjerinic
Member
Registered: 2013-02-11
Posts: 51

What I'm doing wrong?

I have interface based service.

type
  TServiceRemoteLiveServerStandard = class(TInterfacedObject, IRemoteLiveServerStandard)
  protected
    fProps: TOleDBMSSQL2008ConnectionProperties;
  public
    destructor Destroy; override;
    procedure AfterConstruction; override;
...

On event AfterConstruction I create props with DBConnection data and on destructor try to destroy props, but catch error "You should call TOleDBConnection.Free from the same thread which called its Create: i.e. call MyProps.EndCurrentThread from an THttpServerGeneric.OnHttpThreadTerminate event - see ticket 213544b2f5."

Does anybody can help me? What is solution? To move create and destroy props somewhere else and where?

procedure TServiceRemoteLiveServerStandard.AfterConstruction;
var
  iniData:  TiniData;
begin
  inherited;

  if fProps = nil then
  begin
    iniData := TiniData.Create;
    try
      JSONFileToObject(C_IniFileName, iniData);

      fProps := TOleDBMSSQL2008ConnectionProperties.Create(
        iniData.ServerName,
        iniData.DatabaseName,
        iniData.Username,
        DecryptData(iniData.Password, c_ApplicationName)
      );
    finally
      FreeAndNil(iniData);
    end;
  end;
end;

destructor TServiceRemoteLiveServerStandard.Destroy;
begin
//  fProps.EndCurrentThread;
  FreeAndNil(fProps);

  inherited;
end;

Offline

#2 2013-04-12 08:58:01

chapa
Member
Registered: 2012-04-30
Posts: 117

Re: What I'm doing wrong?

Probably you wish to create and destroy TIniData at inside your REST server, which will be done once.
And use threadvar ServiceContext inside your interface service.

Or define any method to be called inside TServiceRemoteLiveServerStandard, do all "create try finaly destroy" operations.

Sample 14 - "14 - Interface based services" may help you.

Offline

#3 2013-04-12 09:22:28

sjerinic
Member
Registered: 2013-02-11
Posts: 51

Re: What I'm doing wrong?

I want make create TSQLDBConnectionProperties for each connected user and destroy TSQLDBConnectionProperties on logout or timeout.

something like:
- New user Login on TSQLHttpServer. Create in TSQLRestServerFullMemory new TSQLDBConnectionProperties for TServiceRemoteLiveServerStandard service (with that TSQLDBConnectionProperties TServiceRemoteLiveServerStandard  services will use SQLServer database)
- User Logout on TSQLHttpServer. Destroy in TSQLRestServerFullMemory for TServiceRemoteLiveServerStandard service TSQLDBConnectionProperties



chapa wrote:

Probably you wish to create and destroy TIniData at inside your REST server, which will be done once.
And use threadvar ServiceContext inside your interface service.

Or define any method to be called inside TServiceRemoteLiveServerStandard, do all "create try finaly destroy" operations.

Sample 14 - "14 - Interface based services" may help you.

Offline

#4 2013-04-12 09:45:04

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

Re: What I'm doing wrong?

If you use remote HTTP access and a thread-pool, the incoming request may not be on the same thread.

I suppose the easiest in this case is to force the execution in the main thread.
This is what we do for instance in sample "16 - Execute SQL via services", in Project16ServerHttp.dpr:

      // register our IRemoteSQL service on the server side
      aServer.ServiceRegister(TServiceRemoteSQL,[TypeInfo(IRemoteSQL)],sicClientDriven).
        SetOptions([],[optExecInMainThread]);

This sample is in fact very close to what you expect to do, AFAIK.

And it will save you a lot of resources, since maintaining one connection per thread can be very costly.

Code was optimized not to slow down the process much, even if it is run in the main thread.

Offline

#5 2013-04-12 11:45:55

sjerinic
Member
Registered: 2013-02-11
Posts: 51

Re: What I'm doing wrong?

Now, I started Sample 16 and got same Exception like in my app. sad

Debugger Exception Notification

Project Project16ServerHttp.exe raised exception class EAssertionFailed with message 'You should call TOleDBConnection.Free from the same thread which called its Create: i.e call MyProps.EndCurrentThread from an THttpServerGeneric.OnHttpThreadTerminate event - see ticket 213544v2f5 (C:\......\SynOleDB.pas line 1884)'.

Delphy XE3, Windows 7 64bit, compiled Debug 32bit and mORMot from yesterday.

Offline

#6 2013-04-12 15:45:07

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

Re: What I'm doing wrong?

Could you please create a ticket so that we may fix it?

Offline

#7 2013-04-12 17:27:29

sjerinic
Member
Registered: 2013-02-11
Posts: 51

Re: What I'm doing wrong?

Posted.

Ticket ID is 57bea48f30c8ef59f2bb83fc3eb9f96401f6bfa2.

Thanks!

Offline

#8 2013-04-22 06:09:04

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

Re: What I'm doing wrong?

Ticket http://synopse.info/fossil/tktview?name=57bea48f30 should now be fixed.

We have added a new optFreeInMainThread execution options for the service, allowing server side service class instance release via Synchronize().

See the sample source code.

Note that the constructor won't be run in the main thread: if you initialize a fProps instance, you have to do this in a dedicated method, NOT at class initialization.

Offline

#9 2013-04-23 18:27:16

sjerinic
Member
Registered: 2013-02-11
Posts: 51

Re: What I'm doing wrong?

Thanks!

Looks like is ok. No fault occurs.

Offline

Board footer

Powered by FluxBB