Page 1 of 1

Hot redeploy extensions, Not working :(

Posted: 19 Jul 2013, 20:15
by Sparticus
I read from the docs I can hot redeploy extensions.
SmartFoxServer 2X provides Extensions hot-redeploy which can be very useful during the development phases. When this feature is turned on (see the Custom configuration paragraph above), the server will monitor your Extension folders and reload your code when a jar file is modified.
All you need to do is configure your Java IDE to build or copy the jar file directly under the Extension folder in your SmartFoxServer path, and you will have a one-click deploy system.
Whenever I copy a new version of the extension over the old one I can see that the new extension gets loaded... however, I immediately start seeing errors in the logs.

After investigation, it appears an object of mine that held a value before now is null.

In my main extension I have this :

Code: Select all

private ConcurrentHashMap<Integer,GameRoom> gameRooms = new ConcurrentHashMap<Integer,GameRoom>();
And each client sends a message to the server once a second they they read values from that GameRoom object.

While debugging, I trace out this each request :

Code: Select all

System.out.println("GameRooms : "+this.gameRooms);
Normally I see this :

Code: Select all

GameRooms :{2=GameRoom@62073b74}
Which means my hash map knows about my game room.... however, immediately after I hot re-deploy the extension it traces out :

Code: Select all

12:39:33,060 INFO  [Thread-4] managers.SFSExtensionManager     - Reloading extension: { Ext: MPBTGTD, Type: JAVA, Lev: ZONE, { Zone: MPBTGTD }, {} }
GameRooms :{}
The only way in my code to actually remove anything from the hash map is from a "removeGameRoom" method but I have traces in there any that method definitely doesn't get called.

Am I missing something? Maybe I assumed players could keep playing their games while I hot deployed the extension.... and maybe you can't.

Any help would be greatly appreciated! :)

Re: Hot redeploy extensions, Not working :(

Posted: 20 Jul 2013, 01:44
by rjgtav
Hi,

When an extension is reloaded the previous instance of it is destroyed, actually before the new one gets loaded.
As a result, all the variables and values that it was holding are released, and the info is lost.

In order to solve that issue, when the extension is getting destroyed, you have to store the current information, so that it is then loaded again when the new instance is initialized.
For this, you have various ways. You could use a database and/or a file-based storage system, but as we're talking about extension reloading which needs to be fast and not much CPU intensive, this method is not recommended.

You can also store the data directly at the SFSZone object or, for example, store each GameRoom object at the SFSRoom object. Both SFSZone and SSRoom have a getProperty() and setProperty() methods, which are used to store and retrieve custom objects. These objects are only at the server-side and are never transmitted to any client, which makes this a really great solution for you.

What do you think?
You can find more information at the Java Server-side API:
http://docs2x.smartfoxserver.com/api-do ... /Zone.html
http://docs2x.smartfoxserver.com/api-do ... oc/server/

Cheers

Re: Hot redeploy extensions, Not working :(

Posted: 20 Jul 2013, 11:31
by Lapo
There are also more sophisticated ways to reload the actual extension code while keeping the game data intact.
This however requires solid knowledge of Java and its mechanism of Class Loading. We explain this subject in a specific article here:
http://docs2x.smartfoxserver.com/Advanc ... assLoading

In order to keep a "Data Store" intact in memory you will need to deploy the model in "__lib__" folder inside the extension directory, while the rest of your code goes under the normal extension directory. Anything deployed under __lib__ will be loaded by the top class loader and won't be lost between multiple extension reloads.

Re: Hot redeploy extensions, Not working :(

Posted: 21 Jul 2013, 16:05
by Sparticus
Thanks for the replies.

I might give the saving to the SFSRoom Object a try. Kinda freaks me out of what other info i might be losing when i reload an extension.

Just curious... what do all the really big companies do when they want to deploy an updated extension? For example, when Club Penguin (which I believe uses SFS) wants to deploy a new extension, do they just hot deploy it? Or would they instead tell their users there will be an update at some time and restart SFS fresh with the new extension?

Thanks

Re: Hot redeploy extensions, Not working :(

Posted: 22 Jul 2013, 07:04
by Lapo
We have no idea, they don't tell us their "secrets" :)

Re: Hot redeploy extensions, Not working :(

Posted: 13 Aug 2013, 11:53
by scream
So, If I want to prevent data loss while extension reloading, I should use destroy method in my base SFSExtension class and save some information before destroy operation complete.

After that how I'm going to load the saved data into proper locations? As I see, there is no event triggered after extension reloading.

Re: Hot redeploy extensions, Not working :(

Posted: 13 Aug 2013, 13:01
by Lapo
Yes, there is. It is the init() method.

Re: Hot redeploy extensions, Not working :(

Posted: 13 Aug 2013, 15:20
by scream
Yes, there is. It is the init() method.
Aha yes, I just recognised. We can use init method.
When I start extension first time, inside init() method, ServerReady event is triggered as usual, but after reloading operation init method is called but ServerReady event is not triggered. What is the reason ? To be able to load my lost data (like static fields) back, I should trigger RServerReady event simply.

Re: Hot redeploy extensions, Not working :(

Posted: 13 Aug 2013, 16:32
by Lapo
SERVER_READY fires only when the server starts up because Extensions are create before the server engine is fully ready to communicate.
If you attempt to send any data to clients when the server is booting up it will result in an error, which can be avoided by listening to that event.

When the server is up and running there's no need for such event to be fired again.
In any case you can always test the SmartFoxServer instance to see if it is started:

Code: Select all

SmartFoxServer.getInstance().isStarted()

Re: Hot redeploy extensions, Not working :(

Posted: 23 Jul 2014, 11:32
by chiron
Lapo wrote:Yes, there is. It is the init() method.
But in my test destroy() method of old extension run after init() method of new extension.