Page 1 of 1
SmartFoxServer#getUserById(Integer) not synchronized ?
Posted: 02 Nov 2010, 12:52
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.
Posted: 12 Nov 2010, 16:21
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
Posted: 15 Nov 2010, 12:37
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.
Posted: 15 Nov 2010, 13:20
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.
Posted: 15 Nov 2010, 13:47
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.
Posted: 16 Nov 2010, 08:58
by Lapo
Thanks, it makes sense. It's added in our todo list.
Posted: 24 Nov 2010, 08:09
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.
Posted: 30 Jun 2011, 23:04
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
