-
Notifications
You must be signed in to change notification settings - Fork 602
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
feat(cache/unstable): TtlCache
#5662
Conversation
Codecov ReportAll modified and coverable lines are covered by tests ✅
Additional details and impacted files@@ Coverage Diff @@
## main #5662 +/- ##
==========================================
- Coverage 96.28% 96.25% -0.03%
==========================================
Files 474 475 +1
Lines 38383 38475 +92
Branches 5578 5587 +9
==========================================
+ Hits 36957 37035 +78
- Misses 1384 1398 +14
Partials 42 42 ☔ View full report in Codecov by Sentry. |
Please see #4608 (comment) |
52c7efc
to
3769753
Compare
TtlCache
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
PTAL, @kt3k.
Co-authored-by: Asher Gomez <ashersaupingomez@gmail.com>
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM! Thank you.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM when Asher's point addressed
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
On second thought, I removed [Symbol.toStringTag]()
. We don't implement this anywhere else in std
. Either way, thank you for this PR!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It might be useful to document the valid range for TTL values in this implementation. Because it defers to setTimeout
, this will be implementation-dependent (see the spec), but testing can be performed to inform a suggestion for Deno at least. Here is an example demonstrating that the current build of V8 in Deno only properly handles unsigned 32-bit integers:
settimeout_range.test.ts
:
import { AssertionError } from "jsr:@std/assert@1.0.3/assertion-error";
console.log("Deno.version", Deno.version);
async function assertIntervalIsScheduledAfter1Millisecond(
interval: number,
): Promise<void> {
let timestamp: number | undefined;
const expectedTimeStamp = Date.now() + interval;
const timerId = setTimeout(() => {
timestamp = Date.now();
}, interval);
await new Promise((resolve) => setTimeout(resolve, 1));
if (timestamp) {
throw new AssertionError(
`The callback completed ${
expectedTimeStamp - Date.now()
} ms earlier than expected.`,
);
}
clearTimeout(timerId);
}
Deno.test("setTimeout(): Schedules intervals…", async (t) => {
await t.step(
"less than 2 ** 31",
() => assertIntervalIsScheduledAfter1Millisecond(2 ** 31 - 1),
);
await t.step(
"greater than or equal to 2 ** 31",
() => assertIntervalIsScheduledAfter1Millisecond(2 ** 31),
);
});
Test output:
% deno test settimeout_range.test.ts
------- pre-test output -------
Deno.version { deno: "1.46.1", v8: "12.9.202.2-rusty", typescript: "5.5.2" }
----- pre-test output end -----
running 1 test from ./settimeout_range.test.ts
setTimeout(): Schedules intervals… ...
less than 2 ** 31 ... ok (3ms)
greater than or equal to 2 ** 31 ... FAILED (1ms)
setTimeout(): Schedules intervals… ... FAILED (due to 1 failed step) (4ms)
ERRORS
setTimeout(): Schedules intervals… ... greater than or equal to 2 ** 31 => ./settimeout_range.test.ts:34:10
error: AssertionError: The callback completed 2147483647 ms earlier than expected.
throw new AssertionError(
^
at assertIntervalIsScheduledAfter1Millisecond (file:///Users/deno/settimeout_range.test.ts:18:9)
at eventLoopTick (ext:core/01_core.js:213:9)
at async innerWrapped (ext:cli/40_test.js:191:5)
at async exitSanitizer (ext:cli/40_test.js:107:27)
at async Object.outerWrapped [as fn] (ext:cli/40_test.js:134:14)
at async TestContext.step (ext:cli/40_test.js:492:22)
at async file:///Users/deno/settimeout_range.test.ts:34:2
FAILURES
setTimeout(): Schedules intervals… ... greater than or equal to 2 ** 31 => ./settimeout_range.test.ts:34:10
FAILED | 0 passed (1 step) | 1 failed (1 step) (5ms)
error: Test failed
* | ||
* @experimental **UNSTABLE**: New API, yet to be vetted. | ||
* | ||
* Automatically removes entries once the configured amount of time elapses. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It might be more clear to use the word "after" (this is the word used in the spec) since the spec doesn't seem to enforce that a runtime must prioritize timer tasks over all other tasks in the event loop — which essentially means that a runtime is free to delay execution of the callback for an unbounded amount of time.
* Automatically removes entries once the configured amount of time elapses. | |
* Automatically removes entries after the configured amount of time elapses. |
@jsejcksn, would you be able to submit a PR containing your suggestions? |
Closes #5669