aboutsummaryrefslogtreecommitdiff
path: root/src/bun.js/api/bun.zig
diff options
context:
space:
mode:
authorGravatar Jarred Sumner <jarred@jarredsumner.com> 2023-08-10 15:25:52 -0700
committerGravatar GitHub <noreply@github.com> 2023-08-10 15:25:52 -0700
commit85b81624dcc17339fc6f160e210a12b071a99c3d (patch)
treeb047d46cf62db6925256390ef9b85495fc421516 /src/bun.js/api/bun.zig
parentcf12d80f5eab9989d01aa61c88aba326ce5fe71f (diff)
downloadbun-85b81624dcc17339fc6f160e210a12b071a99c3d.tar.gz
bun-85b81624dcc17339fc6f160e210a12b071a99c3d.tar.zst
bun-85b81624dcc17339fc6f160e210a12b071a99c3d.zip
Handle thundering herd of setInterval (#4109)
Co-authored-by: Jarred Sumner <709451+Jarred-Sumner@users.noreply.github.com>
Diffstat (limited to 'src/bun.js/api/bun.zig')
-rw-r--r--src/bun.js/api/bun.zig19
1 files changed, 17 insertions, 2 deletions
diff --git a/src/bun.js/api/bun.zig b/src/bun.js/api/bun.zig
index fe0aafc25..d2349ce2b 100644
--- a/src/bun.js/api/bun.zig
+++ b/src/bun.js/api/bun.zig
@@ -3597,9 +3597,14 @@ pub const Timer = struct {
break :brk true;
}
} else {
- if (map.get(this.id)) |tombstone_or_timer| {
+ if (map.getPtr(this.id)) |tombstone_or_timer| {
+ // Disable thundering herd of setInterval() calls
+ if (tombstone_or_timer.* != null) {
+ tombstone_or_timer.*.?.has_scheduled_job = false;
+ }
+
// .refresh() was called after CallbackJob enqueued
- break :brk tombstone_or_timer == null;
+ break :brk tombstone_or_timer.* == null;
}
}
@@ -3869,6 +3874,7 @@ pub const Timer = struct {
did_unref_timer: bool = false,
poll_ref: JSC.PollRef = JSC.PollRef.init(),
arguments: JSC.Strong = .{},
+ has_scheduled_job: bool = false,
pub const Kind = enum(u32) {
setTimeout,
@@ -3906,6 +3912,12 @@ pub const Timer = struct {
var globalThis = this.globalThis;
+ // Disable thundering herd of setInterval() calls
+ // Skip setInterval() calls when the previous one has not been run yet.
+ if (repeats and this.has_scheduled_job) {
+ return;
+ }
+
var cb: CallbackJob = .{
.callback = if (repeats)
JSC.Strong.create(
@@ -3950,6 +3962,9 @@ pub const Timer = struct {
this.arguments = .{};
map.put(vm.allocator, timer_id.id, null) catch unreachable;
this.deinit();
+ } else {
+ this.has_scheduled_job = true;
+ map.put(vm.allocator, timer_id.id, this) catch {};
}
var job = vm.allocator.create(CallbackJob) catch @panic(