Lane

class Lane(val name: String, val liveProbe: LiveProbe) : ExecLane

One execution lane: a tick source (a game method a Mixin injects at RETURN — the "heartbeat") whose every fire steps the lane's active evals once, on that source's own thread, so a step has exclusive access to that side's game state. Three lanes exist (Lanes): server (server tick), client (client tick), render (render frame) — identical machinery, different heartbeat.

Readiness is asked, never timed: a LiveProbe answers from the physical side and from the tick source itself, so a stall is not death — a paused game, an autosave or a slow /tick rate stays ready — and a source that really has stopped says so at once, with no window in which a submission can join a queue nothing will pump again. A remote-connected client has no local MinecraftServer, so its server lane is simply not ready.

An eval is reaped for exactly ONE reason: its heartbeat will never fire again, which would hang the caller blocked on its future. A world unload, a dimension change, a server switch all leave the heartbeat firing, so the eval keeps stepping and ends on its own terms — finish, throw, watchdog, or cancel. That one boundary can't be seen by the stopped pump itself, so it arrives from outside as reapOnStop (MinecraftServer#stopServer; onDisable on Paper). Client and render have none short of JVM exit.

Constructors

Link copied to clipboard
internal constructor(name: String, liveProbe: LiveProbe)

Properties

Link copied to clipboard
Link copied to clipboard

Advanced only by reapOnStop; offerOrReap compares against it to kill a straggler still compiling when the heartbeat stopped for good.

Link copied to clipboard
open override val isReady: Boolean
Link copied to clipboard
private val liveProbe: LiveProbe
Link copied to clipboard
open override val name: String
Link copied to clipboard

Evals stepped this tick that aren't done. Parked out of active for the rest of the pump so the drain loop can't hand a task straight back to itself, then flushed back in stepAll's finally. Reaped and removed alongside active everywhere — an eval parked here is exactly as live as one still queued.

Link copied to clipboard

What the last heartbeat handed in — the MinecraftServer on the server lane, the Minecraft on client/render; null before the first pump. Republished every pump because isReady and run_command read it from the HTTP thread, and both must get a current value on an idle lane too.

Functions

Link copied to clipboard
private fun guardLane(): GuardLane

Which timeout kill-id lane this is: the server lane runs on the Server thread; the client and render lanes share the Render thread → RENDER. Known from the lane name at submit time, so it's baked into the script's inlined GETSTATIC at compile/instrument time (no runtime thread sniffing).

Link copied to clipboard
private fun offerOrReap(t: EvalTask)

Every route into active: the compile-completion handoff on the short-lived compile thread once EvalTask.start finishes compiling, and stepAll's flush of an eval it stepped but didn't finish. Publish the task into active, then re-read the epoch it was bound to at submit. Epoch unchanged: it waits for the next pump. Epoch advanced while it was compiling: it's stale, so pull it back out and kill it here, completing its future — otherwise the blocked caller hangs on a queue that will never be pumped again.

Link copied to clipboard
fun pump(self: Any?)

Pump the lane once per heartbeat fire — called by the lane's Mixin (MixinMinecraftServer / MixinMinecraft) at the tick's RETURN, on that side's own thread. Republishes self as the lane's handle, then steps each active eval once. Public so the mixin (a different package) can call it.

Link copied to clipboard
private fun pumpBody(self: Any?)
Link copied to clipboard
private fun reapAll(reason: String): Long

Kill and drop every active eval. Safe from any thread: drains concurrent queues; kill is idempotent. Two callers: an auth revoke (on the pump thread, which keeps pumping and so self-heals any straggler still compiling), and reapOnStop.

Link copied to clipboard
fun reapOnStop(reason: String): Long

The lane's one terminal boundary, signaled from outside the pump: MinecraftServer#stopServer (Paper: onDisable). Past it the heartbeat never fires again, so every queued eval would hang the request blocked on it — including one still compiling, which will offerOrReap itself into the queue a moment later. Advance the epoch before draining — see offerOrReap for why that pairing strands nothing. Server thread only, and the sole writer of currentEpoch.

Link copied to clipboard
private fun stepAll()

Step every queued eval once, in order, under ONE timeout budget for this tick: they run serially on this one tick thread, so their combined time is what would freeze it. The guard inlined into each script reads this lane's kill-id field, which beginFrame's watchdog writes when the budget elapses (see TimeoutGuard). Drains to empty, so an eval that finishes compiling mid-pump runs this tick instead of waiting out a heartbeat.

Link copied to clipboard
open override fun submit(code: String, beforeStart: (EvalHandle) -> Unit): EvalHandle

Schedule code on this lane. It compiles off the tick, joins the lane once compiled, and is stepped every heartbeat until done. It's bound to the epoch current at submit: if the heartbeat has stopped for good by the time it finishes compiling, it's killed rather than queued forever. The returned EvalHandle carries the result future (callers block on it — block-until-done) and can cancel the eval (the client-initiated notifications/cancelled path).