Class: Karafka::Core::Configurable::Node

Inherits:
Object
  • Object
show all
Defined in:
lib/karafka/core/configurable/node.rb

Overview

Single non-leaf node This is a core component for the configurable settings

The idea here is simple: we collect settings (leafs) and children (nodes) information and we only compile/initialize the values prior to user running the #configure API. This API needs to run prior to using the result stuff even if there is nothing to configure

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(node_name, nestings = ->(_) {}) ⇒ Node

Returns a new instance of Node.

Parameters:

  • node_name (Symbol)

    node name

  • nestings (Proc) (defaults to: ->(_) {})

    block for nested settings



20
21
22
23
24
25
26
27
28
# File 'lib/karafka/core/configurable/node.rb', line 20

def initialize(node_name, nestings = ->(_) {})
  @node_name = node_name
  @children = []
  @nestings = nestings
  @compiled = false
  @configs_refs = {}
  @local_defs = []
  instance_eval(&nestings)
end

Instance Attribute Details

#childrenObject

We need to be able to redefine children for deep copy



16
17
18
# File 'lib/karafka/core/configurable/node.rb', line 16

def children
  @children
end

#nestingsObject (readonly)

Returns the value of attribute nestings.



13
14
15
# File 'lib/karafka/core/configurable/node.rb', line 13

def nestings
  @nestings
end

#node_nameObject (readonly)

Returns the value of attribute node_name.



13
14
15
# File 'lib/karafka/core/configurable/node.rb', line 13

def node_name
  @node_name
end

Instance Method Details

#compileObject

Note:

It runs once, after things are compiled, they will not be recompiled again

Converts the settings definitions into end children



104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
# File 'lib/karafka/core/configurable/node.rb', line 104

def compile
  @children.each do |value|
    # Do not redefine something that was already set during compilation
    # This will allow us to reconfigure things and skip override with defaults
    skippable = @configs_refs.key?(value.node_name) || (value.is_a?(Leaf) && value.compiled?)
    lazy_leaf = value.is_a?(Leaf) && value.lazy?

    # Do not create accessor for leafs that are lazy as they will get a custom method
    # created instead
    build_accessors(value) unless lazy_leaf

    next if skippable

    initialized = if value.is_a?(Leaf)
                    value.compiled = true

                    if value.constructor && value.lazy?
                      false
                    elsif value.constructor
                      call_constructor(value)
                    else
                      value.default
                    end
                  else
                    value.compile
                    value
                  end

    if lazy_leaf && !initialized
      build_dynamic_accessor(value)
    else
      @configs_refs[value.node_name] = initialized
    end
  end

  @compiled = true
end

#configure {|_self| ... } ⇒ Node

Allows for the configuration and setup of the settings

Compile settings, allow for overrides via yielding

Yields:

  • (_self)

Yield Parameters:

Returns:

  • (Node)

    returns self after configuration



51
52
53
54
55
# File 'lib/karafka/core/configurable/node.rb', line 51

def configure
  compile if !@compiled || node_name == :root
  yield(self) if block_given?
  self
end

#deep_dupNode

Deep copies all the children nodes to allow us for templates building on a class level and non-side-effect usage on an instance/inherited.

Returns:

  • (Node)

    duplicated node



85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
# File 'lib/karafka/core/configurable/node.rb', line 85

def deep_dup
  dupped = Node.new(node_name, nestings)

  dupped.children += children.map do |value|
    if value.is_a?(Leaf)
      # After inheritance we need to reload the state so the leafs are recompiled again
      value = value.dup
      value.compiled = false
      value
    else
      value.deep_dup
    end
  end

  dupped
end

#setting(node_name, default: nil, constructor: nil, lazy: false, &block) ⇒ Object

Allows for a single leaf or nested node definition

Parameters:

  • node_name (Symbol)

    setting or nested node name

  • default (Object) (defaults to: nil)

    default value

  • constructor (#call, nil) (defaults to: nil)

    callable or nil

  • lazy (Boolean) (defaults to: false)

    is this a lazy leaf

  • block (Proc)

    block for nested settings



37
38
39
40
41
42
43
44
45
# File 'lib/karafka/core/configurable/node.rb', line 37

def setting(node_name, default: nil, constructor: nil, lazy: false, &block)
  @children << if block
                 Node.new(node_name, block)
               else
                 Leaf.new(node_name, default, constructor, false, lazy)
               end

  compile
end

#to_hHash

Returns frozen config hash representation.

Returns:

  • (Hash)

    frozen config hash representation



58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
# File 'lib/karafka/core/configurable/node.rb', line 58

def to_h
  config = {}

  @children.each do |value|
    config[value.node_name] = if value.is_a?(Leaf)
                                result = if @configs_refs.key?(value.node_name)
                                           @configs_refs[value.node_name]
                                         elsif value.constructor
                                           value.constructor.call
                                         elsif value.default
                                           value.default
                                         end

                                # We need to check if value is not a result node for cases
                                # where we merge additional config
                                result.is_a?(Node) ? result.to_h : result
                              else
                                value.to_h
                              end
  end

  config.freeze
end