Hi, I'm making a database-driven game, in which there is a question, and a user gains the right to change the question (i.e. write a new question) if they find the correct answer.
But this has an important issue, I think it's called a race condition. The issue is this:
Right now, I've fixed this issue by using some kind of semaphore, by keeping its timestamp
. To summarize it works like this:
['user_ip' = 'x.x' , 'time'='y.y' , 'locked'='true']
so when a new question is submitted, the application accepts it only if the semaphore is not locked, and the current time is larger by t
(15) seconds than the semaphore's date.
But this has a problem too, User 2 is prompted
"You have found the answer, but somebody found it before you. You can change the question if they don't submit a new question in 15 seconds."
So the new winner has to wait 15 seconds, maybe unnecessarily.
Therefore,
I want to prompt the "winner" a form, with a stopwatch (time counter). When it reaches zero, it unlocks the semaphore so that the new winner can submit their question.
But this solution will have this problem:
If the winner closes the page before time counter reaches to zero, then the AJAX request will never be done and the semaphore will be locked indefinitely.
So I have to make sure I have called the userLeave();
function if the user closes the page.
Google suggests onbeforeunload
and onunload
but people also complain about those functions not working. So is there a 100%-sure way to send this AJAX call if a user (a winner) leaves the page ?
Is there a 100%-sure way to send this AJAX call if a user (a winner) leaves the page?
You can never rely on the client doing anything 100%. Think of network connectivity losses, browser crashes, not available features (from HTML5-incompatible browsers to disabled javascript), scripting errors, misconfigured agents that do call (or not) your API in unexpected ways or hackers doing the same on purpose…
The only thing you can expect of a client is that he does nothing - which is called a timeout.
If you want your semaphore to expire at a certain time, you have to create the timer serverside. If you want, you can additionally abort the timer and expire immediatley when a client signals that he's not going to submit an answer (by whichever means). If you want to try to catch closing the page, you can use synchronous (A)JAX from an unload
event.
Btw: While I don't know your game, it would be easier and probably more comfortable if you simply would accept both new questions :-)