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 =
Total number of hash nodes traversed. For example, loading a 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-value
According 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 the 500_000 nodes should be an upper limit, provided that the are additional safeguard present in other parts of the code (example: maximum number of interpolation blocks found). 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.
57 58 59 60 |
# File 'lib/gitlab/ci/config/interpolation/config.rb', line 57 def initialize(hash) @config = hash @errors = [] end |
Instance Attribute Details
#errors ⇒ Object (readonly)
Returns the value of attribute errors.
55 56 57 |
# File 'lib/gitlab/ci/config/interpolation/config.rb', line 55 def errors @errors end |
Class Method Details
.fabricate(config) ⇒ Object
83 84 85 86 87 88 89 90 91 92 |
# File 'lib/gitlab/ci/config/interpolation/config.rb', line 83 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.
72 73 74 75 76 77 78 79 80 |
# File 'lib/gitlab/ci/config/interpolation/config.rb', line 72 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
62 63 64 |
# File 'lib/gitlab/ci/config/interpolation/config.rb', line 62 def to_h @config end |