I'm using TIdHTTP
in my class to handle web APIs (TWebAPI
). Since it might happen that this class is used in a TIdHTTPServer.OnCommandGet
event handler, I need to make sure that TWebAPI
is thread safe.
Do I need to wrap a PUT
/GET
/POST
inside a TMultiReadExclusiveWriteSynchronizer
?
EDIT: Code-Sample
TWebAPI
TWebAPI=class(TObject)
FSocket:TidHTTP;
end;
procedure TWebAPI.Send;
Var
Response:TSTringStream;
begin
FSocket.Get(fURL,Response);
end;
Main Program
TMain=class(TForm)
Server:TidHTTPServer;
WebAPI:TWebAPI;
end;
procedure TMain.ServerCommandGet(....)
begin
WebAPI.Send;
end;
So my WebAPI would be used in different threads on each command the server gets. SHould I use the CriticalSection in TMain, or implement it in TWebAPI like this?
TWebAPI=class(TObject)
FSocket:TidHTTP;
FLock:TCriticalSection;
end;
procedure TWebAPI.Send;
Var
Response:TSTringStream;
begin
FLock.Aquire;
try
FSocket.Get(fURL,Response);
finally
FLock.Release;
end;
end;
A single TIdHTTP could be protected by a TCriticalSection
or TMonitor
. There is no R/W involved, so don't use TMultiReadExclusiveWriteSynchronizer
- just a mutex/lock. But if you use a single TIdHTTP you will need a mutex/lock, so all HTTP calls will be serialized, which may be not a good idea on a multi-threaded server.
I would maintain one connection per thread, or write a connection pool. Perhaps just a given TIdHTTP each time may not be too bad. At least it will be safe and there will be room for improvement later on. Reopening a TCP/HTTP connection is quick in practice.