Ticket Lifecycle
Every state your backend can observe, and what moves between them.
stateDiagram-v2
[*] --> Active: CreateTicket
Active --> Resolved: match formed → match.created
Active --> Cancelled: CancelTicket
Active --> Expired: expiration_ttl_secs elapsed → ticket.expired
Active --> Removed: queue cleared / retired / params changed → ticket.removed
Resolved --> Active: ReactivateTickets
Resolved --> [*]: terminal_retention_ttl_secs elapsed
Cancelled --> [*]: terminal_retention_ttl_secs elapsed
Expired --> [*]: terminal_retention_ttl_secs elapsed
Removed --> [*]
| State | Meaning |
|---|---|
| Active | Waiting in the pool and eligible for matching |
| Resolved | Committed to a formed match. No longer matchmaking |
| Cancelled | Withdrawn by you via CancelTicket |
| Expired | Aged out unmatched after expiration_ttl_secs |
| Removed | Taken out of the pool by a configuration change, retirement, or a pool clear |
The edge that matters
Section titled “The edge that matters”Resolved → Active via ReactivateTickets is the only
way to undo a match you cannot honour, and it exists only while the ticket is still retained.
Once terminal_retention_ttl_secs elapses the ticket is gone and the player needs a fresh
CreateTicket.
That makes terminal_retention_ttl_secs a real integration parameter rather than a cleanup detail:
it is the width of your compensation window. See
When provisioning fails.
Terminal states are terminal
Section titled “Terminal states are terminal”Cancelled, Expired, and Removed never return to Active. Reactivation applies to Resolved
tickets only. A ticket that expired was never matched, so there is nothing to compensate for.
Re-queue those players with a new ticket instead.