Skip to content

Commit 21e4653

Browse files
committed
chore: pin bun to an exact version above the known-bad range
Bun's node:http client occasionally drops the terminating chunk of an empty chunked HTTP response. When that happens a ClickHouse read never completes, and the client's request_timeout cannot rescue it: that timeout is implemented with socket.setTimeout, which Bun's node:http client ignores. The call hangs forever rather than failing. Measured against a real clickhouse-server:24.8 with bursts of zero-row queries through @clickhouse/client: about 1% of bursts hang on 1.3.9, and none on 1.3.12 or later (0 in 16000 queries on both 1.3.12 and 1.3.14). This is what had been intermittently hanging the ClickHouse schema integration tests in CI at bun's 5000ms per-test timeout. CI already ran 1.3.12 and was therefore already unaffected, but nothing said that the pin was load-bearing, and the other pins had drifted: publish.yml was still on 1.3.9, the images used the floating oven/bun:1.3 tag, and the research compose file ran the archive forwarder on bun 1.2. The runtime version of the service that reads and writes ClickHouse continuously was consequently decided by image build date. Pin every workflow and image to 1.3.14 — the newest 1.3.x, which is what the floating tag resolves to today, so no image is downgraded — and state the constraint at each pin site, since it is invisible from the code. Verified: 30 consecutive runs of the ClickHouse schema integration suite on 1.3.14 against a persistent instance, all green; oven/bun:1.3.14 pulls and runs; every touched YAML parses; bun run check, check:server-lines and typecheck:sidecar all pass.
1 parent 2c96e60 commit 21e4653

8 files changed

Lines changed: 54 additions & 8 deletions

File tree

.github/workflows/archive-live-smoke.yml

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,13 @@ jobs:
2121
- name: Install Bun
2222
uses: oven-sh/setup-bun@v1
2323
with:
24-
bun-version: 1.3.12
24+
# Pinned, not floating: bun <= 1.3.9 can drop the terminating chunk of
25+
# an empty chunked HTTP response, which hangs a ClickHouse read
26+
# forever. request_timeout cannot rescue it — the client implements
27+
# that with socket.setTimeout, which Bun's node:http client ignores.
28+
# Measured at ~1% of query bursts on 1.3.9 and zero on 1.3.12 and
29+
# later, so keep this at 1.3.12 or above.
30+
bun-version: 1.3.14
2531

2632
- name: Install dependencies
2733
run: bun install

.github/workflows/ci.yml

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,13 @@ jobs:
3535
- name: Install Bun
3636
uses: oven-sh/setup-bun@v1
3737
with:
38-
bun-version: 1.3.12
38+
# Pinned, not floating: bun <= 1.3.9 can drop the terminating chunk of
39+
# an empty chunked HTTP response, which hangs a ClickHouse read
40+
# forever. request_timeout cannot rescue it — the client implements
41+
# that with socket.setTimeout, which Bun's node:http client ignores.
42+
# Measured at ~1% of query bursts on 1.3.9 and zero on 1.3.12 and
43+
# later, so keep this at 1.3.12 or above.
44+
bun-version: 1.3.14
3945

4046
- name: Install dependencies
4147
run: bun install

.github/workflows/publish.yml

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,13 @@ jobs:
3535
- name: Install Bun
3636
uses: oven-sh/setup-bun@v1
3737
with:
38-
bun-version: 1.3.9
38+
# Pinned, not floating: bun <= 1.3.9 can drop the terminating chunk of
39+
# an empty chunked HTTP response, which hangs a ClickHouse read
40+
# forever. request_timeout cannot rescue it — the client implements
41+
# that with socket.setTimeout, which Bun's node:http client ignores.
42+
# Measured at ~1% of query bursts on 1.3.9 and zero on 1.3.12 and
43+
# later, so keep this at 1.3.12 or above.
44+
bun-version: 1.3.14
3945

4046
- name: Setup Node.js for npm publishing
4147
uses: actions/setup-node@v4

.sandbox/Dockerfile

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,10 @@
1-
FROM oven/bun:1.3
1+
# Pinned to an exact patch, not the floating 1.3 tag: bun <= 1.3.9 can drop the
2+
# terminating chunk of an empty chunked HTTP response, which hangs a ClickHouse
3+
# read forever. request_timeout cannot rescue it — the client implements that
4+
# with socket.setTimeout, which Bun's node:http client ignores. Measured at ~1%
5+
# of query bursts on 1.3.9 and zero on 1.3.12 and later, so keep this at 1.3.12
6+
# or above.
7+
FROM oven/bun:1.3.14
28

39
WORKDIR /app
410

Dockerfile

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,10 @@
1-
FROM oven/bun:1.3
1+
# Pinned to an exact patch, not the floating 1.3 tag: bun <= 1.3.9 can drop the
2+
# terminating chunk of an empty chunked HTTP response, which hangs a ClickHouse
3+
# read forever. request_timeout cannot rescue it — the client implements that
4+
# with socket.setTimeout, which Bun's node:http client ignores. Measured at ~1%
5+
# of query bursts on 1.3.9 and zero on 1.3.12 and later, so keep this at 1.3.12
6+
# or above.
7+
FROM oven/bun:1.3.14
28

39
WORKDIR /app
410

docker/clickhouse-research.compose.yml

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,10 @@ services:
2020
# host `bun install`. For a standalone prod image build
2121
# services/archive-forwarder/Dockerfile instead (self-contained, no mount).
2222
archive-forwarder:
23-
image: oven/bun:1.2
23+
# Same bun floor as the production images: bun <= 1.3.9 can drop the
24+
# terminating chunk of an empty chunked HTTP response and hang a ClickHouse
25+
# read forever, and this runs the real forwarder against ClickHouse.
26+
image: oven/bun:1.3.14
2427
container_name: cex-broker-archive-forwarder
2528
working_dir: /app
2629
command: ["bun", "run", "services/archive-forwarder/index.ts"]

services/archive-forwarder/Dockerfile

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,14 @@
55
#
66
# Build from the repository ROOT so the schema/ directory is in the build context:
77
# docker build -f services/archive-forwarder/Dockerfile -t cex-broker-archive-forwarder .
8-
FROM oven/bun:1.3
8+
# Pinned to an exact patch, not the floating 1.3 tag: bun <= 1.3.9 can drop the
9+
# terminating chunk of an empty chunked HTTP response, which hangs a ClickHouse
10+
# read forever. request_timeout cannot rescue it — the client implements that
11+
# with socket.setTimeout, which Bun's node:http client ignores. This service
12+
# reads and writes ClickHouse continuously, so it is the most exposed. Measured
13+
# at ~1% of query bursts on 1.3.9 and zero on 1.3.12 and later, so keep this at
14+
# 1.3.12 or above.
15+
FROM oven/bun:1.3.14
916

1017
WORKDIR /app
1118

services/ohlcv-collector/Dockerfile

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,13 @@
99
# Set CEX_BROKER_URL=host:port and mount the canonical feed configuration named
1010
# by CEX_BROKER_MARKET_DATA_COLLECTOR_CONFIG. The legacy OHLCV array variable is
1111
# retained for compatibility.
12-
FROM oven/bun:1.3
12+
# Pinned to an exact patch, not the floating 1.3 tag: bun <= 1.3.9 can drop the
13+
# terminating chunk of an empty chunked HTTP response, which hangs a ClickHouse
14+
# read forever. request_timeout cannot rescue it — the client implements that
15+
# with socket.setTimeout, which Bun's node:http client ignores. Measured at ~1%
16+
# of query bursts on 1.3.9 and zero on 1.3.12 and later, so keep this at 1.3.12
17+
# or above.
18+
FROM oven/bun:1.3.14
1319

1420
WORKDIR /app
1521

0 commit comments

Comments
 (0)