#1 Re: mORMot 1 » Why 32 threads with 2 TSQLHttpServer ? » 2020-06-22 17:30:31

And with case 3 ,database connections count number  increase 1 every time from 32 up to 33,34,35 .......

all test on delphi 10.4.

Sorry for post a lot of Source Codes here....

1.   GlobalCodeServer.dpr

program GlobalCodeServer;

uses
  Vcl.Forms,
  Main in 'Main.pas' {FormMain},
  Services in 'Services.pas';

{$R *.res}

begin
  Application.Initialize;
  Application.MainFormOnTaskbar := True;
  Application.CreateForm(TFormMain, FormMain);
  Application.Run;
end.

1.1 Services.pas

unit Services;

interface

uses mORMot, Syncommons, SynOleDB, SynDB;

type
  IVeCode = interface(IInvokable)
    ['{DE580C16-54F4-4C82-860C-D60BE6374F29}']
    function GenCodes(aSetCode: RAWUTF8; aSvcCode: RAWUTF8): RAWUTF8;
  end;

  IPaCode = interface(IInvokable)
    ['{ED56F71A-37A3-4A3A-BB2B-827A6D03A390}']
    function GenCodes(aSetCode: RAWUTF8; aSvcCode: RAWUTF8): RAWUTF8;
  end;

  TVeCode = Class(TInterfacedObject, IVeCode)
  public
    function GenCodes(aSetCode: RAWUTF8; aSvcCode: RAWUTF8): RAWUTF8;
  End;

  TPaCode = Class(TInterfacedObject, IPaCode)
  public
    function GenCodes(aSetCode: RAWUTF8; aSvcCode: RAWUTF8): RAWUTF8;
  End;

var
  VeProp, PaProp: TOleDbMssqlConnectionProperties;

implementation

{ TVeUniCode }

function TVeCode.GenCodes(aSetCode, aSvcCode: RAWUTF8): RAWUTF8;
var
  _Data: Variant;
  aQuery: TSQLDBStatement;
begin

  // _Data := _Json(VeProp.Execute('select ?+? As Adata', [aSetCode, aSvcCode]).FetchAllAsJSON(true));
  aQuery := VeProp.NewThreadSafeStatement;
  aQuery.Execute('select ?+? As Adata', true, [aSetCode, aSvcCode]);
  _Data := _Json(aQuery.FetchAllAsJSON(true));
  aQuery.Free;
  Result := _Data._(0).Adata;
end;

{ TPaUniCode }

function TPaCode.GenCodes(aSetCode, aSvcCode: RAWUTF8): RAWUTF8;
var
  _Data: Variant;
  aQuery: TSQLDBStatement;
begin
  // _Data := _Json(PaProp.Execute('select ?+? As Adata', [aSetCode, aSvcCode]).FetchAllAsJSON(true));
  aQuery := PaProp.NewThreadSafeStatement;
  aQuery.Execute('select ?+? As Adata', true, [aSetCode, aSvcCode]);
  _Data := _Json(aQuery.FetchAllAsJSON(true));
  aQuery.Free;
  Result := _Data._(0).Adata;
end;

end.

1.2 Main.pas

unit Main;

interface

uses
  Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
  Vcl.Controls, Vcl.Forms, Vcl.Dialogs, mORMot, mORMotSqlite3, mORMotHttpServer, SynOleDB, SynSqlite3Static;

type
  TFormMain = class(TForm)
    procedure FormCreate(Sender: TObject);
    procedure FormDestroy(Sender: TObject);
  private
    { Private declarations }
    VeModel, PaModel: TSQLModel;
    VeRest, PaRest: TSQLRestServerDB;
    VeHttp, PaHttp: TSQLHttpServer;
  public
    { Public declarations }
  end;

var
  FormMain: TFormMain;

implementation

{$R *.dfm}

uses Services;

