Memory Leak with Olympia Server and EventSinks

Hello!,

This is an eternal issue that finally I decided to look deep into it and that was slowly killing our servers.

The problem happens while using the NON legacy event sink registration, in other words when calling the RegisterEventClient(GuidToAnsiString(ClientId),EID_XXXSink) from the server, usually during the login operations.

This ONLY happens if you use Olympia Server, InMemory Manager doesnt suffer this issue.

The case is reproducible with the HTTPChat sample that comes with the latest version of RO/DA for Delphi.

Simply enable to report memory leaks on shutdown on the HttpChatServer.pas file:

ReportMemoryLeaksOnShutdown:= DebugHook<>0;
Application.Initialize;
Application.Title := ‘HTTP Chat Server’;
Application.CreateForm(THTTPChatServerMainForm, HTTPChatServerMainForm);
Application.Run;

Set the build configuration to debug, rebuild the project and run it. Select Olympia Server.

Run one Chat client, login, logout. On the Chat Server close the application (click on the [x]) and see the memory report about the memory leaks.

It will not matter if you use Bin or JSON message, or if you stop the chat server. The memory leaks will show up.

Obviously this issue is HUGE, and after some hours it can swallow hundreds of megabytes until it eventually kills your services.

Thank you in advance for the assistance.

Thanks, logged as bugs://72614

Thank you for the report. We’ll start to investigate the issue ASAP

1 Like

bugs://72614 got closed with status fixed.

you can apply this patch:

e313e70485906dcb6150dbbd582c80951dcc42df
 RemObjects SDK for Delphi/Source/uROEventRepository.pas       |  9 ++++++++-
 .../Source/uROOlympiaEventRepository.pas                      |  7 +++++++
 RemObjects SDK for Delphi/Source/uROOlympiaSessionManager.pas | 11 +++++++++++
 3 files changed, 26 insertions(+), 1 deletions(-)

diff --git a/RemObjects SDK for Delphi/Source/uROEventRepository.pas b/RemObjects SDK for Delphi/Source/uROEventRepository.pas
index 9bf471d..db6fab7 100644
--- a/RemObjects SDK for Delphi/Source/uROEventRepository.pas    
+++ b/RemObjects SDK for Delphi/Source/uROEventRepository.pas    
@@ -246,0 +247 @@ type
+    function IsSessionPresentinSessionManager(const aSessionID : TGUID):Boolean; virtual;
@@ -862,0 +864,6 @@ end;
+function TROInMemoryEventRepository.IsSessionPresentinSessionManager(
+  const aSessionID: TGUID): Boolean;
+begin
+  Result := (SessionManager.FindSession(aSessionID,False) <> nil);
+end;
+
@@ -932 +939 @@ begin
-      if (fSessionIDs.IndexOf(s) <> -1) and (SessionManager.FindSession(aSessionID,False) <> nil) then fSessionIDs1.Add(s);
+      if (fSessionIDs.IndexOf(s) <> -1) and IsSessionPresentinSessionManager(aSessionID) then fSessionIDs1.Add(s);
diff --git a/RemObjects SDK for Delphi/Source/uROOlympiaEventRepository.pas b/RemObjects SDK for Delphi/Source/uROOlympiaEventRepository.pas
index 7d6650f..f7e3010 100644
--- a/RemObjects SDK for Delphi/Source/uROOlympiaEventRepository.pas    
+++ b/RemObjects SDK for Delphi/Source/uROOlympiaEventRepository.pas    
@@ -53,0 +54 @@ type
+    function IsSessionPresentinSessionManager(const aSessionID : TGUID):Boolean; override;
@@ -262,0 +264,6 @@ end;
+function TROOlympiaEventRepository.IsSessionPresentinSessionManager(
+  const aSessionID: TGUID): Boolean;
+begin
+  Result := SessionManager.IsSessionPresent(aSessionID);
+end;
+
diff --git a/RemObjects SDK for Delphi/Source/uROOlympiaSessionManager.pas b/RemObjects SDK for Delphi/Source/uROOlympiaSessionManager.pas
index 6f30df0..6a8b2f5 100644
--- a/RemObjects SDK for Delphi/Source/uROOlympiaSessionManager.pas    
+++ b/RemObjects SDK for Delphi/Source/uROOlympiaSessionManager.pas    
@@ -69,0 +70 @@ type
+    function IsSessionPresent(const aSessionID : TGUID):Boolean;
@@ -215,0 +217,10 @@ end;
+function TROOlympiaSessionManager.IsSessionPresent(
+  const aSessionID: TGUID): Boolean;
+var
+  l_UserSession : OlympiaUserSession;
+begin
+  l_UserSession := SessionManager.ReadSession(GUIDToAnsiString(aSessionID));
+  Result := l_UserSession <> NIL;
+  FreeAndNil(l_UserSession);
+end;