0

I want to make ISAPI dll for Apache with Delphi (10.4) WebBroker. It works fine. But then I want to add some kind of sessions monitor: the idea is to add idTCPServer on WebModule and get by it some global variable with all current "sessions". For test reasons I make infinite loop "while true" in every request to webmodule default handler action. Before loop I also add value to global variable DictRequests: Tdictionary<Tguid, string>. So the problem is when I'm doing, for example, 5 requests with infinite loop and trying to get by TCP DictRequests.Count I get only 1 request and another four only after about 20 seconds. I suppose that the problem is in threads instances of isapi, maybe you can give some advice how to get the actual value of global variable?

type
  TWebModule2 = class(TWebModule)
    IdTCPServer1: TIdTCPServer;
    procedure WebModule2DefaultHandlerAction(Sender: TObject;
      Request: TWebRequest; Response: TWebResponse; var Handled: Boolean);
    procedure IdTCPServer1Execute(AContext: TIdContext);
  end;

var
  WebModuleClass: TComponentClass = TWebModule2;
  DictRequests: Tdictionary<Tguid, TRequest>;

implementation

procedure TWebModule2.IdTCPServer1Execute(AContext: TIdContext);
var
  Item: TPair<TGuid, TRequest>;
  DictContent: String;
begin
  AContext.Connection.IOHandler.readln;
  AContext.Connection.IOHandler.writeln(
          DateTimeToStr(now) +
          #13#10 +
          'DictGUid.Count: ' + #9 + inttostr(DictRequests.Count));


procedure TWebModule2.WebModule2DefaultHandlerAction(Sender: TObject;
  Request: TWebRequest; Response: TWebResponse; var Handled: Boolean);
var
  guid: Tguid;
begin

  guid := TGUID.NewGuid;

  DictRequests.Add(guid, 'some kind of data');

  while True do
  begin
  end;

  Response.Content :=
              '<html>' +
              '<head><title>2_Web Server Application</title></head>' +
              '<body>' DATETIME = ' + DateTimeToStr(now) + '</body>' +
              '</html>';
end;

initialization
  DictRequests := TDictionary<Tguid, TRequest>.Create;

What I get from tcp: 03.05.2023 9:12:27 DictGUid.Count: 1 03.05.2023 9:12:41 DictGUid.Count: 3 03.05.2023 9:12:41 DictGUid.Count: 5

If I remove while-true it all works as expected.

JBD
  • 1
  • Not sure for Apache, but IIS starts new instance of your module when request takes too much time. Take a look at this point. Best way for debuging - start your module directly from Delphi (IIS alows it) or use some kind of logs. – Oleksandr Morozevych May 03 '23 at 09:21
  • Well, i have tried it with iis and the same thing happened in there. I also use debug, but there i can see only same results: DictRequests.Count update in 20 seconds. – JBD May 03 '23 at 09:34
  • Try to add into your DictRequests HInstance of your dll. Maybe server thinks that your code is hang and he kill your instance and start newone? Compare HInstance of few requests to know exactly. – Oleksandr Morozevych May 03 '23 at 11:39
  • Checked it - all requests have the same HInstance – JBD May 03 '23 at 12:40

2 Answers2

0

If you write

while true do
begin
end;

anywhere, it will lock the thread of execution indefinitely. Any code after it may not get executed.

I would advise to start a separate Delphi project with the TIdTCPServer component (typically a sand-alone exe file or an NT-service), and use a TIdTCPClient component to connect to that server from each TWebModule2.WebModule2DefaultHandlerAction to read the data stored and managed by the server.

Stijn Sanders
  • 35,982
  • 11
  • 45
  • 67
0

If someone meet similar problem: suddenly turns out that there was no problem with ISAPI, the main reason of 20 seconds latency in updating global variables lies in specific work of browsers. I tested the interaction with isapi by opening several tabs in a row in one browser. Each tab had the same url and apparently the browser sent only one request instead of 5 requests for 5 tabs to "make it easier for itself". So the problem was solved by using jmeter. Each request was immediately sent to a separate thread and the values of global variables were updated (even with an infinite loop running)

JBD
  • 1