I was testing a simple Delphi ISAPI application in order to see how it internally works when IIS receive multiple/parallel requests.
I know IIS can span multiple "IIS Worker Process" probably to do just that, but, as per application-pool settings, the default is 1 single "IIS Worker Process".
I know IIS (in each single "IIS Worker Process") can create multiple TWebModules
instances in separate threads in order to handle concurrent / parallel requests.
Is there a way to identify each "currently running" TWebModule
? Maybe via some "reference" or ID each TWebModule
has?
My current project file:
library TestIsapiProject;
uses
Winapi.Windows,
Winapi.ActiveX,
System.SysUtils,
System.Win.ComObj,
Web.WebBroker,
Web.Win.ISAPIApp,
Web.Win.ISAPIThreadPool,
TestIsapiMainWebModuleUnit in 'TestIsapiMainWebModuleUnit.pas' {WebModule1: TWebModule};
exports
GetExtensionVersion,
HttpExtensionProc,
TerminateExtension;
begin
ReportMemoryLeaksOnShutdown := true;
CoInitFlags := COINIT_MULTITHREADED;
IsMultiThread := true; // already present in ...
TISAPIApplication(Application).OnTerminate := TerminateLast; // very last finalize
Application.MaxConnections := 2; // connectionsactivemax 32 by default
NumberOfThreads := Application.MaxConnections;
Application.CacheConnections := true; //not IsDebuggerPresent; // default is true, false will create/destroy isapidll with each request, do not use it in production
Application.Initialize;
Application.WebModuleClass := WebModuleClass;
Application.Run;
end.
and web-module:
unit TestIsapiMainWebModuleUnit;
interface
uses
System.SysUtils
, System.Classes
, Web.HTTPApp
;
type
TWebModule1 = class(TWebModule)
procedure WebModule1DefaultHandlerAction(Sender: TObject; Request: TWebRequest; Response: TWebResponse; var Handled: Boolean);
private
{ Private declarations }
public
{ Public declarations }
end;
var
WebModuleClass: TComponentClass = TWebModule1;
implementation
uses
Winapi.Windows
, Web.Win.ISAPIHTTP
, Web.WebBroker
;
function GetProcessID: cardinal; register; assembler;
{$IFDEF 32BIT}
asm
mov eax, FS:[$20]
end;
{$ELSE}
begin
Result := Winapi.Windows.GetCurrentProcessId;
end;
{$ENDIF}
function GetThreadId: cardinal; register; assembler;
{$IFDEF 32BIT}
asm
mov eax, FS:[$24]
end;
{$ELSE}
begin
Result := Winapi.Windows.GetCurrentThreadID;
end;
{$ENDIF}
procedure TWebModule1.WebModule1DefaultHandlerAction(Sender: TObject; Request: TWebRequest; Response: TWebResponse; var Handled: Boolean);
begin
Response.Content :=
'<html>'
+ sLineBreak + '<head><title>Web Server Application</title></head>'
+ sLineBreak + '<body>'
+ sLineBreak + '<pre>'
+ sLineBreak + 'Test Isapi Web Server Application'
+ sLineBreak + 'datetime : ' + DateTimeToStr(Now)
+ sLineBreak + 'pid : ' + GetProcessID.ToString
+ sLineBreak + 'tid : ' + GetThreadId.ToString
+ sLineBreak + 'requestconnid : ' + (Request as TISAPIRequest).Ecb^.ConnId.ToString
+ sLineBreak + 'connection/webmodule: ' + '???'
+ sLineBreak + 'maxconnections : ' + Application.MaxConnections.ToString
+ sLineBreak + 'activeconnections : ' + Application.ActiveCount.ToString
+ sLineBreak + 'inactiveconnections : ' + Application.InActiveCount.ToString
+ sLineBreak + 'cachedconnections : ' + Ord(Application.CacheConnections).ToString
+ sLineBreak + '<pre>'
+ sLineBreak + '</body>'
+ sLineBreak + '</html>';
end;
end.