Urgent.News

What's breaking now, across thousands of outlets.

Tech

Two phones at the same table pressed Join in the same moment, and the loser was told the quiz did not exist

Nobody who plays a quiz on PubTrivia has an account. They scan the code on their table, type a name, and they are in. That is deliberate, because the alternative is asking six people in a pub to install something, and the honest conversion rate on that is zero. Which leaves the question every anonymous multiplayer thing has to answer: what is a player, if not a user? Here, a player is a row in…

In the event of a PubTrivia quiz, players join by scanning a code, typing their name, and pressing the Join button. The trivia game does not require players to have an account, which simplifies the process. This design choice eliminates the need for users to install anything on their devices, as the conversion rate for doing so is virtually zero.

Each player is represented as a row in the table_participants table, with the primary key being the only means of identifying them. The identity is stored in the browser's localStorage, keyed by the table type and the player's unique identifier. This information is saved using a function that handles potential localStorage errors, such as when the browser is in private browsing mode.

The join process involves three rules, each requiring a read followed by a write operation. These rules include ensuring unique player names within a session, case-insensitive uniqueness, and allowing only one row per table during team play. If these rules are violated, specific error messages are generated, informing the player of the issue.

Two phones at the same table pressing Join at the same moment can lead to a race condition, where both phones read the database as having no row for the table, insert a new player record, and then encounter a partial unique index violation on the leaderboard. This results in the second person being told that the session does not exist, even though it does. The issue lies in the lack of a transaction-scoped advisory lock, which would prevent concurrent inserts and provide a more accurate outcome.

Written by urgent.news from Dev.to's reporting — not their text. Machine-written — may contain errors; check the original before relying on it.

Read the original at dev.to →

More in Tech

Kubernetes Controllers: The Cache-Staleness Bug at Scale

Key takeaways Structure reconcilers as ordered, independently testable steps, each reporting its own status condition, over one monolithic Reconcile function.

  • Kubernetes controller pattern divides reconcile loop into ordered steps
  • Informer caches may lag by tens of milliseconds, causing stale reads
  • Shared status-patching helper centralizes conflict-safe read-then-patch

More from Wednesday 14 October →