Recent

Author Topic: Can anyone explain this to me?  (Read 335 times)

egsuh

  • Hero Member
  • *****
  • Posts: 504
Can anyone explain this to me?
« on: October 31, 2020, 06:53:22 am »
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][+][-]
  1. unit dfcgitest1;
  2.  
  3. {$mode objfpc}{$H+}
  4.  
  5. interface
  6.  
  7. uses
  8.    Classes, SysUtils, httpdefs, httproute;
  9.  
  10. type
  11.  
  12.    { Tdm_fcgitest }
  13.  
  14.    Tdm_fcgitest = class(TDataModule)
  15.       procedure DataModuleCreate(Sender: TObject);
  16.       procedure DataModuleDestroy(Sender: TObject);
  17.    private
  18.       Count : integer;
  19.       mid : integer;
  20.       procedure DoHello(ARequest:TRequest; AResponse:TResponse);
  21.       procedure GoodMorning(ARequest:TRequest; AResponse:TResponse);
  22.       procedure Guide(ARequest:TRequest; AResponse:TResponse);
  23.  
  24.    public
  25.  
  26.    end;
  27.  
  28. var
  29.    dm_fcgitest: Tdm_fcgitest;
  30.    ModuleID: integer = 0;
  31.  
  32. procedure Log(s: string);
  33.  
  34.  
  35. implementation
  36.  
  37. procedure Log(s: string);
  38. var
  39.    f: TextFile;
  40.    fn: string;
  41. begin
  42.    fn := 'c:\temp\fcgi-test.log';
  43.    AssignFile(f, fn);
  44.    if FileExists(fn) then Append(f) else Rewrite(f);
  45.    writeln (f, TimeToStr(now) + '  ' + s);
  46.    Closefile(f);
  47. end;
  48.  
  49. {$R *.lfm}
  50.  
  51. { Tdm_fcgitest }
  52.  
  53. procedure Tdm_fcgitest.DataModuleCreate(Sender: TObject);
  54. begin
  55.    inherited;
  56.  
  57.    Count := 0;
  58.    ModuleID += 1;
  59.    Mid := moduleid;
  60.    Log('Datamodule created ' + IntToStr(Mid));
  61. end;
  62.  
  63. procedure Tdm_fcgitest.DataModuleDestroy(Sender: TObject);
  64. begin
  65.    log('dataModule destroyed ' + IntToStr(Mid));
  66. end;
  67.  
  68. procedure Tdm_fcgitest.DoHello(ARequest: TRequest; AResponse: TResponse);
  69. begin
  70.   Count += 1;
  71.   Sleep(5000);    // This waits for 5 second
  72.   AResponse.Content := 'Hello, World from fcgi_test - datamodule<br>'
  73.            + 'Count = ' + IntToStr(Count)
  74.            + '<br>ModuleID = ' + IntTostr(mid);
  75. end;
  76.  
  77. procedure Tdm_fcgitest.GoodMorning(ARequest: TRequest; AResponse: TResponse);
  78. begin
  79.   AResponse.Content := 'Good Morning<br>'
  80.            + 'Count = ' + IntToStr(Count)
  81.            + '<br>ModuleID = ' + IntTostr(mid);
  82. end;
  83.  
  84. procedure Tdm_fcgitest.Guide(ARequest: TRequest; AResponse: TResponse);
  85. begin
  86.    AResponse.Content := 'You need action'
  87.               + 'ModuleID = ' + IntTostr(mid);
  88. end;
  89.  
  90. initialization
  91.     dm_fcgitest := Tdm_fcgitest.Create(nil);
  92.     HTTPRouter.RegisterRoute('/hello', @dm_fcgitest.DoHello);
  93.     HTTPRouter.RegisterRoute('/morning', @dm_fcgitest.GoodMorning);
  94.     HTTPRouter.RegisterRoute('*', @dm_fcgitest.Guide);
  95. 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

  • Hero Member
  • *****
  • Posts: 504
Re: Can anyone explain this to me?
« Reply #1 on: October 31, 2020, 07:00:37 am »
Code: Pascal  [Select][+][-]
  1. initialization
  2.     Log('initialization - ModuleID= ' + Inttostr(moduleid));
  3.  

I tested again by adding the above code. It seems that another instance of whole application is  created.

zamronypj

  • Full Member
  • ***
  • Posts: 104
    • Fano Framework, Free Pascal web application framework
Re: Can anyone explain this to me?
« Reply #2 on: October 31, 2020, 11:10:09 am »
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.
Fano Framework, Free Pascal web application framework https://fanoframework.github.io
Personal Projects https://v3.juhara.com
Github https://github.com/zamronypj

egsuh

  • Hero Member
  • *****
  • Posts: 504
Re: Can anyone explain this to me?
« Reply #3 on: October 31, 2020, 04:36:08 pm »
@ 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.

 

TinyPortal © 2005-2018