Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

hotfix: suppress GC in heartbeat #3623

Merged
merged 3 commits into from
Dec 6, 2022
Merged

hotfix: suppress GC in heartbeat #3623

merged 3 commits into from
Dec 6, 2022

Conversation

crusso
Copy link
Contributor

@crusso crusso commented Dec 6, 2022

Mainnet doesn't yet support DTS for canister_heartbeat yet, so a long GC may fail to complete when it would in an ordinary message supporting DTS.

This PR suppresses the GC call, leaving it to the already scheduled async message executing Motoko system function heartbeat, which will run with DTS enabled, avoiding the issue (and a potential space leak).

#3622 tracks the need to revert this hack once IC heartbeats support DTS.

@crusso crusso requested review from luc-blaeser and ggreif December 6, 2022 11:48
@crusso crusso marked this pull request as ready for review December 6, 2022 11:49
src/codegen/compile.ml Outdated Show resolved Hide resolved
src/codegen/compile.ml Outdated Show resolved Hide resolved
crusso and others added 2 commits December 6, 2022 11:53
Co-authored-by: Gabor Greif <gabor@dfinity.org>
@@ -3894,7 +3894,11 @@ module IC = struct
let fi = E.add_fun env "canister_heartbeat"
(Func.of_body env [] [] (fun env ->
G.i (Call (nr (E.built_in env "heartbeat_exp"))) ^^
GC.collect_garbage env))
(* TODO(3622)
Copy link
Contributor

@ggreif ggreif Dec 6, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I saw this while implementing system func timer, and I remember considering it a bit expensive/dangerous. But with DTS not covering this, yuck!

Copy link
Contributor Author

@crusso crusso Dec 6, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, I remember you suggesting it but thought better not to mess with the GC. This just a temp hack. Let's see what Luc thinks.

@luc-blaeser
Copy link
Contributor

Looks good. I also checked it with an example (that creates garbage in the heartbeat). The question is whether this extra GC schedule call is needed at all in the future even if DTS is available for the heartbeat call (since the async function contains GC scheduling anyway).

@crusso
Copy link
Contributor Author

crusso commented Dec 6, 2022

Looks good. I also checked it with an example (that creates garbage in the heartbeat). The question is whether this extra GC schedule call is needed at all in the future even if DTS is available for the heartbeat call (since the async function contains GC scheduling anyway).

My initial intention was to hopefully remove the extra async hop in future, so the heartbeat code runs during the heartbeat method. The fact that it runs with a delay is an accident to the async/await implementation (that async*/await* will optimize). If we do that, we'll need to do the GC I think, otherwise an inactive canister will just leak memory due to heartbeats.

@crusso crusso added the automerge-squash When ready, merge (using squash) label Dec 6, 2022
@github-actions
Copy link

github-actions bot commented Dec 6, 2022

Comparing from 112f9eb to 16c1145:
In terms of gas, no changes are observed in 4 tests.
In terms of size, no changes are observed in 4 tests.

@mergify mergify bot merged commit 68f387a into master Dec 6, 2022
@mergify mergify bot deleted the claudio/heartbeat-no-gc branch December 6, 2022 15:58
@mergify mergify bot removed the automerge-squash When ready, merge (using squash) label Dec 6, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants