Skip to content

deps: Bump github.com/reearth/ygo from 1.48.0 to 1.50.0 - #141

Open
dependabot[bot] wants to merge 1 commit into
mainfrom
dependabot/go_modules/github.com/reearth/ygo-1.50.0
Open

dependabot[bot] wants to merge 1 commit into
mainfrom
dependabot/go_modules/github.com/reearth/ygo-1.50.0

Conversation

@dependabot

@dependabot dependabot Bot commented on behalf of github Sep 14, 2026

Copy link
Copy Markdown
Contributor

Bumps github.com/reearth/ygo from 1.48.0 to 1.50.0.

Release notes

Sourced from github.com/reearth/ygo's releases.

v1.50.0 — Redis Streams relay tier: at-least-once delivery with bounded replay

v1.50.0

Who is affected: nobody, unless you choose to be. This release adds a second way for cluster/redis to move updates between nodes. The existing way is the default and is unchanged — if you do not set the new Config.Transport field, your cluster behaves exactly as it did in v1.49.x, down to the Redis commands it issues.

What you may want to opt into. Until now, a multi-node deployment relayed updates over Redis pub/sub, which is at-most-once: if a node cannot keep up with the stream of messages — a slow moment, a network blip, Redis disconnecting a client whose buffer overflowed — the messages it missed are gone. Nothing reports it. Because collaborative updates depend on each other, one missed update quietly parks every later edit from that same client on that node, and the node only catches up when the room is next loaded from storage. On a busy room that is never loaded again, so it never catches up.

Transport: Streams replaces that mechanism with Redis Streams, which keep recent messages instead of forgetting them. A node that falls behind, restarts, or joins late reads what it missed instead of losing it.

What it guarantees, precisely. Delivery is at-least-once within the window Redis is asked to retainmin(StreamRetention, StreamMaxLen ÷ your publish rate), 60 seconds and 4096 messages per room by default. This is not a no-loss guarantee and we will not describe it as one: the retained history is trimmed at both ends, so a node that falls further behind than the window loses whatever was trimmed underneath it. The difference from pub/sub is not that loss became impossible. It is that loss became bounded and visible — a new Relay.StreamStats() counter, Gaps, goes non-zero when it happens, and a single Gaps means the window was too small for how far behind that node actually got. Size the window for the worst delay you intend to survive: a deploy rollover, a long garbage-collection pause, a node restart.

One limit on that visibility, stated plainly: Gaps detects a jump only after the process has seen a baseline for the publishing node, and those baselines live in memory. A relay that has just restarted takes whatever sequence number it reads first as its baseline, so anything trimmed away while it was down leaves Gaps at zero. Loss over a reader's own downtime is bounded by the retention window rather than reported — which is the other reason to size the window for your restart and deploy times.

What it costs, and why pub/sub is still here. Publishing to pub/sub costs Redis nothing: it hands the message to whoever is listening and forgets it. Writing to a stream is a real write — it replicates, it goes into your AOF/RDB if you have persistence on, and it holds memory proportional to retention × update rate × update size for every room on the node (roughly 800KB per busy room at the defaults). Reading costs a small steady stream of commands even when nothing is happening, and that cost grows with how many rooms a node holds: each reader issues one XREAD per 512 stream keys, and

... (truncated)

Changelog

Sourced from github.com/reearth/ygo's changelog.

[1.50.0] — 2026-09-10

