Skip to content

fix(cache): serve dynamic-outcome markets that carry no static outcomes - #65

Closed
mkelcik wants to merge 1 commit into
mainfrom
fix/dynamic-outcome-market-coverage
Closed

mkelcik wants to merge 1 commit into
mainfrom
fix/dynamic-outcome-market-coverage

Conversation

@mkelcik

@mkelcik mkelcik commented Sep 16, 2026

Copy link
Copy Markdown
Contributor

What was wrong

The odds feed now publishes markets whose outcomes are not in the catalog. Anytime Goalscorer (market 341 on test) is described as

<market id="341" name="Anytime Goalscorer" includes_outcomes_of_type="cw:player" outcome_type="player"><outcomes/></market>

and its outcomes arrive with the odds as cw:player:* URNs. The SDK is already half-ready for that: marketDataImpl.OutcomeName takes the dynamic branch when outcome_type is set and resolves the name through the player cache. The market description cache was not: coversLocaleLocked treats an entry with zero outcomes as covering nothing (guarding against a broken row whose <outcomes> container lost its children), so MarketDescriptionByID answered ErrMarketLocaleIncomplete and LocalizedMarketDescriptions omitted the market. A consumer could never read the description, and on kollector every odds_change for market 341 is skipped with "market description unavailable" (~260 times per 10 minutes on test since the market went live).

What changes

  • coversLocaleLocked: a zero-outcome entry counts as covered when the row declares an outcome_type (dynamicOutcomesLocked). The name check and the per-outcome name check are unchanged.
  • removeLocale: same exception in the emptiness test, so reconciliation does not drop a dynamic market that legitimately has no outcomes.
  • upsert: a dynamic row that omits the <outcomes> block entirely is read as an empty container instead of being recorded as malformed. Rows without outcome_type keep the old classification, including TestMarketDescriptionCache_EmptyOutcomesContainerNotCovered.

No public API change.

Tests

internal/cache/market_dynamic_outcomes_test.go:

  • outcome_type="player" with <outcomes/> and with no outcomes block: by-id lookup succeeds, snapshot carries the name, OutcomeType, IncludesOutcomesOfType and zero outcomes, the bulk view lists the market.
  • <outcomes/> without outcome_type still answers ErrMarketLocaleIncomplete.

Consumer: corwyn-com/kollector needs this in a release to finish GAD-5544 (dynamic player outcomes in mq).

A market description with outcome_type set (Anytime Goalscorer:
outcome_type="player", empty <outcomes/>) lists no static outcomes on
purpose: its outcomes are player URNs that arrive with the odds and
OutcomeName already resolves them through the player cache. The
coverage check treated every zero-outcome entry as incomplete, so
MarketDescriptionByID answered ErrMarketLocaleIncomplete and the bulk
view omitted the market; consumers could never read its description.

A zero-outcome entry now counts as covered when the row declares an
outcome_type, both in coversLocaleLocked and in removeLocale's emptiness
test, and a dynamic row that omits the <outcomes> block entirely is read
as empty rather than malformed. Rows without outcome_type keep the old
classification.
@github-actions

Copy link
Copy Markdown

Merging this branch will increase overall coverage

Impacted Packages Coverage Δ 🤖
github.com/oddin-gg/gosdk/internal/cache 75.07% (+0.51%) 👍

Coverage by file

Changed files (no unit tests)

Changed File Coverage Δ Total Covered Missed 🤖
github.com/oddin-gg/gosdk/internal/cache/market.go 92.31% (+0.70%) 442 (+37) 408 (+37) 34 👍

Please note that the "Total", "Covered", and "Missed" counts above refer to code statements instead of lines of code. The value in brackets refers to the test coverage of that file in the old version of the code.

Changed unit test files

  • github.com/oddin-gg/gosdk/internal/cache/market_dynamic_outcomes_test.go

@mkelcik

mkelcik commented Sep 16, 2026

Copy link
Copy Markdown
Contributor Author

Opened against the wrong repository: kollector consumes github.com/corwyn-com/gosdk. Superseded by the same change in corwyn-com/gosdk.

@mkelcik mkelcik closed this Sep 16, 2026
@mkelcik
mkelcik deleted the fix/dynamic-outcome-market-coverage branch September 16, 2026 12:06
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant