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(name, nestings = ->(_) {}) ⇒ Node

Returns a new instance of Node.

Parameters:

  • name (Symbol)

    node name

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

    block for nested settings



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

def initialize(name, nestings = ->(_) {})
  @name = name
  @children = []
  @nestings = nestings
  @compiled = false
  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

#nameObject (readonly)

Returns the value of attribute name.



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

def name
  @name
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

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



95
96
97
98
99
100
101
102
103
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
# File 'lib/karafka/core/configurable/node.rb', line 95

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 = respond_to?(value.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
    singleton_class.attr_accessor(value.name) 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
      public_send("#{value.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



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

def configure
  compile if !@compiled || 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



76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
# File 'lib/karafka/core/configurable/node.rb', line 76

def deep_dup
  dupped = Node.new(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(name, default: nil, constructor: nil, lazy: false, &block) ⇒ Object

Allows for a single leaf or nested node definition

Parameters:

  • 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



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

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

  compile
end

#to_hHash

Returns frozen config hash representation.

Returns:

  • (Hash)

    frozen config hash representation



56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
# File 'lib/karafka/core/configurable/node.rb', line 56

def to_h
  config = {}

  @children.each do |value|
    config[value.name] = if value.is_a?(Leaf)
                           result = public_send(value.name)
                           # 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