Added

  • cluster/redis: an at-least-once delivery tier built on Redis Streams (#206). Config.Transport selects it; the zero value is PubSub, so every existing deployment is unchanged and no new field has to be set.

    Redis pub/sub is at-most-once by Redis's own definition: a subscriber that cannot keep up loses the message for good, and no amount of client-side buffering changes that. #187 asked for "no silent divergence on backpressure" and PR #200 could only bound the damage. This tier delivers a bounded version of it: each room becomes a Redis stream, and a reader that stalls or restarts resumes from where it left off.

    The guarantee is bounded and stated as such: at-least-once within min(StreamRetention, StreamMaxLen / publish-rate) — defaults 60s and 4096 entries, the two enforced separately (MAXLEN ~ inline on XADD, XTRIM MINID on a TrimInterval sweeper), so whichever binds first is the real window. 60s matches y-redis's own REDIS_MIN_MESSAGE_LIFETIME. It is not a no-loss guarantee: a reader lagging past its room's window loses what was trimmed underneath it, and StreamStats.Gaps makes that loss provable rather than silent.

    Sync streams are read from the oldest retained entry, not the tail. V1 updates are idempotent, so replay is harmless — which eliminates the race between loading a snapshot and starting to read, and makes late-joiner catch-up fall out for free. No cursor is persisted anywhere; a lost cursor costs a replay, not a loss.

    Under lane backpressure the reader declines to advance its cursor rather than merging or dropping the backlog. The entries stay in the stream and are read again next cycle, so backpressure toward Redis is safe here for the first time — what it costs is lag, and lag past the window shows up as Gaps.

    Awareness gets its own stream, read from the tail and never replayed. Sharing the sync stream would let heartbeat traffic evict sync entries out of the retention window, and replaying presence would resurrect clients that are long gone. Awareness entries are excluded from gap accounting for the same reason.

    New Config fields: Transport, StreamPrefix, StreamRetention, StreamMaxLen, AwarenessMaxLen, AwarenessRetention, Readers, TrimInterval, ReadBlock. New rejects rather than silently adjusts: an unknown Transport; a client PoolSize not greater than Readers; a TrimInterval not less than StreamRetention; and a ReadBlock outside [1ms, 250ms] — 250ms because a blocked XREAD cannot be interrupted, so that value is also how long Close and a newly activated room may wait, and 1ms because go-redis truncates sub-millisecond values to BLOCK 0, which Redis reads as "block forever". Nothing is validated in PubSub mode.

... (truncated)

Commits
  • 7bebc9e feat(cluster): Redis Streams relay tier with at-least-once delivery and bound...
  • 13b918c test(client): generous hang deadlines, with a goroutine dump on timeout (#243...
  • 34882d8 fix(client): classify a rejected token at every write site, not just two (#23...
  • 28b7f3e docs(readme): lead with code, and stop duplicating the changelog (#241)
  • 85dd1aa fix(websocket): back off a failing MemoryPersistence fold instead of retrying...
  • f987dfe fix(client): a rejected auth token could reach a second attempt (#238)
  • ec42817 docs: release notes for v1.49.2 (#237)
  • f06a1a3 test(crdt): a benchmark that can actually see the observed-transaction cost (...
  • 2355ac1 fix(crdt): ApplyUpdateV2 silently dropped content on GC structs (#235)
  • ac9cd00 fix(websocket,client): append-then-compact MemoryPersistence (#186); shutdown...
  • See full diff in compare view

Dependabot compatibility score

Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting @dependabot rebase.


Dependabot commands and options

You can trigger Dependabot actions by commenting on this PR:

  • @dependabot rebase will rebase this PR
  • @dependabot recreate will recreate this PR, overwriting any edits that have been made to it
  • @dependabot show <dependency name> ignore conditions will show all of the ignore conditions of the specified dependency
  • @dependabot ignore this major version will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself)
  • @dependabot ignore this minor version will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself)
  • @dependabot ignore this dependency will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)

Bumps [github.com/reearth/ygo](https://github.com/reearth/ygo) from 1.48.0 to 1.50.0.
- [Release notes](https://github.com/reearth/ygo/releases)
- [Changelog](https://github.com/reearth/ygo/blob/main/CHANGELOG.md)
- [Commits](reearth/ygo@v1.48.0...v1.50.0)

---
updated-dependencies:
- dependency-name: github.com/reearth/ygo
  dependency-version: 1.50.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
@dependabot @github

dependabot Bot commented on behalf of github Sep 14, 2026

Copy link
Copy Markdown
Contributor Author

Labels

The following labels could not be found: dependencies, go. Please create them before Dependabot can add them to a pull request.

Please fix the above issues or remove invalid values from dependabot.yml.

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.

0 participants