Repository navigation
Conversation
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
There was a problem hiding this comment.
All reported issues were addressed across 6 files
Reply with feedback, questions, or to request a fix.
View guided diff | Turn on auto-fix | Re-trigger cubic
thymikee
left a comment
There was a problem hiding this comment.
Request changes.
- (a) Holds: allocate validates each caller before joining; rent publishes the owner before its start microtask, so joiners observe the same creation without inheriting caller validation errors.
- (b) Holds: release/shutdown call the same owner.end; a late create after the 120s budget re-enters end, records rent, and stops once. Evidence: lease-owner.test.ts pending-create release/shutdown case.
- (c) Holds: create and stop waits are bounded (120s/30s); uncertain stop remains stop-failed with the stop promise retained for retry. All disposal provider calls are behind start/readiness budgets or the bounded stop wait.
- (d) Holds: startDevice uses POST and Revyl client defaults retries only GET; start has one attempt on unknown outcome.
- (e) Holds: startRevylSession calls recordRent immediately after start_device returns, before readiness polling.
- (f) Holds: ready allocation reads entry.session and returns synchronously before any await.
- (g) Holds: shutdown gathers outcomes from this runtime instance's own lease map.
- (h) Not independently verified here: eager-closure guard was not run. PR body reports 882 passing.
- Finding [P1]: packages/provider-revyl/src/runtime.ts:149 — hasLiveSession/getInteractor still expose the session once shutdown begins and while release is stopping or stop-failed. These read paths use sessionForDevice without either guard, so callers can continue binding/dispatching against a device being disposed. Refuse access when shuttingDown or the lease owner is releasing, and add stopping/stop-failed coverage.
- Tests: provider-revyl focused unit suite passed once (147). New lifecycle assertions fail on base: base returns allocation after concurrent release, while head rejects it as provider-lease-releasing. Unit evidence supports the local ownership races but not live provider behavior; the live run got HTTP 401 and created zero sessions, so live device behavior remains unverified.
Size Report
Startup median (7 runs, lower is better):
|
thymikee
left a comment
There was a problem hiding this comment.
Independent review at head 1f1ae76b279fff1db30e0554958ebc8a30c941cc; merge-base a0e7c7dc239922bf93adaceff20a2f7e78579146.
Verdict: no actionable code regressions found. The owner-local RevylLeaseState union has one transition owner (RevylLeaseOwner), and a lease in stopping or stop-failed cannot supply a ready device.
Checklist, with concrete traces (paths below are under packages/provider-revyl/src/):
- (a) Holds.
runtime.ts:200-242validates each caller synchronously, checks request compatibility, and publishes the owner without awaiting.lease-owner.ts:60-76defers creation to a microtask, which runs after publication. Thus A's invalid profile fails before an owner exists; valid B starts independently. If A is already starting, B's incompatible profile fails in B's call without poisoning A's shared creation. - (b) Holds. Release or shutdown calls
end(), which synchronously replaces starting/ready with stopping and shares one disposal promise (lease-owner.ts:117-145). Disposal waits for creation before stopping the returned identity. If creation exceeds 120 seconds, it reports uncertainty, retains the owner, and installs a late continuation that re-entersend(). Concurrent release/recovery/shutdown and the failed-start continuation join the same stopping owner.lease-owner.test.ts:98-138covers both release and shutdown crossing that budget, a late successful create, and one stop;runtime.test.ts:273-288,397-427covers shared disposal and stop-after-create ordering. Exactly-once here means one shared logical stop attempt; failed confirmed attempts can be retried, and the HTTP client can retry the idempotent stop. - (c) Holds for owner disposal. Creation and stop are wrapped by independent 120-second and 30-second waits (
lease-owner.ts:138-177,216-228), including a transport promise that ignores abort. An unanswered stop enters stop-failed withcleanup: 'uncertain'and its pending stop handle. A retry joins that handle; late confirmation closes/removes the owner, while late failure leaves it available for a new attempt. A settled refused stop also retains the owner. Release propagates uncertainty instead of reporting success (runtime.ts:289-296). The separate restart-recovery path uses the existing HTTP client's finite per-attempt timeout/retry count (revyl-client.ts:106-119,228-239). - (d) Holds.
startDeviceis a POST without retry opt-in (revyl-client.ts:152-159);sendtherefore permits exactly one attempt (106-110). This is the provider's own fetch client, with no SDK retry layer. Unknown create outcomes carry the deterministic session identity into cleanup rather than issuing another create. Stop retries are explicitly idempotent and do not retry creation. - (e) Holds. Immediately after the create result returns,
revyl-session.ts:123-127parses the remote run/session identity and callsrecordRent, before identity checks or any readiness await. The owner records it in starting/stopping, or updates the uncertain identity in stop-failed (lease-owner.ts:106-110). - (f) Holds. Existing-ready allocation follows
runtime.ts:207-230without an await. A starting allocation does await creation, then re-readsentry.sessionbefore answering; if release overtook that wait, the getter supplies no session and allocation fails withprovider-lease-releasing. - (g) Holds by source trace. Each runtime constructs its own leases map and shutdown flag (
runtime.ts:96-100); shutdown aggregates failures only from that map (167-177). Plugin cleanup invokes and captures each registration's shutdown separately (packages/plugins/src/registry.ts:182-191,325-342). No module-global warning accumulator or cross-instance lease state was introduced. - (h) Holds. I compared the production eager-import walker at merge-base and head for all 437 measured entries: zero changed closure module sets. The new runtime imports remain behind the existing function-scoped plugin setup seam.
hasLiveSession and getInteractor both go through sessionForDevice (runtime.ts:149-157,312-316). The owner getter exposes a session only in ready (lease-owner.ts:98-103). Therefore both refuse during stopping and stop-failed; inventory also returns null. The new test exercises immediate retirement and post-failure refusal.
Validation: install/build passed; the single permitted provider test invocation, pnpm exec vitest run --project unit-core packages/provider-revyl, passed all 147 tests in 11 files. Reviewed source remains clean. I did not run further tests or wait for CI.
Base sensitivity: the PR reports five executed base-red regressions. I independently checked their failure traces against the base sources, but did not execute a second suite under the one-run limit: the immediate-retirement test fails because base still exposes the session; release before the first allocation await misses base's unpublished entry and allocation succeeds; both late-create budget cases fail because base waits indefinitely for start; the unanswered-stop case fails because base has no outer disposal budget. These are source-checked counterfactuals, not an independently reproduced base-red run. The bot's proposed extra stop assertion in the immediate-publication test is optional strengthening: other tests already assert the stop count and stop-after-create ordering, while that test specifically detects admission before the first await.
The unit evidence is sufficient to support this scoped in-memory ownership/lifecycle fix. It is not sufficient to claim live Revyl allocation, device commands, or remote release were verified. The reported HTTP 401 / zero-created-session run exercises authentication refusal only; successful provider integration and live cleanup remain unverified. CI was still pending when inspected and is not counted as passed evidence here.
|
Addressed r4441116491 at |
Apex SentinelVerdict: Since the last review: 4 new · 0 still open · 5 no longer raised 4 finding(s): 4 nit. Verdict: approve. reached max rounds (1). 🔵 Nit (4)
Reply under an inline comment with |
There was a problem hiding this comment.
Apex Sentinel: 5 new findings on 240b050. The verdict and the full list are in the summary comment.
|
Final round at |
There was a problem hiding this comment.
Apex Sentinel: 4 new findings on a8ebe1f. The verdict and the full list are in the summary comment.
|
Thanks for the work here. I found two lifecycle defects at a8ebe1f, and the change still needs live Revyl evidence. CI is green: 21 checks pass and none fail. There are no conflicts. Before merge, the two defects need fixes and the live run needs to be attached. I read the code only. I did not run the tests or reach Revyl, and both defects are traced from code, not reproduced. A failed start's stop is no longer bounded by the caller's patience. At base,
This change rewrites allocate, release, recovery, shutdown and when the interactor is handed out, so it needs live validation. The only live attempt returned HTTP 401 'Invalid API key' with zero sessions, so no changed route ran against Revyl. Please run with a valid key at the final head and attach output for three routes. First, connect to ready, run one device command, then disconnect. The output should show release data with Can this PR land first without a second Revyl-only lifecycle owner beside the shared one? #4158 already moves the same bookkeeping into Not blocking, and fine to take or leave: On the earlier review threads: the one on |
Summary
Revyl kept handing out devices after release started or failed. One lease owner now makes starting, ready, stopping, stop-failed and closed explicit. It retires admission synchronously, shares bounded disposal, retains uncertain cleanup for retry, and disposes late creates once.
Seven files; scope stays within Revyl lifecycle, adjacent tests and its guide. Related: #4102; follows #4130 and #4141. Eager closure is preserved.
Final review round derives disposal's stop budget from the HTTP client's full retry budget plus a margin, preserves typed retirement when a waiting caller gives up, and caches ready-session reuse. Field and callback-signature nits are explained in their threads.
Validation
Base
a0e7c7dc239922bf93adaceff20a2f7e78579146; heada8ebe1f45f164249fc8d4a04221000ab1dd9d180; previous reviewed head240b05012f6895ea90406d974c80102b94745903.pnpm check:affected --run --head HEADpassed: receiptrun-trpcM0,exactCommit=true,checkoutChanged=false; 16,972 unit tests passed, one skipped. Full-repository format passed.Invalid API key: one rejected create, zero sessions created. Command/release/listing were blocked. Host cleanup had no pending/unknown releases; private-state daemon stop reported known cleanup with no warnings. No new live run this round.