Handling concurrency on SFS Pro

Need help with SmartFoxServer? You didn't find an answer in our documentation? Please, post your questions here!

Moderators: Lapo, Bax

User avatar
mistermind
Posts: 131
Joined: 15 Sep 2007, 01:33
Contact:

Handling concurrency on SFS Pro

Postby mistermind » 22 Feb 2008, 16:40

Hello there my fellow SFS companions.
This isn't a bug, so no need to pull your guns out :)
My question is more of a "how should I code":
Here is the deal: I'm always trying to make very friendly lobbies interfaces, and my attempts haven't been very successful using the old SFS Basic, and now I finally had the guts to order SFS Pro, and as far as I can tell, it works amazing, even with the old config.xml from SFS Basic.

Now, with this new "client approach", I'm trying something new: Instead of having the all known and simple "create room" and "join room" scenarios that are basically "less buggy" and more reliable due to concurrency issues, I'm working on a new "random match" system, that will basically handle the client questions of "should I create a room or should I join an opponent's?".
Basically the system will search for about 5 seconds for open rooms matching that player's level with other players around, and if it can't find it, he will then create a room and wait until someone join his game. As great as it sounds in theory, I'm running into a known problem with client requests: Too many players clicking on the "random match", two clients finding an available game room at the same time. Both will try to join and, o well, one of them will be kicked out of the game.

Now I realize that the all mighty SFS Pro can handle server events and, with extensions, multiple requests much better client requests.
My question is: How? I've read a lot on the docs, and tried a lot of the examples, but due to my client engine code that handles everything with SFS Basic public methods, I can't figure out how to migrate, at least the essential concurrency methods, to SFS Pro's extensions.
In other words, how can I convert a simple

Code: Select all

// This code has been reduced to a better understanding :)
var gameRoomExist:Room = smartfox.getRoom(mylevel);
if (!gameRoomExist.getId()){
   var room:Object = new Object;
   room.name = mylevel;
   room.isGame = true;
   room.exitCurrentRoom = false;
   room.maxUsers = 2;
   smartfox.createRoom(room);
}else{
   smartfox.joinRoom(gameRoomExist.getId(),"",false,true);
}

To a more stable server side "random match" with no concurrency problems?



// Daniel L.
// www.ederon.com - Online Trading Card Game.
User avatar
mistermind
Posts: 131
Joined: 15 Sep 2007, 01:33
Contact:

Postby mistermind » 23 Feb 2008, 17:40

any ideas?
User avatar
Lapo
Site Admin
Posts: 23008
Joined: 21 Mar 2005, 09:50
Location: Italy

Postby Lapo » 26 Feb 2008, 15:26

There are two concurrency problems one is "logic" and the other is programmatic.

Logic:
Three players (A,B,C) hit the join button on the same room at the "same time". What happens next is that their requests travel through the network up to SmartFoxServer and depending on their connection speed they will get in the server in a certain order. Let's say it is C,A,B

