вівторок, 18 лютого 2020 р.

Delphi - Close inactive sessions in DataSnap

There is something wrong with DataSnap at least in Delphi 10 or I did something wrong. Anyway, when client application becomes to be frozen (f.e. long time running SQL query or becomes to be frozen somehow in another way or client application did not ask anything from the DataSnap for awhile), DatSnap stopped to create new instance for other client, after DataSnap ran TDSSessionManager.Instance.CloseSession(ASession.SessionName);.

Controls used in DataSnap server side application: DSServer and DSHTTPService. Client application communicates via http(s).

In Server side DataModuleCreate set how long session will live in an inactive state:

  TDSSessionManager.Instance.AddSessionEvent(
    procedure(Sender: TObject;
              const EventType: TDSSessionEventType;
              const Session: TDSSession)
    begin
      case EventType of
        {The provided Session was just created.}
        SessionCreate: Session.LifeDuration := 10000000; // less than 3 hours
        {The provided Session has just been closed, either intentionally or it has expired.}
        SessionClose: ;
      end;
    end);

Define how to mark that session is active:
function <>.DSServerTrace(TraceInfo: TDBXTraceInfo): CBRType;
begin
  if TraceInfo.TraceFlag in [TDBXTraceFlags.Execute, TDBXTraceFlags.Command, TDBXTraceFlags.Transact, TDBXTraceFlags.Reader, TDBXTraceFlags.Driver, TDBXTraceFlags.Custom] then // mark session as an active
    TDSSessionManager.Instance.GetThreadSession.MarkActivity;

  Result := cbrUSEDEF;
end;

In DSServerConnect(DSConnectEventObject: TDSConnectEventObject); run procedure below:
procedure clearInactiveSessions();
  var
    sl: TStringList;
    _Session: TDSSession;
    i: Integer;
  begin
    sl := TStringList.Create;
    try
      TDSSessionManager.Instance.ForEachSession(
        procedure(const ASession: TDSSession)
        begin
            // different session
            if (ASession.SessionName <> TDSSessionManager.Instance.GetThreadSession.SessionName)
              and(
                (not ASession.IsValid)
                or
                (ASession.ElapsedSinceLastActvity > UINT(ASession.LifeDuration))
              )
            then
            begin
              //TDSSessionManager.Instance.CloseSession(ASession.SessionName); // ATTENTION: Causes a freezing of application
              TDBXScheduler.Instance.CancelEvent(ASession.Id);
              // add removed session from the SessionManager to the list
              sl.AddObject(ASession.SessionName, TDSSessionManager.Instance.RemoveSession(ASession.SessionName));
            end;
        end
        );

        for i := 0 to sl.Count - 1 do
        begin
          _Session := TDSSession(sl.Objects[i]);
          if Assigned(_Session) then
            FreeAndNil(_Session);
        end;
    finally
      FreeAndNil(sl);
    end;
  end;

So above procedure shall be ran, when new client trying to connect to the DataSnap.

Normally, TDSSessionManager.Instance.CloseSession(ASession.SessionName); should work fine, but for some reason did not.

As result, frozen or inactive client application did not get any respond that its connection was closed, but session becomes properly closed. Client can kill its process and DataSnap still continue working.

Probably in Delphi 10.3.x it is fixed, will check somewhen.

середа, 12 лютого 2020 р.

Docker

1. Show docker settings.

docker info

- Play with Dicker

1. Put "C:\ProgramData\Docker" on a different drive.

To save free space on your system hard drive, just create/modify the C:\ProgramData\Docker\config\daemon.json file as referenced in the getting started guide here.

{
"graph": "F:\\ProgramData\\Docker"
}

This will put all your images, layers and containers in a different location but leave the config in its original location.
Source

2. Install Microsoft SQL Server.

3. Run SQL Server.

docker run -d -p <HostEnvironmentIP>:<InContainerIP> -e "ACCEPT_EULA=Y" -e "SA_PASSWORD=<YourPassword>" --name sql1 microsoft/mssql-server-windows-express