SmartFoxServer#getUserById(Integer) not synchronized ?

Post here your questions about Actionscript and Java server side extensions development.

Moderators: Lapo, Bax

Post Reply
Tristan
Posts: 7
Joined: 09 Aug 2010, 10:39

SmartFoxServer#getUserById(Integer) not synchronized ?

Post by Tristan »

Hello,

I'm using SmartFoxServer PRO 1.6.9 and I'm working on java extensions.

I encounter some issues with the method Room#getAllUsers(). Sometime it does not return all the users of the room. This method seems to use SmartFoxServer#getUserById(Integer) to resolve User objects from user id. SmartFoxServer#getUserById(Integer) does not seem to synchronize get access on the user map.
The implementation of this map is a HashMap if a put or a remove can happen while a get is executed, the get can fail and return null instead the real stored value.

Thank you in advance for your help.
User avatar
Lapo
Site Admin
Posts: 23438
Joined: 21 Mar 2005, 09:50
Location: Italy

Post by Lapo »

Well the problem is what you are expecting. If your code executes a nanosecond after a User was removed that User won't be part of the list.

Or if your call executes a nanosecond before a new User enters the Room the same problem is there. There's nothing you can do about it, of course many processes are asynchronous.

Another story is if you have concurrency issues. In that case let us know the details of the exception.

Also you can try using getUserList() instead
Lapo
--
gotoAndPlay()
...addicted to flash games
Tristan
Posts: 7
Joined: 09 Aug 2010, 10:39

Post by Tristan »

Hello,

No the synchronization issue is not at the Room level but in SmartFoxServer class.

Case 1:
* If in a room you have user 1, 2 and 3.
* if you call SmartFoxServer#getUserById(Integer) with parameter 1, 2 and 3, it returns the users.

Case 2:
* If in a room you have user 1, 2 and 3.
* A user 4 log-in and is added the SmartFoxServer uesr list.
* if at the same time you call SmartFoxServer#getUserById(Integer) with parameter 1, 2 and 3, it will not always return the users.

The issue is: SmartFoxServer#getUserById(Integer) is not synchronized.
User avatar
Lapo
Site Admin
Posts: 23438
Joined: 21 Mar 2005, 09:50
Location: Italy

Post by Lapo »

Yes this was understood.
It's not just a matter of synchronization, if this was not synchronized correctly you would have data corruption issues, which is not the case.

The problem you are describing could happen just because your call to that method is done one nanosecond before the User object is added to the collection, regardless of the "synchronization".

There are two processes here working independently and asynchronously. We could make the whole transaction completely atomic using a coarse-grained lock on the collection on reading and writing and it wouldn't solve the problem anyways.
It just takes one nanosecond and you don't get that user because physically the Thread working on the new User being added hasn't called the Collection.put() method.

This is why the server side framework provides Server Events. They will tell you when a new user has joined or left a Zone or Room.
Lapo
--
gotoAndPlay()
...addicted to flash games
Tristan
Posts: 7
Joined: 09 Aug 2010, 10:39

Post by Tristan »

My problem is not about getting a connecting user but getting a user who is logged in since many minutes.


User 1 login:
* canLogin add the user to the list
* usersById map look like this:
[1 => User1]

User 2 login:
* canLogin add the user to the list
* usersById map look like this:
[1 => User1; 2 => User2]

User 3 login:
* canLogin add the user to the list
* usersById map look like this:
[1 => User1; 2 => User2; 3 => User3]

Call SmartFoxServer#getUserById(1)
* It returns User1

Call SmartFoxServer#getUserById(2)
* It returns User2

Call SmartFoxServer#getUserById(3)
* It returns User3

User 4 login and at the same time call SmartFoxServer#getUserById(1):
SmartFoxServer#getUserById(1) will return null.

I'm no trying to retrieve a new user I'm just trying to retrieve a user which is:
* log-in since many minutes.
* internal events were fired many minutes ago.
And this operation fails.

SmartFoxServer#getUserById(1) should always return User1 if the user is connected since many minutes and will not leave until many minutes; but it does not always return User1.

If get operations on usersById map are synchronized it will never return null for a value which is in usersById map since many minutes.
User avatar
Lapo
Site Admin
Posts: 23438
Joined: 21 Mar 2005, 09:50
Location: Italy

Post by Lapo »

Thanks, it makes sense. It's added in our todo list.
Lapo
--
gotoAndPlay()
...addicted to flash games
User avatar
Lapo
Site Admin
Posts: 23438
Joined: 21 Mar 2005, 09:50
Location: Italy

Post by Lapo »

UPDATE:
we are planning an SFS PRO update for December, if you are interested in a pre-release of the patch please contact us via email. Make sure to reference this post in the message.
Lapo
--
gotoAndPlay()
...addicted to flash games
Sarevok
Posts: 75
Joined: 12 Apr 2011, 22:12

Post by Sarevok »

Hi Lapo, I just want to ask if this issue is resolved? Tristan said that he had this problem on 1.6.9. You announced a patch in December, but I don't see any patch after 1.6.9. Or maybe it is already added to 1.6.9?

It is very important to me that this issue is resolved, otherwise my extension is going to have big problems in prioduction :wink:
Post Reply