Class: Langis::Dsl::PipesConfig

Inherits:
Object
  • Object
show all
Includes:
Blockenspiel::DSL
Defined in:
lib/langis/dsl.rb

Overview

This represents the configuration of the overall Langis piping. It is the configuration of the message intakes and their corresponding Rackish applications.

See Also:

  • #langis_plumbing

Instance Method Summary collapse

Constructor Details

#initializePipesConfig

Returns a new instance of PipesConfig.



69
70
71
72
73
# File 'lib/langis/dsl.rb', line 69

def initialize
  @intakes = {}
  @sinks = {}
  @check_valve = nil
end

Instance Method Details

#build_pipes{String => Array<#call>}

Creates the sinks (application stacks) and references them in their assigned intakes. A create sink can be referenced by multiple intakes.

Returns:

  • ({String => Array<#call>})

    The intake name to list of created sinks.

Raises:

  • (PipingConfigError)

    Error raised when an intake references a non-existent sink; we are unable to wire up an app.



152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
# File 'lib/langis/dsl.rb', line 152

def build_pipes
  # Build the main sinks, which may be added to the end of other
  # defined middleware.
  built_sinks = {}
  @sinks.each do |key, value|
    built_sinks[key] = value.to_app
  end

  # Full pipes is the final return hash to the caller. Its keys are the
  # intake names, and its values are Arrays of the sinks. Each sink
  # is a Rackish application stack.
  full_pipes = {}
  @intakes.each do |intake_name, sink_type_links|
    # Right now, each intake's value is a list of pairs. Each
    # pair is a sink name and the set of message types it should watch
    # for. Empty sets mean to do a catch all.
    sink_type_links.each do |sink_name, message_types|
      built_sink = built_sinks[sink_name]
      # We want to confirm that the sink the intake is referencing
      # actually exists.
      unless built_sink
        raise PipingConfigError.new "Sink not found: #{sink_name}"
      end

      # If any message type was defined to filter in the intaked block,
      # then we want to create a middleware to filter out all messages
      # whose type is not in that list. Otherwise we'll just flow
      # all messages to this defined sink.
      if message_types.empty?
        half_pipe = built_sink
      else
        half_pipe = ::Langis::Middleware::MessageTypeFilter.new(
          built_sink, *message_types)
      end

      # If we have a check_valve defined in the configuration, then
      # we want to prepend it to the sink.
      if @check_valve
        full_pipe = @check_valve.to_app half_pipe
      else
        full_pipe = half_pipe
      end

      # Now add the wired up sink to the list of sinks to be handled
      # by given intake.
      full_pipes[intake_name] ||= []
      full_pipes[intake_name] << full_pipe
    end
  end
  return full_pipes
end

#check_valve(&block) ⇒ RackishConfig

Dsl only method to define a Rackish application stack that is prepended to all sinks defined in the Langis config. This is so one can define a global intercept patch for functionality like global custom error handling. Note that one SHOULD only declare ‘use Middleware` type statements since this stack will be prepended to the other sinks. A `run` declaration in here will terminate the execution, or even more likely fail to wire up correctly.

Parameters:

  • name (#to_s)

    The name of the sink to define.

  • &block (Block)

    The dsl configuration block for this sink.

Returns:



136
137
138
139
140
# File 'lib/langis/dsl.rb', line 136

def check_valve(&block)
  config = RackishConfig.new
  Blockenspiel.invoke block, config 
  @check_valve = config
end

#for_sink(name, &block) ⇒ RackishConfig

Dsl only method to define a “sink”, a Rackish application stack. Subsequent sinks of the same name will overwrite the configuration of a previously defined sink of that name.

Parameters:

  • name (#to_s)

    The name of the sink to define.

  • &block (Block)

    The dsl configuration block for this sink.

Returns:

  • (RackishConfig)

    The Rackish application stack for this sink.



118
119
120
121
122
# File 'lib/langis/dsl.rb', line 118

def for_sink(name, &block)
  config = RackishConfig.new
  Blockenspiel.invoke block, config 
  @sinks[name.to_s] = config
end

#intake(name, *args, &block) ⇒ IntakeConfig

Dsl only method that parses a sub-block that defines an “intake”. An intake is the “queue” name that a message is sent to, and whose defined “sinks” (application stacks) are executed in turn.

Parameters:

  • name (#to_s)

    The name of the intake to define.

  • *args (#to_s)

    Additional named aliases of this intake.

  • &block (Block)

    The dsl configuration block for this intake.

Returns:

  • (IntakeConfig)

    The configuration of this intake block.



84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
# File 'lib/langis/dsl.rb', line 84

def intake(name, *args, &block)
  # We require at least one intake to be defined here, and merge
  # it into a list where other intake names have been defined.
  intake_names = args.clone
  intake_names.unshift name
  intake_names.map! { |n| n.to_s }

  # Here we launch the blockenspiel dsl processing for the intake block.
  config = IntakeConfig.new
  Blockenspiel.invoke block, config
  sink_type_links = config.sink_type_links

  # Iterate over the returned pipes, then only create intakes that have
  # actual sinks. We don't want to have intakes without sinks.
  # This also is set up so that we can use multiple intake dsl blocks
  # to define a single intake (i.e.- intakes with identical names
  # are only thought of as a single intake.)
  sink_type_links.each do |sink_name, message_types|
    intake_names.each do |intake_name|
      @intakes[intake_name] ||= {}
      @intakes[intake_name][sink_name] ||= Set.new
      @intakes[intake_name][sink_name].merge message_types
    end
  end
end