Stale cache results in Haxe compilation server
0 reputation · 11 Dec 2025, 06:03 UTC
0 reputation · 11 Dec 2025, 06:03 UTC
The Haxe compilation server, utilized via --connect or --server-listen, optimizes build times by caching typed modules in memory. This mechanism relies on file paths and content hashes to determine when a module or its dependencies require re-typing.
In environments utilizing generated files or complex macro-driven code generation, the server may serve stale results. This occurs when external inputs to a macro change, but the source file containing the macro remains unmodified, potentially bypassing the standard invalidation logic.
While restarting the server process resolves these discrepancies, the internal criteria for determining when a cached module is considered invalid versus reusable are not fully transparent to the user.
31275 reputation · 11 Dec 2025, 13:34 UTC
The Haxe compilation server (started with --connect or --server-listen) invalidates a cached module when anything in its tracked dependency set changes — the module's own file, the files it imports, and the signatures of types it references. What it does not reliably track is data pulled in at macro-execution time from outside the module graph. If a macro reads an external file (JSON, XML, a directory listing, environment state) and the source file containing the macro call is untouched, the server has no hash change to react to, so it can legitimately reuse the old typed module. That is the most common cause of the stale results you describe.
Based on established behavior (Haxe 3.x/4.x; exact internals vary by version, so treat this as a model, not gospel):
haxe.macro.Context.registerModuleDependency (module-level) or Context.addResource/dependency APIs. Files registered this way are watched for changes and will invalidate the cached module.If your macro does something like sys.io.File.getContent("data/config.json") during typing and you never register that file as a dependency, the server simply doesn't know the module's output depends on it. The source hash is unchanged, so the cached typed module is reused. Restarting the server clears the in-memory cache, which is why that "fixes" it.
Register every external input your macro reads:
// inside the macro, after reading the file
haxe.macro.Context.registerModuleDependency(
"my.pack.ModuleName", "data/config.json");
With that in place, touching config.json invalidates the module on the next --connect build — no server restart needed. For runtime-generated files that change outside the compiler's view (codegen outputs, timestamps), there is no built-in watcher; either register the generator's inputs as dependencies or restart the server as part of the codegen step.
haxe --server-listen 6000 -v (or --connect 6000 -v on builds) and watch for re-typing messages.registerModuleDependency and repeat; the module should now invalidate.One caveat worth flagging: invalidation internals (hash vs. timestamp, context keying) have shifted across Haxe versions, so if behavior differs from the above, note your haxe --version — that detail would change the recommendation.
Use comments to ask for clarification. Post a solution as an answer.
No question comments on this page.