Skip to content

Test/test java8#2

Open
ninan-nn wants to merge 5 commits into
mainfrom
test/test_java8
Open

Test/test java8#2
ninan-nn wants to merge 5 commits into
mainfrom
test/test_java8

Conversation

@ninan-nn

Copy link
Copy Markdown
Owner

Summary

  • What is changing and why?

Testing

  • Not run (explain why)
  • Unit tests
  • Integration tests
  • e2e / manual verification

Breaking Changes

  • None
  • Yes (describe impact and migration path)

Checklist

  • Linked Issue or clearly described motivation
  • Added/updated docs (if needed)
  • Added/updated tests (if needed)
  • Security impact considered
  • Backward compatibility considered

ninan-nn pushed a commit that referenced this pull request Jun 8, 2026
…ingTtl default

Addresses three bot reviews on PR opensandbox-group#986 head (commit 3f7dddf).

### #1 + #2 — Resource leak: skipped near-expiry sandboxes are now killed

Previously, when ``acquireMinRemainingTtl`` was positive, both
``tryTakeIdle`` and ``reapExpiredIdle`` silently dropped near-expiry idle
entries from store membership but never told the pool, so the live
sandboxes kept running on the server (consuming quota / cost) until their
own TTL elapsed — temporarily exceeding the intended pool size.

Redesigned the store API to surface those IDs to callers:

* New ``TakeIdleResult`` value type carrying ``sandbox_id`` plus a
  ``discarded_alive_sandbox_ids`` list. ``tryTakeIdle(name, minTtl)`` now
  returns it. Already-expired entries (server has reaped them) are
  intentionally excluded — a kill round-trip would be wasted.
* ``reapExpiredIdle(name, now, minTtl)`` now returns the alive evicted IDs
  (same exclusion rule).
* Both Lua scripts now return arrays so the discarded-alive list survives
  the round-trip; the empty-pool fast-path still returns ``nil`` so clients
  can distinguish "nothing to do" cleanly.

Wired into the pool:

* ``SandboxPool.acquire`` (Kotlin) and ``SandboxPoolSync/Async.acquire``
  (Python) call ``_kill_discarded_alive`` on the returned list. Failures
  are logged and swallowed — the primary acquire outcome must not depend
  on a janitor failure.
* ``PoolReconciler.reapExpiredIdle`` routes the returned list through the
  existing ``onDiscardSandbox`` callback, which already triggers a
  best-effort kill (same path used by ``shrinkExcessIdle``).

### #3 — Default no longer breaks existing users with short ``idleTimeout``

A 60s default would fail validation (``acquireMinRemainingTtl <
idleTimeout``) for any pool configured with ``idleTimeout <= 60s``,
silently breaking user code on upgrade. Builder field is now nullable:
``null`` resolves at ``build()`` time to ``min(60s, idleTimeout / 2)``.
This is always strictly less than ``idleTimeout``, so no existing pool
construction breaks. Pass ``Duration.ZERO`` to opt out, or any explicit
positive value to override.

The strict ``< idleTimeout`` validation is retained for explicit user
values so misconfigurations (e.g. ``acquireMinRemainingTtl ==
idleTimeout``) are still caught.

### Tests

* Kotlin ``:sandbox:test`` and ``:sandbox-pool-redis:test`` (with real
  Redis 7 via ``OPENSANDBOX_TEST_REDIS_URL``) — 14/14 in the Redis suite.
* Python ``pytest`` — 197 passed.
* New cases verify, in both languages and both stores: alive entries below
  threshold are surfaced; fully-expired entries are silently dropped;
  ``reapExpiredIdle`` excludes already-expired from the alive list; the
  default scales to ``min(60s, idleTimeout/2)``; explicit ``ZERO`` opts
  out; explicit values still get validated against ``idleTimeout``.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
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