Open addersuk opened 1 year ago
Thanks for the report! I am looking forward to a test case that helps reproducing the issue comparing 4.3 to 4.4. I just had a brief look at cuke_modeler and it seemed like a good abstraction layer.
In any case if I read the comparison correctly the memory increase is at a factor of ~3. But the CPU usage is much lower could that be right? Some kind of trade off happening here?
@enkessler As you created cuke_modeler and #244, do you have an idea what may be happening here?
...a massive increase in memory usage...extensive usage of Gherkin feature files...
Yeah, that's probably due to cuke_modeler
. When CukeModeler makes a model tree, you're getting everything. Models for directories, their feature files, the comments within those files, any random @wip
tags lying around on tests; all of it. CukeModeler doesn't know what the models are needed for, so it's not going to pick and choose what information to keep or leave out and all of those model objects are going to hang around in memory until Ruby thinks that they can be cleaned up, the same as any other object. If it turns out that a directory containing 10,000 tests was modeled in order to find the one test that Turnip actually wants to run or something like that then, yeah, that's 10,000+ objects in memory until either the process ends or the references to that model tree gets thrown away.
So I'm guessing that it's a fixable problem. We just have to have a look at how long the Turnip internals need to hang on to the objects or maybe have it prune off parts of the tree that it knows that it doesn't need.
Additionally, cucumber-gherkin
provides a lot more information than cuke_modeler
bothers to model but, in order to not be a limiting factor, all of that underlying, non-abstracted data is still made available to the user via <some_model_class>#parsing_data
. For example, before CukeModeler had models for the comments in feature files, a user would have been able to still grab the parsed data contained in the feature model and find the comments in there.
Because of all that, the CukeModeler models are 'bigger' than the Gherkin objects that they replaced. But we could, at the very least, throw out that extra data after the models are created inside of the Turnip code.
@addersuk A test or sample project that reproduces the issues would be helpful but, in the mean time, stick this monkey patch in somewhere and see if it affects the numbers.
module Turnip
class Builder
def self.build(feature_file)
feature_file = CukeModeler::FeatureFile.new(feature_file)
# We don't need any of the raw data from Gherkin, so save memory by getting rid of it.
feature_file.each do |model|
model.parsing_data = nil
end
return nil unless feature_file.feature
Node::Feature.new(feature_file.feature)
end
end
end
In a private repo we have seen a massive increase in memory usage of our app that is using turnip since we upgraded to Turnip 4.4.0
Before the upgrade we run two ruby threads on our CI server
After the upgrade to 4.4.0 with two threads
I'll try and create a test case to illustrate this as it is happening in a private repo that makes extensive usage of Gherkin feature files.
We suspect this is due to the move to cuke_modeler