Please see following code. This is a datamodule used in fcgi application. I removed default TFPWebModule which is automatically created when I create a new FastCGI project, and added plain TDataModule.
unit dfcgitest1;
{$mode objfpc}{$H+}
interface
uses
Classes, SysUtils, httpdefs, httproute;
type
{ Tdm_fcgitest }
Tdm_fcgitest = class(TDataModule)
procedure DataModuleCreate(Sender: TObject);
procedure DataModuleDestroy(Sender: TObject);
private
Count : integer;
mid : integer;
procedure DoHello(ARequest:TRequest; AResponse:TResponse);
procedure GoodMorning(ARequest:TRequest; AResponse:TResponse);
procedure Guide(ARequest:TRequest; AResponse:TResponse);
public
end;
var
dm_fcgitest: Tdm_fcgitest;
ModuleID: integer = 0;
procedure Log(s: string);
implementation
procedure Log(s: string);
var
f: TextFile;
fn: string;
begin
fn := 'c:\temp\fcgi-test.log';
AssignFile(f, fn);
if FileExists(fn) then Append(f) else Rewrite(f);
writeln (f, TimeToStr(now) + ' ' + s);
Closefile(f);
end;
{$R *.lfm}
{ Tdm_fcgitest }
procedure Tdm_fcgitest.DataModuleCreate(Sender: TObject);
begin
inherited;
Count := 0;
ModuleID += 1;
Mid := moduleid;
Log('Datamodule created ' + IntToStr(Mid));
end;
procedure Tdm_fcgitest.DataModuleDestroy(Sender: TObject);
begin
log('dataModule destroyed ' + IntToStr(Mid));
end;
procedure Tdm_fcgitest.DoHello(ARequest: TRequest; AResponse: TResponse);
begin
Count += 1;
Sleep(5000); // This waits for 5 second
AResponse.Content := 'Hello, World from fcgi_test - datamodule<br>'
+ 'Count = ' + IntToStr(Count)
+ '<br>ModuleID = ' + IntTostr(mid);
end;
procedure Tdm_fcgitest.GoodMorning(ARequest: TRequest; AResponse: TResponse);
begin
AResponse.Content := 'Good Morning<br>'
+ 'Count = ' + IntToStr(Count)
+ '<br>ModuleID = ' + IntTostr(mid);
end;
procedure Tdm_fcgitest.Guide(ARequest: TRequest; AResponse: TResponse);
begin
AResponse.Content := 'You need action'
+ 'ModuleID = ' + IntTostr(mid);
end;
initialization
dm_fcgitest := Tdm_fcgitest.Create(nil);
HTTPRouter.RegisterRoute('/hello', @dm_fcgitest.DoHello);
HTTPRouter.RegisterRoute('/morning', @dm_fcgitest.GoodMorning);
HTTPRouter.RegisterRoute('*', @dm_fcgitest.Guide);
end.
This is to check whether a new module is created at new request, while webserver program is working on previous request. So there are Sleep(5000).
1) If I call Hello several times, the count increases by one, and it is shown as it is.
2) If I call Morning after I got response to the hello, then the count is the same as from Hello.
3) And if I call Morning while Hello is being processed, I get Count=0 (as expected). And I can check it at my log file (c:\temp\fcgi-test.log).
4) But ModuleID=1 always. In the log file, there are two lines
14:32:44 Datamodule created 1 <-- ID is always 1
14:33:25 Datamodule created 1
What does this mean? I can think of three possibilities.
1) New instance of datamodule; I think if there are new instance of the datamodule, then datamodule id should increase to 2.
2) New thread: But what about thread? If second datamodule is run on a new thread, is it possible that constructor Create is called, but actually another instance is not created?
3) New instance of whole application is created again, including initialization is done again : ModuleID is a variable outside of datamodule.
Which one would be the most likely one?