From 3418ba156e96d71eb80ddefa2e37e7bc7486219c Mon Sep 17 00:00:00 2001 From: michael Date: Mon, 13 Aug 2012 11:43:16 +0000 Subject: [PATCH] * Retry opening session file on error (max 5 times) git-svn-id: trunk@22070 - --- packages/fcl-web/src/base/iniwebsession.pp | 91 +++++++++++++++++++--- 1 file changed, 81 insertions(+), 10 deletions(-) diff --git a/packages/fcl-web/src/base/iniwebsession.pp b/packages/fcl-web/src/base/iniwebsession.pp index 7c31d46072..7b8b67d620 100644 --- a/packages/fcl-web/src/base/iniwebsession.pp +++ b/packages/fcl-web/src/base/iniwebsession.pp @@ -32,15 +32,17 @@ Type FSessionDir: String; FTerminated :Boolean; SID : String; - private - procedure FreeIniFile; + procedure UpdateIniFile; Protected + Function CreateIniFile(Const AFN : String) : TMemIniFile; virtual; + Procedure FreeIniFile; Procedure CheckSession; Function GetSessionID : String; override; Function GetSessionVariable(VarName : String) : String; override; procedure SetSessionVariable(VarName : String; const AValue: String); override; Property Cached : Boolean Read FCached Write FCached; Property SessionDir : String Read FSessionDir Write FSessionDir; + Property IniFile : TMemIniFile Read FIniFile Write FIniFile; Public Destructor Destroy; override; Procedure Terminate; override; @@ -82,6 +84,9 @@ Type Var IniWebSessionClass : TIniWebSessionClass = Nil; +Const + MaxIniCreate = 5; + implementation {$ifdef cgidebug} @@ -235,10 +240,75 @@ begin Result:=SID; end; +Procedure TIniWebSession.UpdateIniFile; + + +Var + ACount : Integer; + OK : Boolean; + +begin + ACount:=0; + OK:=False; + repeat + Inc(ACount); + try + TMemIniFile(FIniFile).UpdateFile; + OK:=True; + except + On E : EFCreateError do + begin + If ACount>MaxIniCreate then + Raise; + Sleep(20); + end; + On E : EFOpenError do + begin + If ACount>MaxIniCreate then + Raise; + Sleep(20); + end; + On E : Exception do + Raise; + end; + Until OK; +end; + +function TIniWebSession.CreateIniFile(Const AFN: String): TMemIniFile; + +Var + ACount : Integer; + +begin + ACount:=0; + Result:=Nil; + repeat + Inc(ACount); + try + Result:=TMemIniFile.Create(AFN,False); + except + On E : EFCreateError do + begin + If ACount>MaxIniCreate then + Raise; + Sleep(20); + end; + On E : EFOpenError do + begin + If ACount>MaxIniCreate then + Raise; + Sleep(20); + end; + On E : Exception do + Raise; + end; + until (Result<>Nil); +end; + procedure TIniWebSession.FreeIniFile; begin If Cached and Assigned(FIniFile) then - TMemIniFile(FIniFile).UpdateFile; + UpdateIniFile; FreeAndNil(FIniFile); end; @@ -265,7 +335,7 @@ begin CheckSession; FIniFile.WriteString(SData,VarName,AValue); If Not Cached then - TMemIniFile(FIniFile).UpdateFile; + UpdateIniFile; end; destructor TIniWebSession.Destroy; @@ -295,7 +365,7 @@ end; procedure TIniWebSession.InitSession(ARequest: TRequest; OnNewSession,OnExpired: TNotifyEvent); Var - S : String; + S,FN : String; SF : TIniSessionFactory; begin @@ -314,8 +384,9 @@ begin // have session cookie ? If (S<>'') then begin -{$ifdef cgidebug}SendDebug('Reading ini file:'+S);{$endif} - FIniFile:=TMemIniFile.Create(IncludeTrailingPathDelimiter(SessionDir)+SF.SessionFilePrefix+S); + FN:=IncludeTrailingPathDelimiter(SessionDir)+SF.SessionFilePrefix+S; +{$ifdef cgidebug}SendDebug('Reading ini file:'+FN);{$endif} + FIniFile:=CreateIniFile(FN); if SF.SessionExpired(FIniFile) then begin // Expire session. @@ -335,14 +406,14 @@ begin GetSessionID; S:=IncludeTrailingPathDelimiter(SessionDir)+SF.SessionFilePrefix+SessionID; {$ifdef cgidebug}SendDebug('Creating new Ini file : '+S);{$endif} - FIniFile:=TMemIniFile.Create(S); + FIniFile:=CreateIniFile(S); FIniFile.WriteDateTime(SSession,KeyStart,Now); FIniFile.WriteInteger(SSession,KeyTimeOut,Self.TimeOutMinutes); FSessionStarted:=True; end; FIniFile.WriteDateTime(SSession,KeyLast,Now); If not FCached then - FIniFile.UpdateFile; + UpdateIniFile; {$ifdef cgidebug}SendMethodExit('TIniWebSession.InitSession');{$endif} end; @@ -381,7 +452,7 @@ begin CheckSession; FIniFile.DeleteKey(SData,VariableName); If Not Cached then - TMemIniFile(FIniFile).UpdateFile; + UpdateIniFile; {$ifdef cgidebug}SendMethodExit('TIniWebSession.RemoveVariable');{$endif} end;