Class: Gitlab::Ci::Config::Interpolation::Config
- Inherits:
-
Object
- Object
- Gitlab::Ci::Config::Interpolation::Config
- Includes:
- Utils::StrongMemoize
- Defined in:
- lib/gitlab/ci/config/interpolation/config.rb
Overview
Interpolation::Config represents a configuration artifact that we want to perform interpolation on.
Constant Summary collapse
- MAX_NODES =
Loading the YAML below would result in a hash having 12 nodes instead of 9, because hash values are being counted before we recursively traverse them.
test:
spec: env: $[[ inputs.env ]]$[[ inputs.key ]]:
name: $[[ inputs.key ]] script: my-valueAccording to our benchmarks performed when developing this code, the worst-case scenario of processing a hash with 500_000 nodes takes around 1 second and consumes around 225 megabytes of memory.
The typical scenario, using just a few interpolations, takes 250ms and consumes around 20 megabytes of memory.
Given the above, 500_000 nodes should be an upper limit given that there are additional safeguards present in other parts of the code. Typical size of a YAML configuration with 500k nodes might be around 10 megabytes, which is an order of magnitude higher than the 1MB limit for loading YAML on GitLab.com
500_000- MAX_NODE_SIZE =
1MB
1024 * 1024
- TooManyNodesError =
Class.new(StandardError)
- NodeTooLargeError =
Class.new(StandardError)
- Visitor =
Class.new do def initialize @visited = 0 end def visit! @visited += 1 raise Config::TooManyNodesError if @visited > Config::MAX_NODES end end
Instance Attribute Summary collapse
-
#errors ⇒ Object
readonly
Returns the value of attribute errors.
Class Method Summary collapse
Instance Method Summary collapse
-
#initialize(hash) ⇒ Config
constructor
A new instance of Config.
-
#replace!(&block) ⇒ Object
The replace! method will yield a block and replace each of the hash config nodes with the return value of the block.
- #to_h ⇒ Object
Constructor Details
#initialize(hash) ⇒ Config
Returns a new instance of Config.
56 57 58 59 |
# File 'lib/gitlab/ci/config/interpolation/config.rb', line 56 def initialize(hash) @config = hash @errors = [] end |
Instance Attribute Details
#errors ⇒ Object (readonly)
Returns the value of attribute errors.
54 55 56 |
# File 'lib/gitlab/ci/config/interpolation/config.rb', line 54 def errors @errors end |
Class Method Details
.fabricate(config) ⇒ Object
82 83 84 85 86 87 88 89 90 91 |
# File 'lib/gitlab/ci/config/interpolation/config.rb', line 82 def self.fabricate(config) case config when Hash new(config) when Interpolation::Config config else raise ArgumentError, 'unknown interpolation config' end end |
Instance Method Details
#replace!(&block) ⇒ Object
The replace! method will yield a block and replace each of the hash config nodes with the return value of the block.
It returns nil if there were errors found during the process.
71 72 73 74 75 76 77 78 79 |
# File 'lib/gitlab/ci/config/interpolation/config.rb', line 71 def replace!(&block) recursive_replace(@config, Visitor.new, &block) rescue TooManyNodesError @errors.push('config too large') nil rescue NodeTooLargeError @errors.push('config node too large') nil end |
#to_h ⇒ Object
61 62 63 |
# File 'lib/gitlab/ci/config/interpolation/config.rb', line 61 def to_h @config end |