# RO Server (Delphi) prevents program from exiting (hangs)

**URL:** https://talk.remobjects.com/t/ro-server-delphi-prevents-program-from-exiting-hangs/16878
**Category:** Remoting SDK
**Tags:** delphi
**Created:** [July 12, 2018, 5:13pm UTC](https://talk.remobjects.com/t/ro-server-delphi-prevents-program-from-exiting-hangs/16878 "2018-07-12T17:13:06Z")
**Posts on this page:** 19
**Page:** 1

<div class="post-metadata">

### Author: ![marcantheunis](https://talk.remobjects.com/letter_avatar_proxy/v4/letter/m/bcef8e/32.png) [@marcantheunis](https://talk.remobjects.com/u/marcantheunis)
#### Post date: [July 12, 2018, 5:13pm UTC](https://talk.remobjects.com/t/ro-server-delphi-prevents-program-from-exiting-hangs/16878/1 "2018-07-12T17:13:06Z")

</div>

It seems our RO server can hang indefinately sometimes upon application exit.  
From the call stack I am inclined to believe it is related to the RO (callback) events  
Could this be te case? Can this be avoided?  
RO version 9.4.107.1363

One thread is in the TROSCServerWorker.WaitForEventsAndMethods loop  
while the main thread is in the while loop in TROSynapseServerSocket.Destroy

TIA,  
Frederic

---

<div class="post-metadata">

### Author: ![DonaldShimoda](https://talk.remobjects.com/user_avatar/talk.remobjects.com/donaldshimoda/32/6_2.png) [@DonaldShimoda](https://talk.remobjects.com/u/DonaldShimoda)
#### Post date: [July 12, 2018, 11:31pm UTC](https://talk.remobjects.com/t/ro-server-delphi-prevents-program-from-exiting-hangs/16878/2 "2018-07-12T23:31:03Z")

</div>

Do you try unscribing to events before destroy app?

---

<div class="post-metadata">

### Author: ![marcantheunis](https://talk.remobjects.com/letter_avatar_proxy/v4/letter/m/bcef8e/32.png) [@marcantheunis](https://talk.remobjects.com/u/marcantheunis)
#### Post date: [July 13, 2018, 8:06am UTC](https://talk.remobjects.com/t/ro-server-delphi-prevents-program-from-exiting-hangs/16878/3 "2018-07-13T08:06:48Z")

</div>

Which un(sub?)scribe are you talking about.  
Of which class is this a member function?  
FYI: I am talking about the RO server application, the client is not closed, it keeps running.  
I do not call any subscribe or unsubscribe in that application

Events are handled by a decendent class of IROEventWriter which get generated by the RODL  
var  
RobotEvntswriter : IRobotEvents2\_Writer;  
…  
if supports (dmGlobal.InMemoryEventRepository, IRobotEvents2\_Writer,RobotEvntswriter) then  
RobotEvntswriter.OnSendMessage(EmptyGUID,Dialog.ID,response,True);

Note: I have a very high  
InMemorySessionManager.SessionDuration (several days)  
could that be related?

---

<div class="post-metadata">

### Author: ![EvgenyK](https://talk.remobjects.com/user_avatar/talk.remobjects.com/evgenyk/32/16_2.png) [@EvgenyK](https://talk.remobjects.com/u/EvgenyK)
#### Post date: [July 13, 2018, 8:12am UTC](https://talk.remobjects.com/t/ro-server-delphi-prevents-program-from-exiting-hangs/16878/4 "2018-07-13T08:12:22Z")

</div>

what event mode you are using ?  
legacy, when events are registered from client-side or .NET compatible, when events are registered on server-side?

---

<div class="post-metadata">

### Author: ![marcantheunis](https://talk.remobjects.com/letter_avatar_proxy/v4/letter/m/bcef8e/32.png) [@marcantheunis](https://talk.remobjects.com/u/marcantheunis)
#### Post date: [July 13, 2018, 8:24am UTC](https://talk.remobjects.com/t/ro-server-delphi-prevents-program-from-exiting-hangs/16878/5 "2018-07-13T08:24:38Z")

</div>

On the client side I have  
FEventReceiver.LegacyEvents:=False;  
It looks to me like events are registered on the client side (was that the question?)

Client code snippet 1:  
FEventReceiver:=TROEventReceiver.Create(Self);  
FEventReceiver.Channel:=ROSuperTCPChannel;  
FEventReceiver.Interval:=300;  
FEventReceiver.Message:=BinMessage\_ER; // FVC: Not sure if we need a separate BinMessage  
FEventReceiver.LegacyEvents:=False;  
FEventReceiver.ServiceName:=‘RobotService2’;  
FEventReceiver.OnPollException:=EventReceiverPollException;  
FEventReceiver.OnActivate:=EventReceiverActivate;  
FEventReceiver.OnDeactivate:=EventReceiverDeactivate;

Client code snippet 2:  
// Register the event handlers  
dmGlobalRobot.EventReceiver.RegisterEventHandlers(  
[EID\_RobotEvents2, EID\_RobotServerEvents2],  
[Self, Self]);  
// Starts polling  
dmGlobalRobot.EventReceiver.Active := TRUE;

---

<div class="post-metadata">

### Author: ![EvgenyK](https://talk.remobjects.com/user_avatar/talk.remobjects.com/evgenyk/32/16_2.png) [@EvgenyK](https://talk.remobjects.com/u/EvgenyK)
#### Post date: [July 13, 2018, 8:51am UTC](https://talk.remobjects.com/t/ro-server-delphi-prevents-program-from-exiting-hangs/16878/6 "2018-07-13T08:51:39Z")

</div>

```auto
FEventReceiver.LegacyEvents:=False;

```

it means that you are using .NET compatible events. as a result, these events should be registered on server-side, say in `login` method

---

<div class="post-metadata">

### Author: ![marcantheunis](https://talk.remobjects.com/letter_avatar_proxy/v4/letter/m/bcef8e/32.png) [@marcantheunis](https://talk.remobjects.com/u/marcantheunis)
#### Post date: [July 13, 2018, 9:44am UTC](https://talk.remobjects.com/t/ro-server-delphi-prevents-program-from-exiting-hangs/16878/7 "2018-07-13T09:44:25Z")

</div>

Can you tell me which class and which function?  
Looking for register on [docs.remotingsdk.com](http://docs.remotingsdk.com) does not give me any applicable information it seems  
Is there sample code?  
I don’t find register functions in RemObjects SDK for Delphi\SuperTCP Channel Chat

---

<div class="post-metadata">

### Author: ![EvgenyK](https://talk.remobjects.com/user_avatar/talk.remobjects.com/evgenyk/32/16_2.png) [@EvgenyK](https://talk.remobjects.com/u/EvgenyK)
#### Post date: [July 13, 2018, 9:47am UTC](https://talk.remobjects.com/t/ro-server-delphi-prevents-program-from-exiting-hangs/16878/8 "2018-07-13T09:47:20Z")

</div>

see `Login` method in the `SuperTCP Channel Chat` sample:

```auto
RegisterEventClient(GuidToString(Session.SessionID), EID_ChatEvents);

```

and in `Logout`:

```auto
UnregisterEventClient(GUIDToString(ClientID), EID_ChatEvents);

```

---

<div class="post-metadata">

### Author: ![marcantheunis](https://talk.remobjects.com/letter_avatar_proxy/v4/letter/m/bcef8e/32.png) [@marcantheunis](https://talk.remobjects.com/u/marcantheunis)
#### Post date: [July 13, 2018, 11:11am UTC](https://talk.remobjects.com/t/ro-server-delphi-prevents-program-from-exiting-hangs/16878/9 "2018-07-13T11:11:03Z")

</div>

hmm, for now this does not fix the issue.  
To be clear: My clients are still running so the logout is not called yet.  
Should it work then?

I will check if the Login gets called first and for all clients.  
However in my case after a server restart an existing client will not re-login but it will reconnect.  
I guess that will give me the same hang issue then.  
Is the InMemoryEventRepositoryAfterAddSession event not a better place to register?

FYI: Code below gets called before any other function (or event) on the server side:

function TRobotService2.Login(const aUserID: String): String;  
var  
newuser : TUserInfo;  
RobotEvntswriter : IRobotEvents2\_Writer;  
begin  
{ Checks if the user is already logged in }  
if (fUsers.Search(‘UserID’, aUserID) \<\> NIL) then  
raise Exception.CreateFmt(‘Client %s is already logged in’ +  
#13’Select an other ClientID’, [aUserID]);

{ Adds the user to the internal list of logged users }  
newuser := fUsers.Add;  
newuser.UserID := aUserID;  
newuser.SessionID := GUIDToString(Session.SessionID);

{ Stores the UserID of the user in the session.  
This will be used in the OnLogout and OnSendMessage methods }  
Session.Values[‘UserID’] := aUserID;  
result := newuser.SessionID;

RegisterEventClient(GuidToString(Session.SessionID), EID\_RobotServerEvents2);  
RegisterEventClient(GuidToString(Session.SessionID), EID\_RobotEvents2);

try  
if supports (EventRepository, IRobotEvents2\_Writer, RobotEvntswriter) then  
begin  
RobotEvntswriter.SessionList.CommaText := result;  
{ Only broadcasts to the session listed in SessionList }  
RobotEvntswriter.ExcludeSessionList := FALSE;  
{ Generates the OnLogin event }  
RobotEvntswriter.OnLogin(EmptyGUID, newuser);  
end;  
finally  
RobotEvntswriter := nil;  
end;

{ Instructs the framework not to destroy the object }  
RetainObject(newuser);  
end;

---

<div class="post-metadata">

### Author: ![EvgenyK](https://talk.remobjects.com/user_avatar/talk.remobjects.com/evgenyk/32/16_2.png) [@EvgenyK](https://talk.remobjects.com/u/EvgenyK)
#### Post date: [July 13, 2018, 11:15am UTC](https://talk.remobjects.com/t/ro-server-delphi-prevents-program-from-exiting-hangs/16878/10 "2018-07-13T11:15:26Z")

</div>

what SessionManager and EventRepository you are using? Olympia, InMemory, RODB or DADB ?

---

<div class="post-metadata">

### Author: ![marcantheunis](https://talk.remobjects.com/letter_avatar_proxy/v4/letter/m/bcef8e/32.png) [@marcantheunis](https://talk.remobjects.com/u/marcantheunis)
#### Post date: [July 13, 2018, 11:43am UTC](https://talk.remobjects.com/t/ro-server-delphi-prevents-program-from-exiting-hangs/16878/11 "2018-07-13T11:43:30Z")

</div>

```
InMemorySessionManager: TROInMemorySessionManager;
InMemoryEventRepository: TROInMemoryEventRepository;
```

---

<div class="post-metadata">

### Author: ![EvgenyK](https://talk.remobjects.com/user_avatar/talk.remobjects.com/evgenyk/32/16_2.png) [@EvgenyK](https://talk.remobjects.com/u/EvgenyK)
#### Post date: [July 13, 2018, 11:51am UTC](https://talk.remobjects.com/t/ro-server-delphi-prevents-program-from-exiting-hangs/16878/12 "2018-07-13T11:51:09Z")

</div>

> [@marcantheunis](#):
>
> To be clear: My clients are still running so the logout is not called yet.  
> Should it work then?

> [@marcantheunis](#):
>
> InMemory

something is wrong with your server then.  
can you check, that all your \_impl, except login one have `requireSession=True`?  
InMemory Session manager supposes that all data is stored in memory and after restarting server, all clients should re-login otherwise `SessionNotFound` exception should be raised at calling of any method of non-login service

---

<div class="post-metadata">

### Author: ![marcantheunis](https://talk.remobjects.com/letter_avatar_proxy/v4/letter/m/bcef8e/32.png) [@marcantheunis](https://talk.remobjects.com/u/marcantheunis)
#### Post date: [July 13, 2018, 12:08pm UTC](https://talk.remobjects.com/t/ro-server-delphi-prevents-program-from-exiting-hangs/16878/13 "2018-07-13T12:08:26Z")

</div>

Ach, I only have a single service, it is requiresSession=False  
So I need to put the login into a seperate RO service, correct?

---

<div class="post-metadata">

### Author: ![EvgenyK](https://talk.remobjects.com/user_avatar/talk.remobjects.com/evgenyk/32/16_2.png) [@EvgenyK](https://talk.remobjects.com/u/EvgenyK)
#### Post date: [July 13, 2018, 12:10pm UTC](https://talk.remobjects.com/t/ro-server-delphi-prevents-program-from-exiting-hangs/16878/14 "2018-07-13T12:10:10Z")

</div>

yep, only login service should have `requiresSession=False`.  
all others services should have `requiresSession=True`.

---

<div class="post-metadata">

### Author: ![DonaldShimoda](https://talk.remobjects.com/user_avatar/talk.remobjects.com/donaldshimoda/32/6_2.png) [@DonaldShimoda](https://talk.remobjects.com/u/DonaldShimoda)
#### Post date: [July 13, 2018, 12:50pm UTC](https://talk.remobjects.com/t/ro-server-delphi-prevents-program-from-exiting-hangs/16878/15 "2018-07-13T12:50:53Z")

</div>

> [@marcantheunis](#):
>
> Which un(sub?)scribe are you talking about.

Evgeny solve your doubts.

HTH.

---

<div class="post-metadata">

### Author: ![marcantheunis](https://talk.remobjects.com/letter_avatar_proxy/v4/letter/m/bcef8e/32.png) [@marcantheunis](https://talk.remobjects.com/u/marcantheunis)
#### Post date: [July 13, 2018, 1:15pm UTC](https://talk.remobjects.com/t/ro-server-delphi-prevents-program-from-exiting-hangs/16878/16 "2018-07-13T13:15:20Z")

</div>

FYI EvgenyK e.a.:  
My server was calling the RO interface from the application itself.  
These calls happened without a login.  
Is a login (registereventclient) also necessary for the server itself?

Question: What is the behaviour when a call is made without a session?  
It looks like the QueryInterface on the THYLocalService object returns nil, correct?  
supports (\_RobotService, IRobotService2, intf) =\> nil

---

<div class="post-metadata">

### Author: ![EvgenyK](https://talk.remobjects.com/user_avatar/talk.remobjects.com/evgenyk/32/16_2.png) [@EvgenyK](https://talk.remobjects.com/u/EvgenyK)
#### Post date: [July 16, 2018, 5:41am UTC](https://talk.remobjects.com/t/ro-server-delphi-prevents-program-from-exiting-hangs/16878/17 "2018-07-16T05:41:29Z")

</div>

> [@marcantheunis](#):
>
> My server was calling the RO interface from the application itself.

in some cases, it is enough to create service instance manually and later destroy it, like

```auto
  myservice := TNewService.Create(nil);
  try
    myservice.mymethod;
  finally
     myservice.Free;
  end;

```

---

<div class="post-metadata">

### Author: ![marcantheunis](https://talk.remobjects.com/letter_avatar_proxy/v4/letter/m/bcef8e/32.png) [@marcantheunis](https://talk.remobjects.com/u/marcantheunis)
#### Post date: [July 16, 2018, 9:20am UTC](https://talk.remobjects.com/t/ro-server-delphi-prevents-program-from-exiting-hangs/16878/18 "2018-07-16T09:20:41Z")

</div>

OK, thanks, for now I use THYLocalService and log in.

My problem is not resolved however.  
The RO server still hangs upon exit.  
FYI: the RO server is also a RO client and a Hydra plugin host, could you pinpoint the issue better if I send you callstacks?

Note: reconnecting a client after a RO server restart also does not work anymore now.  
I get the error below in my RO client (TUserInfo is a RODL class I use)  
Error reading parameter aUserInfo: Unexpected class found in stream; class “TUserInfo” does not descend from “TUserInfo”.

---

<div class="post-metadata">

### Author: ![EvgenyK](https://talk.remobjects.com/user_avatar/talk.remobjects.com/evgenyk/32/16_2.png) [@EvgenyK](https://talk.remobjects.com/u/EvgenyK)
#### Post date: [July 16, 2018, 10:04am UTC](https://talk.remobjects.com/t/ro-server-delphi-prevents-program-from-exiting-hangs/16878/19 "2018-07-16T10:04:38Z")

</div>

yes, you can send callstack.

> [@marcantheunis](#):
>
> Error reading parameter aUserInfo: Unexpected class found in stream; class “TUserInfo” does not descend from “TUserInfo”

this error means that you should put \_Intf where is `TUserInfo` declared into shared run-time package used by host and plugin
