Class: Carnivore::Http::PointBuilder

Inherits:
Object
  • Object
show all
Includes:
Blockenspiel::DSL, Utils::Logging, Utils::Params
Defined in:
lib/carnivore-http/point_builder.rb

Overview

End point builder

Defined Under Namespace

Classes: Endpoint

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(args = {}) ⇒ PointBuilder

Create new instance

Parameters:

  • args (Hash) (defaults to: {})

Options Hash (args):

  • :only (Array)
  • :except (Array)


80
81
82
83
84
85
86
87
88
# File 'lib/carnivore-http/point_builder.rb', line 80

def initialize(args={})
  @only = args[:only]
  @except = args[:except]
  @static = {}
  @regex = {}
  @callback_names = {}
  @endpoint_supervisor = Carnivore::Supervisor.create!.last
  load_endpoints!
end

Instance Attribute Details

#endpoint_supervisorCarnivore::Supervisor (readonly)

Returns supervisor.

Returns:

  • (Carnivore::Supervisor)

    supervisor



73
74
75
# File 'lib/carnivore-http/point_builder.rb', line 73

def endpoint_supervisor
  @endpoint_supervisor
end

#exceptArray (readonly)

Returns do not enable endpoints.

Returns:

  • (Array)

    do not enable endpoints



71
72
73
# File 'lib/carnivore-http/point_builder.rb', line 71

def except
  @except
end

#onlyArray (readonly)

Returns only enable endpoints.

Returns:

  • (Array)

    only enable endpoints



69
70
71
# File 'lib/carnivore-http/point_builder.rb', line 69

def only
  @only
end

#regexHash (readonly)

Returns regex path endpoints.

Returns:

  • (Hash)

    regex path endpoints



67
68
69
# File 'lib/carnivore-http/point_builder.rb', line 67

def regex
  @regex
end

#staticHash (readonly)

Returns static path endpoints.

Returns:

  • (Hash)

    static path endpoints



65
66
67
# File 'lib/carnivore-http/point_builder.rb', line 65

def static
  @static
end

Class Method Details

.compress_offspringHash

Returns merged storages (full tree).

Returns:

  • (Hash)

    merged storages (full tree)



263
264
265
266
267
268
# File 'lib/carnivore-http/point_builder.rb', line 263

def compress_offspring
  stores = offspring_storage
  stores.inject(stores.shift) do |memo, store|
    memo.merge(store)
  end
end

.define { ... } ⇒ Object

Define new API block

Yields:

  • new API block



234
235
236
# File 'lib/carnivore-http/point_builder.rb', line 234

def define(&block)
  store(Zoidberg.uuid, block)
end

.descendantsArray<Class>

Returns descendant classes.

Returns:

  • (Array<Class>)

    descendant classes



253
254
255
# File 'lib/carnivore-http/point_builder.rb', line 253

def descendants
  @descendants ||= []
end

.inherited(klass) ⇒ Object

Store subclass reference in descendants and setup properly for DSL usage

Parameters:

  • klass (Class)


227
228
229
# File 'lib/carnivore-http/point_builder.rb', line 227

def inherited(klass)
  descendants.push(klass)
end

.offspring_storageArray<Hash>

Returns all descendant storages (full tree).

Returns:

  • (Array<Hash>)

    all descendant storages (full tree)



258
259
260
# File 'lib/carnivore-http/point_builder.rb', line 258

def offspring_storage
  descendants.map(&:offspring_storage).flatten.unshift(storage)
end

.storageHash

Returns storage for defined blocks.

Returns:

  • (Hash)

    storage for defined blocks



248
249
250
# File 'lib/carnivore-http/point_builder.rb', line 248

def storage
  @storage ||= {}
end

.store(name, block) ⇒ Object

Store block

Parameters:

  • name (String, Symbol)
  • block (Proc)


242
243
244
245
# File 'lib/carnivore-http/point_builder.rb', line 242

def store(name, block)
  storage[name.to_sym] = block
  self
end

Instance Method Details

#callback_name(point, type) ⇒ String

Generate internal callback name reference

