Application restarts, connected clients use "old server"

rejwan
edited May 2011 in Photon Server
Hey,
Noticed a weird bug - When we update our server code, Photon successfully detects that the code has changed and restarts the application.
However, if any clients are connected - they will remain connected as if nothing had happened, and when they send out commands, they will be called using the "old server code".

This is obviously not an acceptable situation, as we'd like our users to automatically start using the new code, or at the very least get booted out when an application is restarted.

Comments

  • That behavior is expected. On a live server, this should give a soft(er) transition to a new server version.
    In any case, you can configure it:

    In the PhotonServer.config, find the Application nodes. Per app you can replace the EnableAutoRestart attribute with ForceAutoRestart and the "old" connections will be cut off.
    It's a bit hidden, but described in the doc/photon-configuration.pdf:
    "ForceAutoRestart, if set to "true", implies "EnableAutoRestart" but aborts all existing connections rather than waiting for them to disconnect."
  • I have no problem for connections to the "old" server to smoothly transition into the "new" server, but it appears that the "old" ones keep running on that code and don't switch to the new code.
  • Is it possible for users to continue playing without visible disconnection after the code is upgraded?
    If yes, then what's the best way to do it?

    thanks,
    Slav
  • Boris
    Boris ✭✭
    When this happens the application gets a notification: PhotonHostRuntimeInterfaces.IPhotonApplicationControl.OnStopRequested().
    You can send a notification (event) to your clients to reconnect; the client then has to disconnect and connect again.
    public class LiteApplication : Application, IPhotonApplicationControl
    {
            void IPhotonApplicationControl.OnStopRequested()
            {
                  // inform clients here
            }
    
  • Making them re-connect is only a part of the transition: If you have rooms with properties, they won't be transferred automatically. If you use ForceAutoRestart, they would be cut off and the event will only tell clients to reconnect.
    Thats why we use EnableAutoRestart by default: the games stay intact and can be finished. However, the old version never gets a OnStopRequested call and you would need to detect that the version is outdated somehow. Maybe a version entry in a db, which is increased by each start of your app could help detect if a version is outdated.
  • OK so I've changed the application configuration from
    <Application
    ...
    EnableAutoRestart="true"
    >
    </Application>

    To
    <Application
    ...
    ForceAutoRestart="true"
    >
    </Application>

    However, this does nothing for my clients they remain connected.

    In the Application I'm unsure how to access any connected peers since they are connected to a room.
  • I just tried this with Lite. Config:
    <Application
    Name="Lite"
    BaseDirectory="Lite\Lite"
    Assembly="Lite"
    Type="Lite.LiteApplication"
    ForceAutoRestart="true"
    WatchFiles="dll;config"
    ExcludeFiles="log4net.config">
    </Application>

    Of course, Photon has to be started after PhotonServer.config was saved. Then, I changed: sdk\deploy\Lite\Lite\bin\Lite.dll.config and saved it. 10 seconds later I get this log entry in Photon-Instance1-<date>.log:
    ...
    5116: 10:41:16.140 - Restarting application: "Lite" due to file changes
    5116: 10:41:16.140 - Application: "Lite" restart request (abort existing connections)
    ...

    The client were no longer connected after this.
    Maybe you forgot the Photon restart after changing the config?
  • Works like a charm now, thanks :)

    However, how can I access my peer list from IPhotonApplicationControl.OnStopRequested()?
    Since it's in the Application I can't find the instance of my rooms.
  • There is currently no way to get a list of the connected peers.
    But you can extend the Lite.Caching.RoomCacheBase class to inform all existing rooms about the stop request.
    public abstract class RoomCacheBase
    {
    	...
    	
    	public void OnStopRequested()
    	{
    		lock (this.syncRoot)
    		{
    			foreach (var roomInstance in this.roomInstances.Values)
    			{
    				var msg = new RoomMessage(100);
    				roomInstance.Room.EnqueueMessage(msg);
    			}
    		}
    	}
    	
    	...
    }
    

    public class LiteApplication : Application, IPhotonApplicationControl
    {
    	...
    	
    	void IPhotonApplicationControl.OnStopRequested()
    	{
    		LiteGameCache.Instance.OnStopRequested();
    	}
    	
    	...
    }