Transaction Bug? Delay?

Game development with Board Game Arena Studio
Post Reply
User avatar
XCID
Posts: 78
Joined: 26 March 2020, 01:45

Transaction Bug? Delay?

Post by XCID »

Dear smart people of BGA Studio,

I have to ask about a problem I thought I already solved. But I received a bug report about it, so I'll need to look into it again. There is also a chance that only the admins can help me out. Let's see :)

My (now in beta) game Boomerang: Australia has a drafting mechanism, similar to Sushi-Go for example. You simply pick a card from your hand and after all players did that, the chosen card are evaluated and the hand moves to the next player.

So, during alpha development, I set a flag to the card with the player_id in the 'card' table. After that, the player is set to not-multiactive.
After the last player, the game moves on to the evaluation process, where I now select all these cards with the player_id flags.

That seemed to work as is should, but I received some bug reports that one of the cards, that got selected, wasn't included in the evaluation process, as if one player never selected a card. So I looked into it and after a couple of tests I was able to reproduce the problem: it only happened, when the two remaining players to select their card did it at the exact same time. The game moved on to the evaluation part, while one of the transactions wasn't comitted yet. So, in the selection of the cards, that one card was missing, which of course leads to some problems.

I approached the admins and received some snippets from Sushi-Go, which basically does it the exact same way, but instead of a flag on the 'card' table, they save the selected card id in the 'player' table. So I changed my code to do it also this way and the problem seemed to have gone. Weird, but ok.

Now that the game is in beta, I received another report about this problem (if you'd like to have a look: #116599092, pick player Kris10pie, move 40). So I have to seek for a different solution.

I build a small test project just for this purpose (xcidbugtest, feel free to try it yourself) and played around a little. I save a flag in a test-table and do the same in the player-table, afterwards I select these flags again. (The flags are increasing in value each round). Now, here is what happens (remember, this only happens when both players click the card at the same time):
bga_transaction_weird.jpg
bga_transaction_weird.jpg (89.03 KiB) Viewed 827 times
In move 117, everything is OK, the flags in both tables are stored just fine. But in move 118, the flag for player 2321660 has been committed to the 'player' - table, but not to the 'test' table. Even though everything happened in the same transaction. Looking at the table with the phpMyAdmin reveals that eventually the test-table is also updated, but too late.
bga_transaction_weird_2.jpg
bga_transaction_weird_2.jpg (4.72 KiB) Viewed 827 times
So, using the 'player' table (like I do in the actual game) seems to cause no problems, but since I got the new bug report, it appears that it can also happen with the player table. Not really sure. Sushi-Go does not have any bug report like that.

As a workaround, I will check for the amount of selected cards before I continue and throw a BGA exception if it's not fitting the players number, so that the whole transaction will be cancelled and that one player has to pick that card again, but that feels a bit 'dirty' :lol:

Any ideas?
User avatar
XCID
Posts: 78
Joined: 26 March 2020, 01:45

Re: Transaction Bug? Delay?

Post by XCID »

Found another workaround, which still feels a bit 'meh', but it seems to work.

Instead of setting the player inactive in the action, I send a notification to that player, which directly triggers another action, in which the player is then set to non active. That gives the DB enough time to finish all transactions.
User avatar
Victoria_La
Posts: 665
Joined: 28 December 2015, 20:55

Re: Transaction Bug? Delay?

Post by Victoria_La »

So the problem is that your number i.e. 117 does not increase? Where is it stored? Is this stored in database? You have a classic concurrency
race condition. Normally it solved by mutexes, but in this case server probably already started transaction so its too later.
When you send action to server do you pass lock: true flag in ajax call?
User avatar
XCID
Posts: 78
Joined: 26 March 2020, 01:45

Re: Transaction Bug? Delay?

Post by XCID »

Yes, the lock - flag is passed, but it's not helping.

What's happening here is the following: let's say we have two players in a multipleplayer-state. They can click on a card, which triggers an action. In this action, the card-id is stored in the database and setPlayerNonMultiactive() is called. After the second player is set to NonMultiactive, a game state is executed, where these card-ids are selected from the DB.

Player A clicks:
UPDATE sometable SET card_id = 555 where player_id = 1;
setPlayerNonMultiactive(1);

A bit later, Player B clicks:
UPDATE sometable SET card_id = 999 where player_id = 2;
setPlayerNonMultiactive(2);
-> Game proceeds to next state, triggered by Player B.
-> SELECT card_id FROM sometable

Expected Result:
1: 555
2: 999

Now, if both players click at the same time (or more precise, the request hits the server at the same time), the result sometimes is
1: 0 (or whatever data was in the table before)
2: 999

So in my understanding, the game shouldn't progress to the next state, until all the DB transactions are fully committed.

-------
What's weird: if, instead of writing the data to "sometable", I write it into the 'player' table, the problem seems to appear much much less frequent.
vincentt
Posts: 254
Joined: 01 September 2017, 17:25

Re: Transaction Bug? Delay?

Post by vincentt »

Hi

If you look at the unexpected errors you should see a deadlock error. This happens a lot in diceforge.
What you could do :
- Before calling the setPlayerNonMultiactive(), check that the update was correctly done (as a postulate player_id should have something updated)
- In your next state, detect if there are some players with non seleted card and if so go back to the multiactive state.

I think I managed this like that, but without knowing this will happen (sometime it is allowed to get lucky :))

Cheers
Post Reply

Return to “Developers”