Jump to content

Recommended Posts

Hello
I use TSslHttpCli in my backend built on DelphiMVCFramework for query external services.

The TSslHttpCli object embedded into DelphiMVCFramework session and used each time then client called my endpoint.

This call each time occurs in different thread. For certain reasons a can't create, use and free TSslHttpCli object each time in one thread context.

 

I want to use thread context switching. Is this code safe?

// initialization
fClient: TSslHttpCli;
...
fClient := TSslHttpCli.Create( nil );
fClient.MultiThreaded := True;


// using
if fClient.ThreadID = 0 then
  fClient.ThreadAttach;
try
  fClent.Post(...);
finally
  fClient.ThreadDetach;
end;

 

Share this post


Link to post

At first glance it is not correct. The component is asynchronous. Calling one method will merely start the process in the background. You shouldn't detach the component from the thread before it has finished the operation you requested.

 

You should remind that ICS components are asynchronous and doesn't require multi-threading to execute a lot of operations in parallel. Multi-threading is only useful if you have a large number (hundreds) of active communications simultaneously. Other operations that your application does may require multi-threading, for example lengthy SQL requests if they don't use an asynchronous programming model.

 

 

 

Share this post


Link to post

Since the code of [using] section is already executed in a separate thread, I use the synchronous Get method and not GetAsync
I expect that in the finally section work of Get method will be completed
 

1 hour ago, FPiette said:

At first glance it is not correct.

 

What do you think would be the correct solution?
 

Edited by Mark Lobanov

Share this post


Link to post
54 minutes ago, Mark Lobanov said:

What do you think would be the correct solution?

Use pure asynchronous operation.

Share this post


Link to post
23 hours ago, Mark Lobanov said:

code of [using] section is already executed in a separate thread

have I use TSslHttpCli.PostAsync method ?
separate thread is the TTask.Run() thread

Edited by Mark Lobanov

Share this post


Link to post

Why in the first place do you create a thread? Is this a DelphiMVCframework requirement?

 

Of course you can put your TSslHttpCli component in a thread. You should better create it at the beginning of the Execute method and free it before returning from the execute method (With a try/finally construct). Your thread need to have a message pump or call the one in TWSocket to work properly. There are a few samples of threads in ICS distribution.

 

Multi-threading is always more complex and overkill with an asynchronous component.

Share this post


Link to post

Thank you, i saw the topic

 

but is not my case.


I can't create, run and free TSslHttpCli object in the same thread context for performance reasons and business flow.

I have to create and free TSslHttpCli object within DelphiMVCFramework session and reuse it each time my endpoints are called.

Each time my endpoint is called, new thread is created by DelphiMVCFramework engine with TTask.Run() and TSslHttpCli object is used in that thread context, each endpoint call - new thread, quite so DelphiMVCFramework works.

I also can't use DelphiMVCframework's embedded HttpClient because it doesn't support TLS1.3 ((

 

 

Share this post


Link to post

So effectively you want to use an external pool of TSslHttpCli objects from within your threads, rather than creating them as needed within the threads? 

 

So why use TSslHttpCli  in the thread, why not just use one of the pool objects asynchronously, waiting in the thread for a semaphore to be set on competition? 

 

Windows actually creates a thread for async winsock operations, so there is no reason to use TSslHttpCli in the thread with all the messy stuff that goes with it. 

 

One of the ICS samples uses a pool of components and a queue to download all the elements on a web page.

 

Angus

 

Share this post


Link to post
32 minutes ago, Angus Robertson said:

So effectively you want to use an external pool of TSslHttpCli objects from within your threads, rather than creating them as needed within the threads?

I have a similar pattern but easier
One session, one client data (metadata, authorization, cookie etc.), one TSslHttpCli objects per session lifetime. No pool, no concurrent access to TSslHttpCli objects.

My problem is that the TSslHttpCli object is created in one thread and is used each time in another thread. On each second call TSslHttpCli objects freezes in httpDnsLookup state.

I do not want to use the asynchronous mode of the object yet. DelphiMVCFramework endpoint call is already in asynchronous mode within separate thread.

Besides I don't have access to this threat execute method to add custom message handler.


I added ThreadAttach/ThreadDetach code (look start message in this topic) and freezes gone but I not sure that this code is safe. François Piette thinks this is the wrong code

Share this post


Link to post

Your solution may be easier than a pool, but it does not seem to work.  ICS was not designed for cross thread use, use of threads within ICS is very rare, only for long ZLIB operations and a background mail queue. 

 

Angus

 

Share this post


Link to post
55 minutes ago, Mark Lobanov said:

I added ThreadAttach/ThreadDetach code (look start message in this topic) and freezes gone but I not sure that this code is safe. François Piette thinks this is the wrong code

What I meant is that it is not the best way to use ICS.

What Angus suggested is a good idea. Have your pool of ICS components run asynchronously in a single thread dedicated to that. And from the session thread, call the pool thread to execute the HTTP requests. Use thread synchronization object to make sure no conflict with concurrent access from all session threads.

 

You can use ThreadAttach and thread detach if you like but you must be sure to attache before socket is opened and before any communication take place and detach after all communication is done and socket closed. I'm not sure about OpenSSL work when used from several threads.

Share this post


Link to post

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
×