Discuss Scratch
- Discussion Forums
- » Help with Scripts
- » Cloud variables and concurrency
- MegaApuTurkUltra
- Scratcher
1000+ posts
Cloud variables and concurrency
I'm planning on a project with a cloud leaderboard. I already made a system for encoding usernames and scores lists as numbers, so that's not a problem.
What I'm worried about is the following. Although there's a very low chance of it happening, it could happen.
Is there any way to prevent this?
What I'm worried about is the following. Although there's a very low chance of it happening, it could happen.
- Player 1 gets a higher score than everyone else
score = 10000
- Player 2 gets a higher score than everyone else
score = 9999
- Player 1 retrieves and decodes cloud leaderboard
leaderboard:
Herp: 5000
Derp: 4500
Derpity Derp: 1000 - Player 2 retrieves and decodes cloud leaderboard. Note that at this point Player 1 is not on the leaderboard yet.
leaderboard:
Herp: 5000
Derp: 4500
Derpity Derp: 1000 - Player 1 updates the leaderboard with the score and sets the cloud variable
leaderboard:
Player1: 10000
Herp: 5000
Derp: 4500
Derpity Derp: 1000 - Player 2 still has the leaderboard as so when the cloud variable is updated the list now looks like
leaderboard:
Herp: 5000
Derp: 4500
Derpity Derp: 1000leaderboard:
Player2: 9999
Herp: 5000
Derp: 4500
Derpity Derp: 1000 - Player 1's score now has disappeared! The list on the cloud variable is
leaderboard:
Player2: 9999
Herp: 5000
Derp: 4500
Derpity Derp: 1000
Is there any way to prevent this?
$(".box-head")[0].textContent = "committing AT crimes since $whenever"
- SurgeForce
- Scratcher
100+ posts
Cloud variables and concurrency
Before updating the scoreboard, player 2 should check if it still equals the same thing as it did when player 2 first retrieved it to change it.
- SurgeForce
- Scratcher
100+ posts
Cloud variables and concurrency
If its different, player 2 should delete his edited version and retry
- MegaApuTurkUltra
- Scratcher
1000+ posts
Cloud variables and concurrency
But then you run into the same problem. What if it's updated right after the check? Before updating the scoreboard, player 2 should check if it still equals the same thing as it did when player 2 first retrieved it to change it.
$(".box-head")[0].textContent = "committing AT crimes since $whenever"
- MegaApuTurkUltra
- Scratcher
1000+ posts
Cloud variables and concurrency
Bumpity bump. Does anyone have an answer?
$(".box-head")[0].textContent = "committing AT crimes since $whenever"
- TheLogFather
- Scratcher
1000+ posts
Cloud variables and concurrency
You might find the following posts I made a while back have some helpful info:
http://scratch.mit.edu/discuss/post/293717/
http://scratch.mit.edu/discuss/post/129373/
http://scratch.mit.edu/discuss/post/119793/
Ultimately, though, the way the cloud is implemented at the moment, you can't really guarantee 100% that you will avoid situations like above. You can do things that can help make it less likely, though (see below).
Having said that, I think the simplest thing for something as basic as a cloud-based hi-score, is to just GFI, ignoring the problems, expecting that it's really rare two people will save a hi-score at very nearly the same time (within half a second, usually).
If you do want to make it even less likely to cause trouble, then I'd suggest a kind of ‘locking’ mechanism, something like I was attempting with my cloud locking project, and used in my cloud ping test project (I also put something like it into the hi-score table for InterXeptor 3D).
The idea is to have a single ‘locking’ cloud variable, that you set to a unique value for a user (based on an encoded version of their username, or a long string of random digits), but wait for it to be zero before trying to set it (with a timeout of a few seconds). Once ‘locked’, read the hi-scores from cloud (to ensure got latest values), prepare the new hi-score encoded string (but don't put into actual cloudvar yet). After a second or two, check that the locking cloudvar still has the correct value (if not, start the whole process again). If it does, then update the hi-score cloudvar, and release the locking cloudvar (set it back to zero).
Hope there's some useful thoughts there…
http://scratch.mit.edu/discuss/post/293717/
http://scratch.mit.edu/discuss/post/129373/
http://scratch.mit.edu/discuss/post/119793/
Ultimately, though, the way the cloud is implemented at the moment, you can't really guarantee 100% that you will avoid situations like above. You can do things that can help make it less likely, though (see below).
Having said that, I think the simplest thing for something as basic as a cloud-based hi-score, is to just GFI, ignoring the problems, expecting that it's really rare two people will save a hi-score at very nearly the same time (within half a second, usually).
If you do want to make it even less likely to cause trouble, then I'd suggest a kind of ‘locking’ mechanism, something like I was attempting with my cloud locking project, and used in my cloud ping test project (I also put something like it into the hi-score table for InterXeptor 3D).
The idea is to have a single ‘locking’ cloud variable, that you set to a unique value for a user (based on an encoded version of their username, or a long string of random digits), but wait for it to be zero before trying to set it (with a timeout of a few seconds). Once ‘locked’, read the hi-scores from cloud (to ensure got latest values), prepare the new hi-score encoded string (but don't put into actual cloudvar yet). After a second or two, check that the locking cloudvar still has the correct value (if not, start the whole process again). If it does, then update the hi-score cloudvar, and release the locking cloudvar (set it back to zero).
Hope there's some useful thoughts there…
Last edited by TheLogFather (Aug. 16, 2014 20:11:07)
Siggy the Kumquat slayer:
Main account: DadOfMrLog –– Frameworks for basic pen-rendered 3D in scratch (see studio). Examples:
- - - - 3D Text - - - - - - Simple shapes - - - Controllable structures - - - On the ground - - - - - - In space - - - -
- - - - 3D Text - - - - - - Simple shapes - - - Controllable structures - - - On the ground - - - - - - In space - - - -
- AonymousGuy
- Scratcher
1000+ posts
Cloud variables and concurrency
My way of cloud engines was designed to prevent any of this ever.
How it works - each client gets an “id” when first starting the project. There is then a cloud variable which contains the “id” whose turn it is to save. If someone disconnects, eventually the “id” will get around to someone still connected.
However, it makes it much slower - I'm guessing that there's basically a tradeoff - either the possibility of data overwrite with higher speeds, or safer cloud data with much slower speeds.
I, of course, am by no means an expert.
How it works - each client gets an “id” when first starting the project. There is then a cloud variable which contains the “id” whose turn it is to save. If someone disconnects, eventually the “id” will get around to someone still connected.
However, it makes it much slower - I'm guessing that there's basically a tradeoff - either the possibility of data overwrite with higher speeds, or safer cloud data with much slower speeds.
I, of course, am by no means an expert.
- TheLogFather
- Scratcher
1000+ posts
Cloud variables and concurrency
@AonymousGuy: Beware of saying “ever” - yes, making it turn-based can help reduce risks, but I can think of at least two potential ways that it could go wrong…
1) Think about loopholes in the first essential part - getting an ‘id’. What happens if two users try to get an id at very nearly the same time? Is there really no way they could end up with the same id…? (I don't know exactly how your engine works, but I'm guessing it's quite likely there's a potential loophole…)
2) What happens if a user doesn't take their turn? Does it eventually give up and ‘skip’, moving on to the next user? If so, I suspect there will be a loophole where a user with a slow/dodgy connection could end up seeing their ‘turn’ after it's already moved on to someone else - and they then make their changes to the cloudvar, overwriting anything else done by the subsequent user(s) - and presumably resetting the ‘turn id’ back to a user who's just had their turn…
One of the things to remember is that the order values are sent from the server to users is not necessarily the order the users will receive those values. Similarly, the order users send values to the server is not necessarily the order the server will receive them - it all depends on networks, etc.
Of course, most of the time these won't be so much of a problem (if you don't have too many people making changes at once). But are either of the above two scenarios possible, do you think…?
1) Think about loopholes in the first essential part - getting an ‘id’. What happens if two users try to get an id at very nearly the same time? Is there really no way they could end up with the same id…? (I don't know exactly how your engine works, but I'm guessing it's quite likely there's a potential loophole…)
2) What happens if a user doesn't take their turn? Does it eventually give up and ‘skip’, moving on to the next user? If so, I suspect there will be a loophole where a user with a slow/dodgy connection could end up seeing their ‘turn’ after it's already moved on to someone else - and they then make their changes to the cloudvar, overwriting anything else done by the subsequent user(s) - and presumably resetting the ‘turn id’ back to a user who's just had their turn…
One of the things to remember is that the order values are sent from the server to users is not necessarily the order the users will receive those values. Similarly, the order users send values to the server is not necessarily the order the server will receive them - it all depends on networks, etc.
Of course, most of the time these won't be so much of a problem (if you don't have too many people making changes at once). But are either of the above two scenarios possible, do you think…?
Last edited by TheLogFather (Aug. 17, 2014 15:18:36)
Siggy the Kumquat slayer:
Main account: DadOfMrLog –– Frameworks for basic pen-rendered 3D in scratch (see studio). Examples:
- - - - 3D Text - - - - - - Simple shapes - - - Controllable structures - - - On the ground - - - - - - In space - - - -
- - - - 3D Text - - - - - - Simple shapes - - - Controllable structures - - - On the ground - - - - - - In space - - - -
- AonymousGuy
- Scratcher
1000+ posts
Cloud variables and concurrency
@AonymousGuy: Beware of saying “ever” - I can think of at least two potential ways that the method you describe could go wrong…
I, of course, am by no means an expert.
Yes, that could be a problem - I guess I never thought about it before. I guess I'll just have to hope that nobody tries to connect at the exact same time… 1) Think about loopholes in the first essential part - getting an ‘id’. What happens if two users try to get an id at very nearly the same time? Is there really no way they could end up with the same id…? (I don't know exactly how your engine works, but I'm guessing it's quite likely there's a potential loophole…)
It will skip them and actually remove them from the queue, basically disconnecting them. I've tried to keep this minimal by waiting something like 4 seconds to wait for their connection, but if they don't take their turn, the person next will eventually take their own, and add the previous user to a list of user ids to skip. 2) What happens if a user doesn't take their turn? Does it eventually give up and ‘skip’, moving on to the next user? If so, I suspect there will be a loophole where a user with a slow/dodgy connection could end up seeing their ‘turn’ after it's already moved on to someone else - and they then make their changes to the cloudvar, overwriting anything else done by the subsequent user(s) - and presumably resetting the ‘turn id’ back to a user who's just had their turn…
Of course, they would still overwrite the data once, but after that they would be virtually disconnected, without the ability to write data.
The only way they would be added back on is if they were also re-writing the list of user ids to skip - which would be unlikely.
- Ante22
- Scratcher
100+ posts
Cloud variables and concurrency
I have the simmilar problem.
You could make update before saving. (Not very helpfull ha ?)
You could make update before saving. (Not very helpfull ha ?)
- Discussion Forums
- » Help with Scripts
- » Cloud variables and concurrency