Commit Graph
10 Commits
Author SHA1 Message Date
Chris Tate 26e458932e Poll the checker server's socket before a reply read blocks
The native compiler sends most checker requests one at a time and blocks
in recv for each reply. The server answers most of them in a few
microseconds, and a reader the reply wakes takes tens of microseconds more
per round trip, over about 130,000 round trips on a large program.

scriptc_ts7_read now polls the socket with MSG_DONTWAIT for up to 200 us
before it blocks. Windows keeps its blocking pipe read.
2026-10-28 23:39:17 -05:00
Chris Tate 3b374f3201 Check with the shared tsc-ts server by default on Linux and macOS
Builds on Linux and macOS now connect to a shared `tsc-ts --api --listen`
server by default, which keeps the files it parsed and bound, so a later
build in the same working directory does not parse the TypeScript libs and
scriptc's declaration files again. SCRIPTC_CHECKER_SERVER=0 turns it off.
When CI is set to a value other than 0 or false, builds use their own tsc-ts
process unless SCRIPTC_CHECKER_SERVER=1.

- The server exits after 600 seconds without a build (was 300).
- Its name also digests the compiler executable's identity, so each scriptc
  installation and build connects only to servers it started.
- The server process runs in the root directory, so it does not keep the
  first build's directory in use; its --cwd argument is unchanged.
- When the connection to the server fails after it answered, through a
  failed transfer or an ended stream, the native CLI runs the command again
  in a new process with SCRIPTC_CHECKER_SERVER=0 and exits with its status.
- SCRIPTC_CHECKER_SERVER no longer changes the frontend cache key: the
  server's answers are the build's own checker's.

The CLI docs describe the background process, its socket directory, when it
exits and how to stop it.
2026-10-27 08:21:48 -05:00
Chris Tate 24ef53ac23 Have tsc-ts read its library files from disk when it can
Every file tsc-ts reads goes through scriptc's file system callbacks,
including the ~80 files of tsc-ts's own default library directory: one
round trip from the checker to the compiler and back for each. Those
files belong to the installed tsc-ts (the build caches key on its
executable's identity), and no build serves them differently.

When tsc-ts takes --default-libraries-from-disk, the native compiler
passes it to the checker it starts and to the shared checker server, so
tsc-ts reads those files itself; every other path keeps the callbacks.
Released tsc-ts versions reject the flag, so checker-features.ts asks
each tsc-ts executable once (tsc-ts --api --default-libraries-from-disk
with an empty input exits with 0 only when it knows the flag) and keeps
the answer in the native cache, keyed by the executable's identity. With
a tsc-ts that does not know the flag, builds run as before.

Edit builds of small programs through the shared checker server are
about 18 ms faster, and 6-9 ms faster without it.
2026-10-25 06:32:18 -05:00
Chris Tate f26cc427c2 Merge main 2026-10-24 18:51:06 -05:00
Chris Tate 924fc1055c Find checker reply element ends in C and list dynamic imports from module references (#1885) 2026-10-24 18:34:58 -05:00
Chris Tate 05bc5299b0 Reap the checker process within a millisecond of closing it
Closing a checker process checked for its exit once and then slept 10 ms
before checking again, although the process exits a fraction of a
millisecond after its input closes. The checks now start 0.1 ms apart and
double, so the process is reaped as soon as it exits. The total wait before
the kill stays at about 50 ms (51.1 ms).
2026-10-24 17:54:15 -05:00
Chris Tate c0a4496900 Check with a tsc-ts server shared by later builds (opt-in)
With SCRIPTC_CHECKER_SERVER=1 on Linux and macOS, the native compiler's
checker connections go to a shared `tsc-ts --api --listen` server, which
keeps the files it parsed for the next build. When the variable is unset,
nothing changes.

checkerServerName names the server by a digest of the tsc-ts executable's
identity, the working directory, the file system callbacks, the timing
flag and the TSC_TS_* environment. scriptc_ts7_attach takes the server's
lock file with a non-blocking flock, connects to its socket in this
user's private server directory ($XDG_RUNTIME_DIR/scriptc or
/tmp/scriptc-<uid>), and starts the server when none answers: in its own
process group, with its standard streams on /dev/null and no other
descriptor of the build, with --idle-exit 300 and TSC_TS_LISTEN_MEMORY=2048
unless the environment sets it. A build that finds the server in use,
cannot start or reach it, or gets no answer to a ping checks with its own
tsc-ts process, as without the variable; so does a tsc-ts without
--listen, which exits as it starts. The syntax-only source parser, which
reads no libraries, always uses its own process and leaves the server to
the program's checker.
2026-10-24 17:50:45 -05:00
Chris Tate 5e7338ad2c Scan checker reply strings with many escapes in one pass
scriptc_ts7_json_value_end searched for the next quote again after each
backslash escape in a string, so a string with many escapes was scanned
once per escape. The quote it found now stays the candidate end until an
escape skips it, and each byte of a string is scanned once by each
search.

A test scans strings of 2,000,000 newline, backslash and quote escapes,
alone and inside an object, and compares the ends with jsonValueEnd's;
before the change it does not finish within 60 s.
2026-10-24 15:56:52 -05:00
Chris Tate a3b9cfb146 Find checker reply element ends in C and list dynamic imports from module references 2026-10-22 18:51:14 -05:00
Chris Tate 806b96d32b feat(compiler): own the TypeScript server from native clients
- Launch and manage TypeScript server processes through a portable native FFI boundary.
- Share the production session API between Node and statically compiled clients.
- Preserve Unicode command-line arguments and release server resources on every exit path.
2026-09-28 09:54:18 -05:00