Skip to content

feat: update to MoonBit v0.10.4 / async 0.20.2 and lift the 1000 req/s rate cap - #20

Merged
paveg merged 6 commits into
mainfrom
chore/toolchain-deps-update
Jul 18, 2026
Merged

paveg merged 6 commits into
mainfrom
chore/toolchain-deps-update

Conversation

@paveg

@paveg paveg commented Jul 18, 2026 •

Copy link
Copy Markdown
Owner

Summary

Update the MoonBit toolchain to v0.10.4 and all dependencies to their latest versions,
fix a pre-existing hang in the rate limiter,
and lift its 1000 req/s cap.

The toolchain and moonbitlang/async are tightly coupled and cannot be updated independently:
async 0.20.x requires the moonc v0.10.4 syntax and the new manifest format,
while moonc v0.10.4 rejects the legacy syntax used inside async 0.17.1.
That is why the dependency updates land as a single PR.

Changes

Dependency updates (mechanical)

  • moonbitlang/async 0.17.1 → 0.20.2 / mizchi/tui 0.9.1 → 0.10.0 / moonbitlang/x 0.4.40 → 0.4.46
  • Migrate moon.mod.json to moon.mod (DSL) — auto-migrated by moon fmt; the json form is deprecated under the new toolchain
  • Switch release-please to the generic updater with x-release-please-start-version block annotations in moon.mod
  • Update expect tests for the new core Show format (String tuple elements are no longer quoted)
  • Migrate deprecated APIs: verify~ → trust~ (@tls.TrustedRoot), and Client::new / Server::new → struct-constructor call style.
    --insecure semantics are unchanged (insecure → NoVerification, default → SystemRoot)

Rate limiter (core)

  • fix: resolve a pre-existing hang whenever --rate was set (reproducible in v0.1.9).
    The token filler loops forever, and spawn_bg waits for child tasks by default,
    so with_task_group never returned once the test finished.
    The filler is now spawned with no_wait=true, making it an auxiliary task the group cancels on termination
  • feat: support rates above 1000 req/s via batch token emission.
    @async.sleep has millisecond resolution, so the previous one-token-per-sleep filler topped out at ~1000 tokens/s.
    The filler now computes how many tokens are due at the current instant against the absolute schedule and emits them as a batch,
    keeping exact long-run pacing for any rate

Verification

  • moon test --target native 256/256, moon test (wasm-gc) 187/187
  • End-to-end against the built-in server: -d 3s -r 3000 measured 3000.13 req/s (9,006 requests); -r 100 measured 100.40 req/s
  • Confirmed the -n+-r and -d+-r hangs are gone by comparing the new binary against the v0.1.9 release binary
  • TUI rendering and terminal restore verified under a pty with tui 0.10.0
  • Reviewed by a separate spec-review agent (0 critical findings; the single consistency finding was addressed in b689970)

Notes

A pre-existing display bug was found during this work and is intentionally out of scope for this PR:
format_us_as_ms drops the leading zero of the fractional part, rendering 80µs as "0.8ms" instead of "0.08ms" (src/lib/reporter/format.mbt).
A follow-up PR will address it.

🤖 Generated with Claude Code

paveg and others added 6 commits July 19, 2026 05:53
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Requires MoonBit toolchain v0.10.4+ (async 0.20.x uses new language
syntax and the moon.mod manifest format).

- migrate moon.mod.json to moon.mod (auto-migrated by moon fmt; the
  json form is deprecated and removed by the new toolchain)
- switch release-please to the generic updater with
  x-release-please-version block annotations in moon.mod
- update expect tests for the new core Show format (String tuple
  elements are no longer quoted)

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
- verify flag is deprecated in favor of trust (@tls.TrustedRoot);
  --insecure now maps to NoVerification, default to SystemRoot
- Client::new / Server::new are deprecated aliases; use the
  struct-constructor call style
- moon fmt migrated is-main to pkgtype(kind: "executable")

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
The filler task loops forever, and spawn_bg waits for child tasks by
default, so with_task_group never returned once a rate limit was set:
every run with --rate hung after the test finished (duration mode) or
after the request count was reached. spawn_bg(no_wait=true) marks the
filler as an auxiliary task that the group cancels on termination.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…ission

@async.sleep has millisecond resolution, so a one-token-per-sleep filler
tops out at ~1000 tokens/s. The filler now computes how many tokens are
due at the current instant against the absolute schedule and emits them
as a batch, keeping exact long-run pacing for any rate (verified at
3000 req/s end-to-end: 9006 requests over 3s).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@changeset-bot

changeset-bot Bot commented Jul 18, 2026

Copy link
Copy Markdown

⚠️ No Changeset found

Latest commit: b689970

Merging this PR will not cause a version bump for any packages. If these changes should not result in a new version, you're good to go. If these changes should result in a version bump, you need to add a changeset.

Click here to learn what changesets are, and how to add one.

Click here if you're a maintainer who wants to add a changeset to this PR

@paveg
paveg merged commit 8fbb433 into main Jul 18, 2026
4 checks passed
@paveg
paveg deleted the chore/toolchain-deps-update branch July 18, 2026 21:27
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