Clone Past Match (admin)¶
Clone a CLOSED match, validate that srsim can load its recorded feed, create
an is_test row, and enqueue a live Celery listener pointed at srsim.
| Item | Value |
|---|---|
| URL | /admin/test-match-listeners |
| Nav | Play → Clone Past Match |
| Availability | Non-main only (develop, staging, test) |
| REST | GET /api/matches?league=&day=&status=closed&is_test=false&listener_events_archived=true, POST /api/matches/{id}/clone |
| Match picker | Shared admin_match_picker + AdminMatches.bindPicker (archived live matches only) |
Operator flow¶
- Choose league and local calendar day (shared pick-one controls; Day
defaults to yesterday).
You can also open this page from match details via
Clone match, which deep-links with query params
league,day(operator local calendar day ofMatch.scheduled), andmatch_id(internal match id) so the picker loads pre-selected. - Pick a CLOSED live (non-test) match that has listener events archived to S3. A View match link opens that row’s match details page.
- Optionally click a form preset (does not change the selected match or clone start):
- Normal-time — reset stream + listener fields to page defaults; Wait for listener off (continuous session, Sportradar-like).
- Speed through —
playback_speed=0,max_ms_between_events=100,rewrite_ts_strategy=0, Wait for listener on (one-shot),listener_timing_source=ts,listener_post_issuance_pause_seconds=35,listener_sr_request_timeout=60(fast feed, human answer window; timeout above the pause so the HTTP read does not die). - Optionally set clone start datetime (default: now UTC), or use +1 /
+5 / +10 / +30 / +60 to add minutes to the current start (or to now
if empty). A future kickoff delays
start_match_listeneruntil that time (Speed through one-shot and Normal-time continuous). With Wait for listener off, this is also the continuous srsim session kickoff (Match.scheduled): the feed clock starts here even if no listener is connected. It is not the same as srsimstart_at(which slices the archive). See SRSim parameters — continuous sessions. - Optionally enable Push notifications for the clone (default off).
When off, push fan-out skips the match (
skip_reason=match_push_disabled) so the auto-followed creator is not notified during srsim. Toggle later on match details (including mid-match). See Push notifications. - Optionally edit In-game question overrides (max questions, min interval, points,
period distribution). Points accept an absolute value or
*Nmultiplier of the league default. Fields prefill from the selected match; blank uses league defaults. Same semantics as Matches. - Optionally edit Sponsorships (match sponsor + question sponsorship slots).
Prefills from the source match via match detail; clear sponsor with None,
remove or add slots as needed. Written on clone create (before the listener
starts). Slot count cannot exceed the clone’s effective
question_max_count. - Optionally set srsim stream properties (
playback_speed,start_at, Wait for listener, etc.). - Optionally set listener env overrides (including
listener_post_issuance_pause_secondsfor a real-time pause after each issued question during fast playback, andlistener_force_exit_codefor ops exit-code testing).listener_write_logs_to_filedefaults to on. - Clone — fails with 404 if no archived recording exists in
AWS_S3_MATCH_ARCHIVE_BUCKETfor the match shortcode ({sr_id[:8]}-{match_id[:8]}.json). No clone row is created on failure. On success, the page redirects to the new clone’s match details (/admin/matches/{clone_id}). The creator is auto-followed on the server (force); unrestricted Play Following also gets the clone id inlocalStorageso the filter bar picks it up without a manual follow.
POST /api/matches/{id}/clone accepts the same override_question_* fields as
match PATCH. Omitted fields copy the source match; explicit null clears
(league defaults); a value sets the clone override. The authenticated admin is
stored as created_by_user_id on the new is_test row (shown as
Created by on match details).
The same omit / null / value pattern applies to sponsor_brand_id and
question_sponsorships (omit copies source slots; [] clears; otherwise the
provided list is written, each item with brand_id + strategy/target/
best_effort).
The clone is created as scheduled.
Wait for listener off (default): clone injects
session={internal match id}. The continuous srsim session owns status —
inprogress when the producer starts; with game_delay_at_event,
delayed then back to inprogress; closed when the stream completes.
The MatchListener does not write status. Operator Stop ends the Celery listener
only; srsim keeps advancing — use
POST /sessions/{internal_match_id}/reset or /stop to rewind/halt (see
what-if scenarios).
Wait for listener on: no session= (one-shot replay). The listener sets
inprogress when it starts and closed when it exits. Reconnect restarts
the archive from the beginning (or start_at).
Auto-dispatch includes is_test rows (open MatchListenerRecord still
prevents double-start). On develop, Beat only dispatches test clones
(is_test=True); staging/main dispatch includes live and test.
The listener stream uses the clone’s Sportradar match id (Match.sr_id) against
srsim (which loads the source archive from S3). New listener runs still write
live event files under
{FILESYSTEM_CONTAINER_DATA_DIR}/listener/{league}/{Match.shortcode}.json.
To browse existing test clones, use Matches and filter Test only.
Related¶
- Matches — list/filter test clones
- Brand Sponsorships — assign sponsors on live scheduled matches
- SRSim parameters (continuous sessions + what-ifs)
- Match listener startup