Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
Problem with getting session list
#1
Hi!
In order to let some forms be terminated I get the session list with; gSessions.GetList(alst); as one of the last things in  the event IWServerControllerBaseNewSession() in the server control unit
But it will almost always not work the second time around, the first time is OK.
I've tried to push it to a later time, when the form is up and running (with a timer 5000), but it is the same behaviour.
Thx Martin
Code:
procedure TIWServerController.CleanUpForms(ASession: TIWApplication);
var
  alst:     TStringList;
  aid:      string;
  app:      TIWApplication;
  exp, al:  boolean;
  ok:       boolean;
  cnt:      integer;
begin

  if _LogEnabled then
    _Log('Trying to clean-up session list');

  try
    ok:=false;
    cnt:=0;
    repeat
      alst:=TStringList.Create;
      try
        gSessions.GetList(alst);
        ok:=true;
      except
        Inc(cnt);
        if cnt = 100 then begin
          if _LogEnabled then
            _Log('**Warning: Could not retrieve session list from IntraWeb platform');
          Exit;
        end;
        Sleep(50);
      end;
    until ok;

    if _LogEnabled then begin
      if cnt > 0 then
        _Log('Retry count is: ' + IntToStr(cnt));
      _Log('Number of sessions currently in the list: ' + IntToStr(alst.Count));
    end;

    for aid in alst do begin
      if aid <> ASession.AppID then begin
        app:=gSessions.LookupAndLock(aid, exp, al);
        if Assigned(app) and not exp then begin
          if app.Name = ASession.Name then begin
            if _LogEnabled then
              _Log('Session "' + app.AppID + '" will be terminated');
            app.Unlock;
            app.Terminate;
            app.Free;
          end else begin
            app.Unlock;
          end;
        end;
      end;
    end;

  finally

    alst.Free;

  end;

  if _LogEnabled then
    _Log('Number of sessions (from gSessions): ' + IntToStr(gSessions.Count));

end;
Reply
#2
Hi, see this demo, maybe help you:
https://github.com/Atozed/IntraWeb/tree/...essionList
Reply
#3
I don't understand what you are trying to accomplish exactly... You said that you are trying to terminate some forms but you are actually terminating some sessions, correct?

How's this method called/triggered? From an user event?

You are terminating one specific session from another session (i.e. from Session A you terminate Session B)?

If so, the code looks good to me, most of it. But the problem relies on the terminate itself. *Don't free the session yourself*.

Code:
    if aid <> ASession.AppID then begin
      app:= gSessions.LookupAndLock(aid, exp, al);
      if Assigned(app) and not exp then begin
        if app.Name = ASession.Name then begin
          if _LogEnabled then
            _Log('Session "' + app.AppID + '" will be terminated');
          app.Terminate;  // terminate first
        end;
        app.Unlock;      // then unlock it. Don't free it!
      end;
    end;

After being terminated, session will be collected by the clean up thread which runs in the background, and freed. If you free it yourself, the clean up thread won't be able to do the proper clean up.
Reply
#4
Hi Alexandre!
Yes, it is sessions I want to terminate, and yes, terminate session b from session a.
I'll try without the free.
Thx Martin

Hi again,
Yes, that worked, I no longer get errors when reading the list.
But the list just keeps growing, the sessions are never freed as far as I can tell.
I saw from the examples that you can set a parameter on terminate and that is the new HTML it shows. 
Is that a way to go when wanting the forms in a session to be released, I have some forms with big amount of data on them and those dataset are never freed when the form is not freed.
What can I do?
Thx Martin


Edit: I have put a SessionTimeout := 1; and that triggers the release of my forms after a minute at least. Is there a cleaner way?

Code:
    for aid in alst do begin
      if aid <> ASession.AppID then begin
        app:=gSessions.LookupAndLock(aid, exp, al);
        if Assigned(app) and not exp then begin
          if app.Name = ASession.Name then begin
            if _LogEnabled then
              _Log('Session "' + app.AppID + '" will be terminated');
            //app.ReleaseForm(app.Forms[0]);
            app.SessionTimeOut:=1;
            app.Terminate;
          end;
          app.Unlock;
        end;
      end;
    end;
Reply
#5
You shouldn't rely on sessions being destroyed to release forms and/or datasets. If you free a form, regardless of the session state, it will be released. The same for datamodules and any other control. Are you leaving the session with active forms?

I'll test this scenario you mentioned and let you know. I'll keep you posted.
Reply
#6
Thank you for looking into it.
Yes, the user just leaves the form, and it is actually replaced by another form usually in an iframe (by replacing the url), so I need to have the session and of cause forms to be release in an automated way.
I run with the above technique (timeout=1) now and it works very well, what I could which was that there was a way to just terminate the session and automatically free any forms and resources immediately. I have my data set with Owner = the form, so when the form frees the data is freed also. 

See the attachment, the IFrame normally points to a ISAPI IntraWeb form with .../$/start/...?companyId=<some id> and the url is just replaced by a new url with a different company id, and therefore the sessions needs to be able to search and terminate the session that was replaced.

Thx Martin


Attached Files
.html   CRM_Simulator.html (Size: 1.71 KB / Downloads: 14)
Reply
#7
We have a fix in place and a new update should be release soon, which will resolve this problem
Reply
#8
Nice, thank you! Will it be a new terminate and free session immediately function?
Martin
Reply
#9
Please update to IW 15.2.18.

Answering your question: Yes and no. Terminate() never frees the session immediately. It puts it in the list to be collected by the background thread and it will be freed in 60 seconds or less.
Reply


Forum Jump:


Users browsing this thread: 1 Guest(s)