#1 2017-05-17 12:30:17

DigDiver
Member
Registered: 2013-04-29
Posts: 137

TSQLHttpServer with custom ThreadClass

I suggest adding the ability to create threadPool for TSQLHttpServer with custom ThreadClass.

Here is an example of pseudocode:

  Type
   TAPIServer = class(TSQLRestServerFullMemory)
  ...
    published  procedure ServerMethod(Ctxt: TSQLRestServerURIContext); 
   ...
   
  procedure TAPIServer.ServerMethod(Ctxt: TSQLRestServerURIContext);
  var
   Obj1 : TSomeObject;
   Obj2 : TOtherObject;
   ...
  begin
   Obj1 := TSomeObject.Create;
   Obj2 := TOtherObject.Create;
   try
    // Heavy creation
    ...
    // Some calculations
    ...
    // Network functions


    Ctxt.Returns(AnyValue); 

   finally
    Obj1.free;
    Obj2.free;
   end;
  end;  
 

In this example, for each call ServerMethod some amount of objects is created and destroyed.
Objects initialization can be costly both in time and in CPU, eg compiling a large number of regular expressions,
creating hash tables and so on. And all this is destroyed after the method is executed.

You can of course create a separate class, and call its methods through CriticalSection, but
with long calculations it will greatly slow down the server.

How to improve:

type TThreadClass = class of TSynThread;
 ..
TSQLHttpServer.Create(const aPort: AnsiString; aServer: TSQLRestServer;
      const aDomainName: AnsiString='+';
      aHttpServerKind: TSQLHttpServerOptions=HTTP_DEFAULT_MODE; aRestAccessRights: PSQLAccessRights=nil;
      ServerThreadPoolCount: Integer=32; aHttpServerSecurity: TSQLHttpServerSecurity=secNone;
      const aAdditionalURL: AnsiString=''; const aQueueName: SynUnicode=''; ThreadClass: TThreadClass);

     
The TSQLHttpServer constructor is called with a class reference ThreadClass.
When TSQLHttpServer is cloned, it creates threads with our class.   

type 
 TMyThreadClass = class(TSynThread)      
 ..
 end;

 consturctor TMyThreadClass.Create()
 var
   Obj1 : TSomeObject;
   Obj2 : TOtherObject;
   ...
  begin
   Obj1 := TSomeObject.Create;
   Obj2 := TOtherObject.Create;
   // Heavy creation
  end; 
..

 HttpServer  :=  TSQLHttpServer.Create(Port, [APIServer], '+',  useHttpApi, 32, false, TMyThreadClass);
 

In the ServerMethod we get the pointer on Thread, which currently serves THttpServerRequest
and call the thread method:

 procedure TAPIServer.ServerMethod(Ctxt: TSQLRestServerURIContext);
 var
  MyTh : TMyThreadClass;
 begin
  MyTh := Ctxt.Thread as TMyThreadClass;
  MyTh.calculation(Ctxt.inputUtf8['value1']);
  Ctxt.Returns(MyTh.CalculatedValue);
 end;
 

In this case, we noticeably speed up the processing of requests and reduce the load on the memory and CPU.

What do you think?

Offline

#2 2017-05-17 13:43:37

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

Re: TSQLHttpServer with custom ThreadClass

I don't understand your point.

Each method is already executed in its own thread, from the http server thread pool, so I don't see why creating a new thread may help here.
You are not even using your thread execution context - just its properties!

So if you want to re-use some existing resource, create a pool of resources.

Note that you have already some thread execution options for method-based services, with TSQLRest.AcquireExecutionMode[execSOAByMethod] property.
See https://synopse.info/files/html/Synopse … #TITLE_288

Offline

#3 2017-05-17 14:01:55

DigDiver
Member
Registered: 2013-04-29
Posts: 137

Re: TSQLHttpServer with custom ThreadClass

Each method is already executed in its own thread, from the http server thread pool, so I don't see why creating a new thread may help here

There is no need to create a new thread. If you pass a reference to a class, then create a thread inherited from TSynThread instead of plain TSynThread, by default create TSynThread as it is.

So if you want to re-use some existing resource, create a pool of resources.

Now it is implemented in this way. Only in this case the another thread pool is used.

Offline

#4 2017-05-17 15:13:22

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

Re: TSQLHttpServer with custom ThreadClass

How the thread is created depends on how the HTTP server is implemented.
It may be a from a thread pool, or not. It may inherit from TSynThread, but not directly.

Let the logic depend from this implementation detail is a wrong idea.
There are other cleaner options available, focusing on resources, not threads.

Your design is clearly breaking the Single Responsibility OOP Principle.

The cleanest way to handle such case may be to use a sicClientDriven interface-based service...

Offline

#5 2017-05-17 15:53:15

oz
Member
Registered: 2015-09-02
Posts: 95

Re: TSQLHttpServer with custom ThreadClass

ab wrote:

How the thread is created depends on how the HTTP server is implemented.
It may be a from a thread pool, or not. It may inherit from TSynThread, but not directly.

Let the logic depend from this implementation detail is a wrong idea.
There are other cleaner options available, focusing on resources, not threads.

Your design is clearly breaking the Single Responsibility OOP Principle.

The cleanest way to handle such case may be to use a sicClientDriven interface-based service...

I'm with Arnaud here. What you need sounds like some kind of ressource pool, not threadpool. If using interface base services in sicClientDriven mode is no option, then there's no other way then using custom ressource pools i guess.
Cheers.

Offline

Board footer

Powered by FluxBB