diff options
author | 2023-08-10 15:25:52 -0700 | |
---|---|---|
committer | 2023-08-10 15:25:52 -0700 | |
commit | 85b81624dcc17339fc6f160e210a12b071a99c3d (patch) | |
tree | b047d46cf62db6925256390ef9b85495fc421516 | |
parent | cf12d80f5eab9989d01aa61c88aba326ce5fe71f (diff) | |
download | bun-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>
-rw-r--r-- | src/bun.js/api/bun.zig | 19 |
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( |