procedure TFormMain.FormCreate(Sender: TObject);
begin
  VeProp := TOleDBMssqlConnectionProperties.Create('127.0.0.1,1433', 'DB8', 'Sa', '1');
  PaProp := TOleDBMssqlConnectionProperties.Create('127.0.0.1,1433', 'DB8', 'Sa', '1');

  VeModel := TSQLModel.Create([], 'Ve');
  PaModel := TSQLModel.Create([], 'Pa');

  VeRest := TSQLRestServerDB.Create(VeModel, ':memory:');
  PaRest := TSQLRestServerDB.Create(PaModel, ':memory:');

  VeRest.ServiceRegister(TVeCode, [TypeInfo(IVeCode)], sicClientDriven);
  PaRest.ServiceRegister(TPaCode, [TypeInfo(IPaCode)], sicClientDriven);

  VeHttp := TSQLHttpServer.Create('888', [VeRest], '+');
  PaHttp := TSQLHttpServer.Create('999', [PaRest], '+');

  VeHttp.AccessControlAllowOrigin := '*';
  PaHttp.AccessControlAllowOrigin := '*';
end;

procedure TFormMain.FormDestroy(Sender: TObject);
begin
  VeHttp.Free;
  PaHttp.Free;
  VeRest.Free;
  PaRest.Free;
  VeModel.Free;
  PaModel.Free;
  VeProp.Free;
  PaProp.Free;
end;

end.

2.  GlobalCodeTest.dpr

program GlobalCodeTestCase;

{$APPTYPE CONSOLE}
{$R *.res}

uses
  System.SysUtils,
  Services in 'Services.pas', SynTests, mORMotHttpClient, mORMot;

type

  TTestClient = class(TSynTestCase)
  published
    procedure Test1;
  end;

  TTestSuit = class(TSynTestsLogged)
  published
    procedure MyTestSuit;
  end;

  { TTestSuit }

procedure TTestSuit.MyTestSuit;
begin
  AddCase([TTestClient]);
end;

{ TTestClient }

procedure TTestClient.Test1;
var
  VeModel, PaModel: TSQLModel;
  VeClient, PaClient: TSQLHttpClient;
  VeCode: IVeCode;
  Pacode: IPaCode;
  i: integer;
begin
  VeModel := TSQLModel.Create([], 'Ve');
  VeClient := TSQLHttpClient.Create('127.0.0.1', '888', VeModel);
  VeClient.ServiceRegister(TypeInfo(IVeCode), sicClientDriven);
  VeClient.ServerTimestampSynchronize;
  VeCode := VeClient.Service<IVeCode>;

  PaModel := TSQLModel.Create([], 'Pa');
  PaClient := TSQLHttpClient.Create('127.0.0.1', '999', PaModel);
  PaClient.ServiceRegister(TypeInfo(IPaCode), sicClientDriven);
  PaClient.ServerTimestampSynchronize;
  Pacode := PaClient.Service<IPaCode>;

  for i := 1 to 10000 do
  begin
    Check(VeCode.GenCodes('A', 'B') = 'AB');
    Check(Pacode.GenCodes('C', 'D') = 'CD');
  end;

  VeCode := nil;
  VeClient.Free;
  VeModel.Free;

  Pacode := nil;
  PaClient.Free;
  PaModel.Free;
end;

begin
  with TTestSuit.Create do
    try
      Run;
      readln;
    finally
      Free;
    end;

end.

#2 Re: mORMot 1 » Why 32 threads with 2 TSQLHttpServer ? » 2020-06-21 14:51:47

Access both server(888 and 999)  on case 3.
like

  client1.create(888); service1:=client1.service<IServiceA>; service1.dosomething;
  client2.create(999); service2:=client2.service<IServiceB>; service2.dosomething;

#3 Re: mORMot 1 » Why 32 threads with 2 TSQLHttpServer ? » 2020-06-21 14:29:27

----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|No.  |   type   |   httpserver (Port)                                      |       Create threads     |  TestCase  Console App                         | database connections  count |DataBase   |
|       |            |                                                                 |                                 |  Run 1 or 4 TestCase App at same time  |    3rd Tools Counted             |                 |
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|                 |
| 1    |   single |   Sqlhttpserver1(888)                                 |        32                     |          1 / 4                                           | 32 / 32                               |                 |
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|                 |
| 2    |   single |   Sqlhttpserver2(999)                                 |        32                     |          1 / 4                                           | 32 / 32                               | Same One |
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|                 |
| 3    |   both   |   Sqlhttpserver1(888),Sqlhttpserver2(999)   |        32+32               |          1 / 4                                           | 32 / 32                               |                 |
-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

