Duplicate score updating leading to incorrect scores in tournaments

As the tournament director for many tournaments, I’ve observed that the scores of some players are (randomly) increased by 2 points instead of one point after winning one single game, possibly due to duplicate score updating from the daemon process handling it.

Here’s a typical example of the result from Correspondence 13x13 RoundRobin 2015-08-25 01:00:

Player #1 has 12 points with 9 wins;
Player #2 has 10 points with 8 wins;
Player #4 has 7 points with 6 wins;
Player #8 has 6 points with 5 wins;

The McMahon bar is not activated in this tournament, so everybody should start with 0 points. Therefore, 7 games out of 45 games were scored twice, which is quite a high ratio. I guess this could be prevented by having an integrity check or some transaction protection when performing the score updating. Could someone look into this problem?

2 Likes

I’m looking into this problem, sorry about that!

Thank you, I once thought it’s been fixed, but unfortunately this bug is still happening:

Here’s my guess on the reason:

There are multiple scripts running on the back-end. When a game ends, it creates a temporary game-ending event (x_i) in the database.

Sometimes there are multiple tournament-handling threads (T_i) running. The normal process would be:

Thread T1 fetches the oldest event e1
Thread T1 deletes event e1
Thread T1 updates tournament table
Thread T2 fetches the oldest event e2
Thread T2 deletes event e2
Thread T2 updates tournament table

The time between the fetch and delete operation is very small, so in most cases the multi-threads work well. The actual running order could be like:

Thread T1 fetches the oldest event (e1)
Thread T1 deletes event e1
Thread T2 fetches the oldest event (e2)
Thread T2 deletes event e2
Thread T1 updates tournament table
Thread T2 updates tournament table

However, the problem happens when the [fetch, delete] operation is not atomic:

Thread T1 fetches the oldest event (e1)
Thread T2 fetches the oldest event (e1) (!)
Thread T1 deletes event e1
Thread T2 deletes event e1
Thread T1 updates tournament table
Thread T2 updates tournament table (the score is increased twice!)