Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Race condition in SmrSession #635

Open
hemberger opened this issue Jan 16, 2019 · 1 comment
Open

Race condition in SmrSession #635

hemberger opened this issue Jan 16, 2019 · 1 comment
Labels

Comments

@hemberger
Copy link
Member

When players are logging in, they can sometimes trigger a duplicate entry in the active_session table. Analyzing the pathways for this to occur, it appears to only be possible when the same login is processed twice almost simultaneously.

MySQL Error MSG: Duplicate entry '...' for key 'PRIMARY'
Error Message: Exception: SQL query failed (INSERT INTO active_session (session_id, account_id, game_id, last_accessed, session_var) VALUES(...) in /smr/lib/Default/MySqlDatabase.class.inc:133
Stack trace:
#0 /smr/lib/Default/MySqlDatabase.class.inc(38): MySqlDatabase->error('SQL query faile...')
#1 /smr/lib/Default/SmrSession.class.inc(249): MySqlDatabase->query('INSERT INTO act...')
#2 /smr/htdocs/login_processing.php(220): SmrSession::update()
#3 {main}

This occurs on a fairly regular basis (maybe a few times a week to a few times a month), but the only way I have been able to reproduce it in development was by manually adding a sleep just before the INSERT and manually triggering it twice.

I have not been able to rapidly respond to players who encountered this issue, but one player a few hours later described their pre-error activity as (roughly) "logging in, going afk for a while, then trying to log in again from the same browser window".

This error could be avoided by using REPLACE instead of INSERT, but I feel like that only hides the underlying problem, which I do not fully understand yet.

@hemberger hemberger added the bug label Jan 16, 2019
@hemberger
Copy link
Member Author

This simplified diagram of the logic illustrates how the error is impossible to trigger in a single-threaded case.

if (session_id exists in database) {
    generate = false
} else {
    generate = true
}

if (generate) {
    insert session_id into database   <-- this is where the error occurs
}

hemberger added a commit that referenced this issue Jan 16, 2019
There was a lot of other processing between when the SmrSession
was created during login and when it was actually saved to the
database. The longer this time interval, the greater the opportunity
for a race condition.

Save the SmrSession as soon as possible (immediately after it is
updated with the account_id and the next page SN. This is not
expected to fix the problem, but may reduce its frequency.

See #635 for more detail.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

1 participant