Files
bun.sh/test/js/bun/http/bun-serve-date.test.ts
Jarred Sumner 7b31393d44 Don't run the "Date" header timer every second all the time (#21850)
### What does this PR do?

Only reschedule the Date header while there are in-flight incoming HTTP
requests.

Update the Date header if, at the time we reschedule it, it is now
stale.

Goal: don't wake up Bun's process on every second when we're idly doing
nothing.

| Metric | this branch | main |
|--------|--------------------------|-------------------|
| **task-clock** | **35.24 msec** 🟢 | **102.79 msec** |
| **context-switches** | 619 🟢 | 1,699 |
| **cpu-migrations** | 11 🟢| 35 |
| **page-faults** | 2,173 | 2,174 |
| **cpu_atom/instructions** | **109,904,685 (1.76 insn/cycle)** 🟢 |
**67,880,002 (0.55 insn/cycle)** |
| **cpu_core/instructions** | **87,183,124 (1.07 insn/cycle)** 🟢 |
**32,939,500 (0.44 insn/cycle)** |
| **cpu_atom/cycles** | 62,527,125 (1.774 GHz) 🔻 | 122,448,620 (1.191
GHz) |
| **cpu_core/cycles** | 81,651,366 (2.317 GHz) 🟢 | 75,584,111 (0.735
GHz) |
| **cpu_atom/branches** | 9,632,460 (273.338 M/sec) 🔻 | 12,119,616
(117.909 M/sec) |
| **cpu_core/branches** | 17,417,756 (494.259 M/sec) 🟢 | 6,901,859
(67.147 M/sec) |
| **cpu_atom/branch-misses** | 192,013 (1.99%) 🟢 | 1,735,446 (14.32%) |
| **cpu_core/branch-misses** | 473,567 (2.72%) 🟢 | 499,907 (7.24%) |
| **TopdownL1 (cpu_core)** | 31.4% backend_bound<br>11.7%
bad_speculation<br>36.0% frontend_bound 🔻<br>20.9% retiring<br>34.1%
bad_speculation<br>41.9% retiring<br>0.0% backend_bound<br>24.0%
frontend_bound 🔻 | 21.3% backend_bound<br>9.6% bad_speculation<br>56.2%
frontend_bound<br>12.9% retiring<br>-20.0% bad_speculation<br>55.2%
retiring<br>26.2% backend_bound<br>38.6% frontend_bound |
| **time elapsed** | 1000.0219 s | 1000.0107 s |
| **user time** | — | 0.042667 s |
| **sys time** | — | 0.060309 s |

### How did you verify your code works?

Added a test

---------

Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
2025-08-14 15:39:09 -07:00

56 lines
1.7 KiB
TypeScript

import { expect, test } from "bun:test";
test("Date header is not updated every request", async () => {
const twoSecondsAgo = new Date(Date.now() - 2 * 1000);
await using server = Bun.serve({
port: 0,
fetch() {
return new Response("OK");
},
});
// Make multiple requests in quick succession
const responses = await Promise.all([
fetch(server.url),
fetch(server.url),
fetch(server.url),
fetch(server.url),
fetch(server.url),
]);
// All responses should have the same Date header since they were made within the same second
const dates = responses.map(r => r.headers.get("Date"));
const uniqueDates = new Set(dates);
// Should only have 1 unique date value since all requests were made rapidly
expect(uniqueDates.size).toBe(1);
expect(dates[0]).toBeTruthy();
for (const delay of [250, 250, 250, 250, 250]) {
await Bun.sleep(delay);
const laterResponses = await Promise.all([
fetch(server.url),
fetch(server.url),
fetch(server.url),
fetch(server.url),
fetch(server.url),
]);
const laterDates = laterResponses.map(r => r.headers.get("Date"));
const laterUniqueDates = new Set(laterDates);
expect(laterUniqueDates.size).toBe(1);
uniqueDates.add([...laterUniqueDates][0]);
}
// There should only really be two, but I don't trust timers to be SUPER accurate.
expect(uniqueDates.size).toBeLessThan(4);
for (const date of [...uniqueDates]) {
const d = new Date(date!);
const stamp = d.getTime();
expect(Number.isFinite(stamp)).toBe(true);
expect(stamp).toBeGreaterThan(0);
expect(stamp).toBeGreaterThan(twoSecondsAgo.getTime());
expect(stamp).toBeLessThan(Date.now() + 100);
}
});