Parameters:

  • point (String, Symbol)
  • type (String, Symbol)

Returns:

  • (String)


165
166
167
168
169
170
171
# File 'lib/carnivore-http/point_builder.rb', line 165

def callback_name(point, type)
  key = "#{point}_#{type}"
  unless(@callback_names[key])
    @callback_names[key] = Digest::SHA256.hexdigest(key)
  end
  @callback_names[key]
end

#deliver(msg) ⇒ Truthy, Falsey

Deliver message to end points

Parameters:

  • msg (Carnivore::Message)

Returns:

  • (Truthy, Falsey)


104
105
106
107
108
# File 'lib/carnivore-http/point_builder.rb', line 104

def deliver(msg)
  type = msg[:message][:request].method.to_s.downcase.to_sym
  path = msg[:message][:request].url
  static_points(msg, type, path) || regex_points(msg, type, path)
end

#endpoint(request_type, regexp_or_string, args) { ... } ⇒ Object

Build new endpoint and supervise

Parameters:

  • request_type (Symbol, String)

    request type (:get, :put, etc.)

  • regexp_or_string (Regexp, String)
  • args (Hash)

Options Hash (args):

  • :workers (Numeric)

    number of workers to initialize

Yields:

  • action to execute on match



180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
# File 'lib/carnivore-http/point_builder.rb', line 180

def endpoint(request_type, regexp_or_string, args, &block)
  request_type = request_type.to_sym
  if(regexp_or_string.is_a?(Regexp))
    regex[request_type] ||= {}
    regex[request_type][regexp_or_string] = args
  else
    static[request_type] ||= {}
    static[request_type][regexp_or_string.sub(%r{/$}, '')] = args
  end
  if(args[:workers] && args[:workers].to_i > 1)
    endpoint_supervisor.pool(Endpoint,
      as: callback_name(regexp_or_string, request_type), size: args[:workers].to_i,
      args: [request_type, regexp_or_string, block]
    )
  else
    endpoint_supervisor.supervise_as(
      callback_name(regexp_or_string, request_type), Endpoint, request_type, regexp_or_string, block
    )
  end
  true
end

#endpointsArray

Returns all endpoints.

Returns:

  • (Array)

    all endpoints



203
204
205
# File 'lib/carnivore-http/point_builder.rb', line 203

def endpoints
  [static, regex]
end

#regex_points(msg, type, path) ⇒ Object

Apply message to regex endpoints and execute if matching

Parameters:

  • msg (Carnivore::Message)
  • type (Symbol)

    request type

  • path (String)

    request path

  • match (Truthy, Falsey)

    was detected and executed



139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
# File 'lib/carnivore-http/point_builder.rb', line 139

def regex_points(msg, type, path)
  if(regex[type])
    match = regex[type].keys.map do |point|
      unless((res = path.scan(/^(#{point})(\?|$)/)).empty?)
        res = res.first
        res.pop # remove empty EOS match
        [point, res]
      end
    end.compact.first
    if(match && !match.empty?)
      if(regex[type][match.first][:async])
        endpoint_supervisor[callback_name(match.first, type)].async.execute(*([msg] + match.last))
        true
      else
        endpoint_supervisor[callback_name(match.first, type)].execute(*([msg] + match.last))
        true
      end
    end
  end
end

#static_points(msg, type, path) ⇒ Object

Apply message to static endpoints and execute if matching

Parameters:

  • msg (Carnivore::Message)
  • type (Symbol)

    request type

  • path (String)

    request path

  • match (Truthy, Falsey)

    was detected and executed



116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
# File 'lib/carnivore-http/point_builder.rb', line 116

def static_points(msg, type, path)
  if(static[type])
    match = static[type].keys.detect do |point|
      !path.scan(/^#{Regexp.escape(point)}\/?(\?|$)/).empty?
    end
    if(match)
      if(static[type][match][:async])
        endpoint_supervisor[callback_name(match, type)].async.execute(msg)
        true
      else
        endpoint_supervisor[callback_name(match, type)].execute(msg)
        true
      end
    end
  end
end