I have tested all  3 scenarios .
The No.3 scenario confused me. The Database connections count still equals 32 ,not 64 .
Why this happened ?

#4 mORMot 1 » Why 32 threads with 2 TSQLHttpServer ? » 2020-06-21 05:34:11

zhyhero
Replies: 5

I have setup 2 TSqlHttpServer in same project and same procedure with diffrent port (888,999).

Both are TSqlHttpServer
             -->TSqlRestServerDb                             (with interfaced service sicShared or sicClientDriven)
             -->TSqlModel                                        (some TSqlRecords with diffrent rooturl)
             -->TOleDbMssqlConnectionPropperties    (connect to same one DB@Server).

And write a Console TestCase to Test 2 ways(port:888 And 999) interfaced service.

But 2 ways testcase are same DataBase connections counts with 1 way (port 888 or 999) testcase , count to 32.

Why not 2 way DataBase connections count to 32+32 ?

2 TSqlHttpServer with diffrent port(888 and 999) ,thread max count = 32+32 or 32?

These are confused me...............

Updated:

I Setup 2 TSqlHttpServer With 2 Propject(win32 application) ,and same result too.

#5 mORMot 1 » Multiple level SQLRecord define suport? » 2020-04-10 03:14:39

zhyhero
Replies: 0

Can we define an  'One to One to .... to One'  SQLRecord model ?

TclassX=class(TSQLRecord)
  ClassXProp:string;
end;

TClass(X-1)=class(TSQLRecord)
  Class(X-1)Prop:string;
  ClassX:TClassX;
end;

......

TClass2=class(TSQLRecord)
  Class2Prop:String;
  Class3:Tclass3;
end;

TClass1=class(TSQL)
  Class1Prop:string;
  Class2:TClass2;
end;

#6 Re: mORMot 1 » mORMot.pas compilation error (10.3.3, win64) » 2020-03-09 08:58:37

demo1  compile error
win10 64   
delphi 10.3.3 target platform win32     
[dcc32 Error] mORMot.pas(44390): E2003 Undeclared identifier: 'IsObjArray'





I found...

mORMot.pas(44390):      fValues.{$ifdef UNDIRECTDYNARRAY}InternalDynArray.{$endif}IsObjArray := true;
Synopse.inc(407):          {$define UNDIRECTDYNARRAY}


And file location...

/(root folder)
       Synopse.inc
/SQLite3(sub folder)
       mORMot.pas


So I changed...

mORMot.pas(71):           {$I Synopse.inc} // define HASINLINE CPU32 CPU64     ⋙   {$I ../Synopse.inc} // define HASINLINE CPU32 CPU64

Compile Success...

Is this right ?

#7 Re: mORMot 1 » Problem with serializing TSynDictionary and TDynArray » 2020-01-14 03:57:31

Hi,I got this ERROR with Demo 1.


Building Project01.dproj (Debug, Win32)
brcc32 command line for "Project01.vrc"
dcc32 command line for "Project01.dpr"
[dcc32 Error] SynCommons.pas(60169): E2034 Too many actual parameters
[dcc32 Fatal Error] Project01.dpr(86): F2063 Could not compile used unit 'SynCommons.pas'

#8 Re: mORMot 1 » [Problem] Implementation conn pool in unigui ? » 2018-01-27 09:01:42

Hi !

Finally,I had changed my project's structure。
unigui app<->mormot app<->database

TWinHttp(unigui app  servermodule.pas) as httpclient。
THttpApiServer(mormot app) as httpserver。
TOleDBMSSQLConnectionProperties(mormot app) as database client( or manager)。

thanks mpv's replys.

#9 Re: mORMot 1 » [Problem] Implementation conn pool in unigui ? » 2018-01-12 02:40:33

