How to get actual value of global variables in ISAPI?

132 views Asked by At

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.

2

There are 2 answers

0
Stijn Sanders On

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.

0
JBD On

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)