You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Running multiple interpreted programs with the regular prelude sequentially eats away memory because the GC effectively can't work (#11580).
This is particularly relevant for our spec suite, which has many integration tests that run programs with the prelude. As a workaround, we can extract execution of integration specs into separate processes. Then each test only uses the memory of its process which is immediately released after it has finished.
There are different approaches to do this. I have three proposals:
Just use the local compiler. This requires that .build/crystal is built with interpreter support before the spec run. This weak dependency is not ideal, but manageable. We could help mitigate with a make recipe which enforces a rebuild of the compiler.
Call the spec executable itself again. It contains the full compiler with interpreter support and thus it's guaranteed to be fresh. We would need to mess with the spec CLI in order to add a special operating mode. So I'm not super fond of this idea. However, it would be self-contained and fast.
Build a custom interpreter executable as a temporary spec helper. It would tailored to this specific use case, so it builds a bit quicker than a generic compiler (option 1).
A problem with the generic compiler is also that it doesn't provide a suitable operating mode for the spec use case: We want to pipe in a program, have it interpreted and get the value of the last expression as a result. That can almost be achieved by wrapping the spec code in p(begin\n#{code}\nend). But that only works for dynamic code and fails as soon as the code contains require, class def or similar. Running the interpreter in REPL mode could theoretically work, but I don't think it's a good idea to start parsing the REPL line output. So for option 1 we either need to add a special operating mode to the interpreter or change the examples so that they explicitly print the last expression. I don't like the latter because I don't want change the semantics of a program for a workaround.
Any thoughts?
The text was updated successfully, but these errors were encountered:
Running multiple interpreted programs with the regular prelude sequentially eats away memory because the GC effectively can't work (#11580).
This is particularly relevant for our spec suite, which has many integration tests that run programs with the prelude. As a workaround, we can extract execution of integration specs into separate processes. Then each test only uses the memory of its process which is immediately released after it has finished.
There are different approaches to do this. I have three proposals:
.build/crystal
is built with interpreter support before the spec run. This weak dependency is not ideal, but manageable. We could help mitigate with a make recipe which enforces a rebuild of the compiler.A problem with the generic compiler is also that it doesn't provide a suitable operating mode for the spec use case: We want to pipe in a program, have it interpreted and get the value of the last expression as a result. That can almost be achieved by wrapping the spec code in
p(begin\n#{code}\nend)
. But that only works for dynamic code and fails as soon as the code containsrequire
, class def or similar. Running the interpreter in REPL mode could theoretically work, but I don't think it's a good idea to start parsing the REPL line output. So for option 1 we either need to add a special operating mode to the interpreter or change the examples so that they explicitly print the last expression. I don't like the latter because I don't want change the semantics of a program for a workaround.Any thoughts?
The text was updated successfully, but these errors were encountered: