Skip to content

[BUG] Public Client WebSocket Prevents Node Exit #444

Description

@phroi

Hello folks at CKB DevRel 🤗

I noticed that a Node process using CCC's default public client stays alive after its RPC completes. The client opens a WebSocket but provides no way to close it.

Minimal Reproduction

import { ccc } from "@ckb-ccc/core";

const client = new ccc.ClientPublicTestnet();
await client.getTipHeader();
console.log("done");

And to run it:

timeout 600 node repro.mjs

Behavior

The RPC completes and done prints, but the process remains alive until killed:

done
exit=124 elapsed=600.02

In Node, the default public client selects WebSocket. A successful response clears its request timer and pending entry but leaves the socket open and referenced. Neither the transport nor client exposes close()/dispose(), and there is no idle close.

Environment

  • @ckb-ccc/core@1.17.0
  • Node.js 24.18.0
  • Linux

Impact

A short-lived command can finish its RPC work and print its final output, but still sit until an outer timeout kills it. In CI, cron, or one-shot containers this can turn successful work into a timeout, delay the next run, or cause a supervisor to retry work that already completed.

The problem is more serious when an application creates clients repeatedly. Every used client can leave another WebSocket and file descriptor open. For example, creating one client per second would leave roughly 600 sockets after the ten-minute period reproduced above. Over time this could hit file-descriptor, memory, RPC connection, or upstream endpoint limits. Worker processes multiply the same effect.

Keep up the Great Work 💪
Phroi %48

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't workingenhancementNew feature or requestgood first issueGood for newcomers

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions