Stream: platform development

Topic: roc runtime continues using CPU after platform code is done


view this post on Zulip Jasper Woudenberg (Nov 11 2024 at 19:32):

I'm working on a little platform in Zig for static site generation. After it generates the site it starts a webserver to serve it. What surprised me was that the webserving portion was using a significant amount of CPU, even when it was doing nothing while waiting for requests.

At first I thought I was maybe doing something silly like an infinite loop in Zig, but I think it's some Roc internals using the CPU, even though the platform is not doing anything at that time. I was curious if anyone might know what's going on.

I've used samply to get some information on what was happening (I think that was a tip from Brendan at one point? Great tool!). It shows that Roc is spending a lot of time in roc_repl_expect::run::ExpectMemory::wait_for_child(see screenshot below). My constant refreshing to excercise the fileserver doesn't even register, so I really think it's this function that's doing a lot of work for some reason, was wondering if anyone knew why.

screenshot_2024-11-11T20:20:56+01:00.png

I also took a look at the compiler code. I think the expect_child bit it's running is here:
https://github.com/roc-lang/roc/blob/b7c2cb084e15a56320e652ad3c77fdb8262bc1a4/crates/repl_expect/src/run.rs#L540

There is a loop there, so that might explain why I'm seeing a lot of CPU usage, but I'm not sure why I'd end up there. Any expect's would have completed long ago.

Note: I'm running my Roc code as a script using roc run (the platform is designed to work that way).

I'd be grateful for any ideas!

view this post on Zulip Luke Boswell (Nov 11 2024 at 19:42):

Can you build roc from source and use a debug build of the compiler?

view this post on Zulip Luke Boswell (Nov 11 2024 at 19:44):

It seems strange that the repl is even involved at all. But hard to say withiut seeing your setup.

view this post on Zulip Brendan Hansknecht (Nov 11 2024 at 19:46):

The stack trace is in the image

view this post on Zulip Brendan Hansknecht (Nov 11 2024 at 19:46):

Apparently roc_dev_native calls into that

view this post on Zulip Brendan Hansknecht (Nov 11 2024 at 19:46):

Probably a bug

view this post on Zulip Jasper Woudenberg (Nov 11 2024 at 22:18):

Reading the code a bit, I think the call into repl code is intentional. My understanding now: because roc run runs Roc in dev mode we want expects to trigger. We fork to have one process running the actual Roc code, another to do bookkeeping with relation to expects that the first encounters.

This reuses some logic used by the repl, I imagine because the repl splits into a repl process and a compile+run process.

My guess is that the logic that gets expect updates from the child polls the child process in a non-blocking loop, which runs one CPU core as fast as it can. I can take a look at maybe blocking that thread while waiting for child updates.

Another thing I wonder is if it'd be possible/valuable to combine these in a single process in some way. The way I understand roc run it's not just for development, it's also what scripts run in by default (like ones with a shebang). I don't know if spawning multiple processes when you run a script might break expectations in some ways when using Roc as an alternative for, say, a bash script.

view this post on Zulip Luke Boswell (Nov 11 2024 at 22:38):

scripts run in by default (like ones with a shebang).

I thought they just run roc script.roc not using the subcommand

view this post on Zulip Jasper Woudenberg (Nov 11 2024 at 22:39):

That's true, I thought those were the same thing but don't remember why I think that :sweat_smile:

view this post on Zulip Brendan Hansknecht (Nov 11 2024 at 23:10):

Probably this really is just the bug that expects are done in an outdated way today

view this post on Zulip Brendan Hansknecht (Nov 11 2024 at 23:10):

They need to be updated to a platform function

view this post on Zulip Brendan Hansknecht (Nov 11 2024 at 23:10):

So that whole system should get ripped out

view this post on Zulip Anton (Nov 12 2024 at 09:42):

It's possible that roc run still tries to run the program even if there are compile errors, I recommend using roc dev. Not sure if that is affecting your issue but it's something to eliminate.


Last updated: Jul 05 2025 at 12:14 UTC