SFS will then process the three requests in that order resulting in the user C to join the room and the other two receiving a join-error-message (let's pretend there was just 1 seat left in that room)

About the programmatic concurrency there's no problem here because that is handled internally by the server.

Programmatic:
Shared data and multiple threads.
The server uses multiple threads that work on the incoming requests, outgoing data, server events etc...
So, for example, when you handle a user request you're running in a different thread then when you handle a server event.

This means that if both processes attempt to work on the same shared resource (variable, list, map) you may incur in concurrency problems and break some important data.

Unfortunately server side actionscript does not have control over the synchronization of threads so it is very important to use collections that are thread safe when working with shared data.

The good news is data both scripting languages (Actionscript and Python) can access and use any class from the Java framework so you could use ConcurrentHashMap, BlockingQueue, CopyOnWriteArray and similar classes to hold your data in a thread-safe fashion.

This topic is massive and it would very difficult to discuss all the details here. The important thing is to understand the basics of the problem: multiple processes working on the same data at the same time can result in broken/incorrect data.

If your application has to deal with this scenario and you're not using Java you can still make use of the thread-safe collections from the Java libraries (java.util.concurrent)

BTW: We are going to publish an in-depth article about the threading model and thread-safety in SmartFoxServer soon.

Have a look at this article -> http://www.ibm.com/developerworks/java/ ... 07233.html
Lapo
--
gotoAndPlay()
...addicted to flash games
User avatar
mistermind
Posts: 131
Joined: 15 Sep 2007, 01:33
Contact:

Postby mistermind » 26 Feb 2008, 16:45

Wow this is bigger then I thought. I could probably try to deal with these issues with Java framework and if my ideas are right here they are probably the key to solve room variables concurrency. I'll read these article and will be in the look out for the SFS article. Thanks a lot all mighty Lapo :)
User avatar
tobypb
Posts: 48
Joined: 15 Jun 2007, 20:50

Postby tobypb » 13 Mar 2008, 15:22

Is each request on to an extension likely to be on a different thread then? Does this mean that any classes I should use should therefore be thread safe on the server side? I'm writing my extension in java and concurrency problems would certainly cause it problems if they were possible..

Are the built in smartfoxserver classes threadsafe? Such as room variables and so on?

Should I start adding "synchronised" to all the methods that can be accessed simultaneously and changing my container classes to concurrency proof ones?
User avatar
Lapo
Site Admin
Posts: 23008
Joined: 21 Mar 2005, 09:50
Location: Italy

Postby Lapo » 13 Mar 2008, 17:15

I'll give you a better idea:

By default in your extension the handleRequest method is invoked by a thread which is different from the thread that calls handleInternalEvent

Additional concurrency can be also introduced by spawning new threads ( starting one of more setIntervals, using the Scheduler etc... )

If your configuration uses multiple threads for the extension handler( using <ExtHandlerThreads> ) then your handleRequest method will be called by one of the threads in the thread-pool. By default 1 thread is used.

Synchronization could be necessary if both your request handler and event handler work on shared data at the same time.
This should be evaluated by checking the specific code and defining the sections that need to be thread safe.

Are the built in smartfoxserver classes threadsafe? Such as room variables and so on?

Yes, they are unless the docs indicates something else.

Should I start adding "synchronised" to all the methods that can be accessed simultaneously and changing my container classes to concurrency proof ones?

Of course no! :shock:
Use synchronized only when needed and try to avoid synch-ing the whole method (which will lock the whole object) as this could break the server performance.

hope it helps
Lapo

--

gotoAndPlay()

...addicted to flash games
User avatar
tobypb
Posts: 48
Joined: 15 Jun 2007, 20:50

Postby tobypb » 13 Mar 2008, 17:37

thanks Lapo - that helps a great deal..

Looks like I will have a few threads running then. One for the for the HandleRequest, one for the handleInternalEvent and one for the Scheduler. From what I read about the Scheduler am I correct in assuming it only uses one thread no matter how many tasks are running and therefore executes them serially. If this is the case my extension has three threads running within it.

Therefore some of my code will have to be synchronised.. I see what you mean about locking problems. Although all the methods I would lock are pretty fast some of them involve database accesses via hibernate which could slow them down I guess. I also don't want the locked objects to be locked from the schedulers point of view as my slowing the scheduler down would not be a good idea as my extension relies heavily on it. Would you therefore recommend synchronizing code in the manner shown below, which I guess should also mean problems such as deadlocking are avoided:

Code: Select all

public class SomeClass {
    private Object lock1 = new Object();

    public void method() {
        synchronized(lock1) {
            // synchronized code
            // only this block is synchronized not
            // the whole object by using a sync object

        }
    }
}


Use synchronized only when needed and try to avoid synch-ing the whole method (which will lock the whole object) as this could break the server performance.

By breaking server performance do you mean simply slowing the server performance down or is the way the server is built mean certain threading operations should be avoided?
User avatar
Lapo
Site Admin
Posts: 23008
Joined: 21 Mar 2005, 09:50
Location: Italy

Postby Lapo » 14 Mar 2008, 07:31

Would you therefore recommend synchronizing code in the manner shown below, which I guess should also mean problems such as deadlocking are avoided:

I don't know... it really depends on what should be synchronized :)
Honestly, since Java 1.5 and its new concurrent collections, I find myself writing less and less "synchronized" keywords in the code...

If you haven't done it yet, I'd suggest to give a look to the whole java.util.concurrent package. It's very useful.

http://java.sun.com/j2se/1.5.0/docs/api ... ary.htmlBy

breaking server performance do you mean simply slowing the server performance down or is the way the server is built mean certain threading operations should be avoided?

I am not following your question.
I am simply saying that I wouldn't recommend putting a synchronized in front of handleRequest and handleInternalEvent. You should look for a more fine grained thread safety. (i.e. only when strictly necessary vs. always)
Lapo

--

gotoAndPlay()

...addicted to flash games
User avatar
tobypb
Posts: 48
Joined: 15 Jun 2007, 20:50

Postby tobypb » 14 Mar 2008, 07:51

Wow java.util.concurrent supplies some amazing classes. When I first learnt java these didn't exist, and I learnt all kinds of techniques for dealing with concurrency. These certainly make things easier though!

Thanks again Lapo!

Return to “SmartFoxServer 1.x Discussions and Help”

Who is online

Users browsing this forum: No registered users and 28 guests