I have several servers behind a router. The server with the routerprovider (datamodule with TRtcDataRouter components) serves some requests, mainly session-stuff and routes the rest. The routerprovider has the lowest CheckOrder value for it's ServerLink.
Some of the servers "behind" the router needs to get small tidbits of cached data from some one of the servers. Rather than coding tables of the different servers addresses and ports for each one (the datamodules can be compiled into different services too so that messes that approach up even more), i use the router to route even the client requests made by the servers themselves. This has worked fine, i think.
Today i made such a client request from a server (lets call it the settings server). The thing with this request is that it goes to the router and then back to the settings server /itself/ where another datamodule with another TRtcDataProvider serves the request. This did not work because the client request gets stuck at the router! After a while of hair-pulling i copied the TRtcDataRouter component (and the TRtcDataRequest and TRtcHttpClient that comes with it) and moved that particular request to be routed by this new TRtcDataRouter component. And now things works as they should again!
All TRtcHttpServer components are multithreaded. The router provider has MultiThread and HyperThreaded checked fo all components. I was under the impression that using a fully multithreaded server the requests would all be served inside their own thread. So i can not understand why this particular request (though i know what is different with it of course) get stuck. Interesting is that the client request fired by the event handler for the TRtcDataProvider reaches the router immediately but reaches (back to) the settings server more or less exactly one minute after it came to the router.
What i have in the router provider is repetitions of the following setup for each potential target server:
procedure TRouting_Provider.RtcDataRouter1CheckRequestI(Sender: TRtcDataServer);
begin
if (Sender.Request.FilePath.Equal(0, 'COMMAND1') or
Sender.Request.FilePath.Equal(0, 'COMMAND2)) then
Sender.Accept;
end;
procedure TRouting_Provider.RtcDataRouter1PostNewRequestI(
Sender: TRtcDataServer; var DataRequest: TRtcDataRequest;
var AddToQueue: Integer; var MoveToBottom: Boolean);
begin
if FClosing then exit;
DataRequest := RtcDataRequest1;
end;
procedure TRouting_Provider.RtcDataRouter1RequestReceivedI(
Sender: TRtcDataServer; Content: TRtcRouterContentBody);
begin
RequestReceived(Sender, Content);
end;
Where "RequestReceived" changes some header info (something like Sender.Request.Value['somesessioninfo'] := 'info'
it does NOT touch the Content parameter.
Each TRtcDataRouter component has a TRtcDataRequest component (designtime) with "HyperThreading" checked. Each TRtcDataRequest component has a TRtcHttpClient component (designtime) with "MultiThreaded" set to true.
Either i have done something very wrong with the way i use the router component or i have missed something basic with this whole thing. I know about the demos (those where used). Maybe the router is waiting for the initial request to finish in these cases? But in that case how can the router serve multiple users? I am at a loss here and would appreciate any pointers or insights.
Regards,
/Dany