mpv wrote:

Inside dbconn.ExecuteInLined mORMot create a connection based on thread ID in which code is executed, so if UniGui create a copy of TUniServerModule for each client (web) connection in separate thread (looks like this is true), then you got as many Db connection as unigui threads. This is as expected.

Sorry for reply so late.

UniGui's UniServerModule is the main thread(only one,and globe shared ) at runtime ,the UniMainModules(thread shared or one client shared) are create in separate threads for every client connect the server.

#10 mORMot 1 » [Problem] Implementation conn pool in unigui ? » 2018-01-11 02:36:10

zhyhero
Replies: 10

Hello every one .

sad   Sorry for my poor english. I am a newbie with mormot.

I had create a unigui application,and use mormot as connection pool in unigui's servermodule unit.
This application connect a mssql database.
I got some problems on this project.
1.The pool create new connection several seconds or minutes.   when i test this , got 40+ connects after 30 minutes.
2.The connection count  look not  accuracy.

What is  wrong or missing ?

the source codes are here:
servermodule.pas unit

type
  TUniServerModule = class(TUniGUIServerModule)
  private
    { Private declarations }
    dbConn: TOleDBMSSQLConnectionProperties;
  protected
    procedure FirstInit; override;
  public
    { Public declarations }
    Procedure OpenSql(aSql:String;aFDMemTable:TFDMemTable);
    Procedure ExecSql(aSql:String);
    function GetConCount:integer;
  end;

implementation
Const
  cServer:RawUTF8='127.0.0.1';
  cDatabase:RawUTF8='testdb';
  cUserId:RawUTF8='sa';
  cUserPwd:RawUTF8='sapassword';

procedure TUniServerModule.ExecSql(aSql: String);
begin
  dbconn.ExecuteNoResult(aSql,[]);
end;

procedure TUniServerModule.FirstInit;
begin
  InitServerModule(Self);
  //add by myself
  dbconn:=TOleDBMSSQLConnectionProperties.Create(cServer,cDatabase,cUserId,cUserPwd);
  dbconn.ConnectionTimeOutMinutes:=1;
  //add by myself end
end;

function TUniServerModule.GetConCount: integer;
begin
  result:=dbconn.MainConnection.TotalConnectionCount;
end;

procedure TUniServerModule.OpenSql(aSql: String; aFDMemTable: TFDMemTable);
var
  rows: ISQLDBRows;
begin
  rows:=dbconn.ExecuteInLined(aSql,True);
  if aFDMemTable.Active=false then aFDMemTable.Open;
  aFDMemTable.EmptyDataSet;
  aFDMemTable.CopyDataSet(ToDataSet(aFDMemTable,rows),[coStructure,coRestart,coAppend]);
  aFDMemTable.CommitUpdates;
//  dbconn.EndCurrentThread;
end;

mainmodule.pas unit

type
  TUniMainModule = class(TUniGUIMainModule)
  private
    { Private declarations }
  public
    { Public declarations }
    procedure OpenSql(aSql:string;aFDMemTable:TFDMemTable);
    procedure ExecSql(aSql:String);
    function GetConCount:Integer;
  end;

implementation

procedure TUniMainModule.ExecSql(aSql: String);
begin
  UniServerModule.ExecSql(aSql);
end;

function TUniMainModule.GetConCount: Integer;
begin
  Result:=UniServerMOdule.GetConCount;
end;

procedure TUniMainModule.OpenSql(aSql: string; aFDMemTable:TFDMemTable);
begin
  UniServerModule.OpenSql(asql,aFDMemTable);
end;

mainform.pas unit

procedure TMainForm.UniButton1Click(Sender: TObject);
var
  SQL:String;
begin
  self.FDMemTable1.Close;
  sql:='select * from testtable';
  UniMainMOdule.OpenSql(sql,self.FDMemTable1);
end;

//value of unitimer1.interval is 5000;
procedure TMainForm.UniTimer1Timer(Sender: TObject);
begin
  self.UniButton1.Click;
end;

Board footer

Powered by FluxBB