Can anyone explain this to me?
lazarus / 38-Networking and Web Programming
----------------------------------------------------------------------
egsuh · 2020-10-31 05:53
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.
Code: Pascal [Select][+][-]window.onload = function(){var x1 =
document.getElementById("main_content_section"); if (x1) { var x =
document.getElementsByClassName("geshi");for (var i = 0; i 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
'
+ 'Count = ' + IntToStr(Count) + '
ModuleID = ' +
IntTostr(mid);end; procedure Tdm_fcgitest.GoodMorning(ARequest:
TRequest; AResponse: TResponse);begin AResponse.Content := 'Good
Morning
' + 'Count = ' + IntToStr(Count) +
'
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
Quote 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?
----------------------------------------------------------------------
egsuh · 2020-10-31 06:00
Code: Pascal [Select][+][-]window.onload = function(){var x1 =
document.getElementById("main_content_section"); if (x1) { var x =
document.getElementsByClassName("geshi");for (var i = 0; i
initialization Log('initialization - ModuleID= ' +
Inttostr(moduleid));
I tested again by adding the above code. It seems that another
instance of whole application is created.
----------------------------------------------------------------------
zamronypj · 2020-10-31 10:10
With FastCGI, several processes of same application maybe created thus
cause code in initialization executed several times.
If FastCGI application run as CGI script, then for each request new
process is created.
If FastCGI application is run with mod_fcgid, mod_fcgid creates
several processes at once, depending on load.
If FastCGI is run with reverse proxy, then you control how many
application process running.
----------------------------------------------------------------------
egsuh · 2020-10-31 15:36
@ zamronypj
Thank you for your explanations. but I just work on Windows operating
system.
I'll write on another thread. FCGI creates another instance of the
application --- IIS does that in the case of Windows. Problem is that
it release / dispose the application from memory, if there are no
requests for a while (default is 5 minutes in case of IIS). The
disposal, however, does not free webmodule/datamodule. I'm looking
into this, as this seems to be one of the causes of failures.