Class: BeanCounter::Strategy::GemeraldBeanstalkStrategy

Inherits:
BeanCounter::Strategy show all
Extended by:
Forwardable
Defined in:
lib/bean_counter/strategies/gemerald_beanstalk_strategy/strategy.rb

Defined Under Namespace

Classes: Job, Tube

Constant Summary collapse

V4_IP_REGEX =

Regex for checking for valid V4 IP addresses

/^(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)(?::\d+)?$/

Constants inherited from BeanCounter::Strategy

MATCHABLE_JOB_ATTRIBUTES, MATCHABLE_TUBE_ATTRIBUTES

Instance Attribute Summary collapse

Instance Method Summary collapse

Methods inherited from BeanCounter::Strategy

inherited, #jobs, known_strategy?, materialize_strategy, strategies, #tubes

Constructor Details

#initializeGemeraldBeanstalkStrategy

Initialize a new GemeraldBeanstalkStrategy. This includes initializing GemeraldBeanstalk::Servers for each of the beanstalk_urls visible to BeanCounter and also spawning direct connections to those servers.



72
73
74
75
76
77
78
79
80
# File 'lib/bean_counter/strategies/gemerald_beanstalk_strategy/strategy.rb', line 72

def initialize
  @clients = {}
  @beanstalk_servers = []
  BeanCounter.beanstalkd_url.each do |url|
    server = GemeraldBeanstalk::Server.new(*parse_url(url))
    @clients[server.beanstalk] = server.beanstalk.direct_connection_client
    @beanstalk_servers << server
  end
end

Instance Attribute Details

#beanstalk_serversObject (readonly, private)

The collection of GemeraldBeanstalk servers the strategy built during initialization



158
159
160
# File 'lib/bean_counter/strategies/gemerald_beanstalk_strategy/strategy.rb', line 158

def beanstalk_servers
  @beanstalk_servers
end

Instance Method Details

#beanstalksArray<GemeraldBeanstalk::Beanstalk> (private)

The collection of beanstalks belonginging to the GemeraldBeanstalk servers that were created during initialization.

Returns:

  • (Array<GemeraldBeanstalk::Beanstalk>)

    the Beanstalks of the GemeraldBeanstalk::Servers



166
167
168
# File 'lib/bean_counter/strategies/gemerald_beanstalk_strategy/strategy.rb', line 166

def beanstalks
  return @beanstalks ||= @beanstalk_servers.map(&:beanstalk)
end

#collect_new_jobs { ... } ⇒ Array<GemeraldBeanstalkStrategy::Job>

Collects all jobs enqueued during the execution of the provided block. Returns an Array of GemeraldBeanstalkStrategy::Job.

Fulfills BeanCounter::Strategy#collect_new_jobs contract.

Yields:

  • Nothing is yielded to the provided block

Returns:

Raises:

  • (ArgumentError)

    if a block is not provided.

See Also:



28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
# File 'lib/bean_counter/strategies/gemerald_beanstalk_strategy/strategy.rb', line 28

def collect_new_jobs
  raise ArgumentError, 'Block required' unless block_given?

  max_id_pairs = beanstalks.map do |beanstalk|
    [beanstalk, beanstalk.jobs[-1] ? beanstalk.jobs[-1].id : 0]
  end
  max_ids = Hash[max_id_pairs]

  yield

  new_jobs = []
  # Jobs are collected in reverse, so iterate beanstalks in reverse too
  beanstalks.reverse.each do |beanstalk|
    jobs = beanstalk.jobs
    index = -1
    while (job = jobs[index]) && job.id > max_ids[beanstalk] do
      new_jobs << strategy_job(job)
      index -= 1
    end
  end
  # Flip new jobs to maintain beanstalk, id asc order
  return new_jobs.reverse
end

#delete_job(job) ⇒ Boolean

Attempts to delete the provided GemeraldBeanstalkStrategy::Job job. Returns true if deletion succeeds or if job does not exist. Returns false if job could not be deleted (typically due to it being reserved by another connection).

Fulfills BeanCounter::Strategy#delete_job contract.

Parameters:

Returns:

  • (Boolean)

    If the given job was successfully deleted or does not exist, returns true. Otherwise returns false.

See Also:



64
65
66
# File 'lib/bean_counter/strategies/gemerald_beanstalk_strategy/strategy.rb', line 64

def delete_job(job)
  return job.delete
end

#job_enumeratorObject (private)

Returns an enumerator that enumerates all jobs on all beanstalk servers in the order the beanstalk servers are defined in ascending order. Jobs are returned as GemeraldBeanstalkStrategy::Job.



174
175
176
177
178
179
180
181
182
# File 'lib/bean_counter/strategies/gemerald_beanstalk_strategy/strategy.rb', line 174

def job_enumerator
  return Enumerator.new do |yielder|
    beanstalks.each do |beanstalk|
      beanstalk.jobs.each do |job|
        yielder << strategy_job(job)
      end
    end
  end
end

#job_matches?(job, options = {}) ⇒ Boolean

Returns a Boolean indicating whether or not the provided GemeraldBeanstalkStrategy::Job job matches the given Hash of options.

See MATCHABLE_JOB_ATTRIBUTES for a list of attributes that can be used when matching.

Fulfills BeanCounter::Strategy#job_matches? contract.

Parameters:

  • job (GemeraldBeanstalkStrategy::Job)

    the job to evaluate for a matche.

  • options (defaults to: {})

    [HashSymbol => Numeric, Proc, Range, Regexp, String, Symbol] Options to be used to evaluate a match.

Returns:

  • (Boolean)

    If job exists and matches the provided options, returns true. Otherwise, returns false.

See Also:



99
100
101
# File 'lib/bean_counter/strategies/gemerald_beanstalk_strategy/strategy.rb', line 99

def job_matches?(job, options = {})
  return matcher(MATCHABLE_JOB_ATTRIBUTES, job, options)
end

#matcher(valid_attributes, matchable, options = {}) ⇒ Object (private)

Generic match evaluator that compares the Hash of options given to the Strategy representation of the given matchable.



187
188
189
190
191
192
# File 'lib/bean_counter/strategies/gemerald_beanstalk_strategy/strategy.rb', line 187

def matcher(valid_attributes, matchable, options = {})
  return false unless matchable.exists?
  return (options.keys & valid_attributes).all? do |key|
    options[key] === matchable.send(key.to_s.gsub(/-/, '_'))
  end
end

#parse_url(url) ⇒ Object (private)

Parses a variety of forms of beanstalk URL and returns a pair including the hostname and possibly a port given by the url.



197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
# File 'lib/bean_counter/strategies/gemerald_beanstalk_strategy/strategy.rb', line 197

def parse_url(url)
  unless V4_IP_REGEX === url
    uri = URI.parse(url)
    if uri.scheme && uri.host
      raise(ArgumentError, "Invalid beanstalk URI: #{url}") unless uri.scheme == 'beanstalk'
      host = uri.host
      port = uri.port
    end
  end
  unless host
    match = url.split(/:/)
    host = match[0]
    port = match[1]
  end
  return port ? [host, Integer(port)] : [host]
end

#pretty_print_job(job) ⇒ String

Returns a String representation of the GemeraldBeanstalkStrategy::Job job in a pretty, human readable format.

Fulfills BeanCounter::Strategy#pretty_print_job contract.

Parameters:

Returns:

  • (String)

    A more human-readable representation of job.

See Also:



113
114
115
116
117
# File 'lib/bean_counter/strategies/gemerald_beanstalk_strategy/strategy.rb', line 113

def pretty_print_job(job)
  hash = job.to_hash
  hash.delete('connection')
  return hash.to_s
end

#pretty_print_tube(tube) ⇒ String

Returns a String representation of tube in a pretty, human readable format.

Fulfills BeanCounter::Strategy#pretty_print_tube contract.

Parameters:

Returns:

  • (String)

    A more human-readable representation of tube.

See Also:



128
129
130
# File 'lib/bean_counter/strategies/gemerald_beanstalk_strategy/strategy.rb', line 128

def pretty_print_tube(tube)
  return tube.to_hash.to_s
end

#strategy_job(gemerald_job) ⇒ Object (private)

Helper method to transform a GemeraldBeanstalk::Job into a BeanCounter::Strategy::GemeraldBeanstalkStrategy::Job. The strategy specific job class is intended to hide native job implementation interface specifics and prevent meddling with native Job internals.



219
220
221
# File 'lib/bean_counter/strategies/gemerald_beanstalk_strategy/strategy.rb', line 219

def strategy_job(gemerald_job)
  return BeanCounter::Strategy::GemeraldBeanstalkStrategy::Job.new(gemerald_job, @clients[gemerald_job.beanstalk])
end

#strategy_tube(tube_name) ⇒ Object (private)

Helper method to transform a tube_name into a BeanCounter::Strategy::GemeraldBeanstalkStrategy::Tube. The strategy specific tube class is intended to hide native tube implementation interface specifics and prevent meddling with native Tube internals. Also handles merging of tube data from multiple servers, as such, requires access to beanstalk servers.



230
231
232
# File 'lib/bean_counter/strategies/gemerald_beanstalk_strategy/strategy.rb', line 230

def strategy_tube(tube_name)
  return BeanCounter::Strategy::GemeraldBeanstalkStrategy::Tube.new(tube_name, beanstalks)
end

#tube_enumeratorObject (private)

Returns an enumerator that enumerates all tubes on all beanstalk servers. Each tube is included in the enumeration only once, regardless of how many servers contain an instance of that tube. Tube stats are merged before they are yielded by the enumerator as a GemeraldBeanstalkdStrategy::Tube.



239
240
241
242
243
244
245
246
247
248
249
# File 'lib/bean_counter/strategies/gemerald_beanstalk_strategy/strategy.rb', line 239

def tube_enumerator
  tubes_in_pool = beanstalks.inject([]) do |memo, beanstalk|
    memo.concat(beanstalk.tubes.keys)
  end
  tubes_in_pool.uniq!
  return Enumerator.new do |yielder|
    tubes_in_pool.each do |tube_name|
      yielder << strategy_tube(tube_name)
    end
  end
end

#tube_matches?(tube, options = {}) ⇒ Boolean

Returns a boolean indicating whether or not the provided GemeraldBeanstalkStrategy::Tube, tube, matches the given Hash of options.

See MATCHABLE_TUBE_ATTRIBUTES for a list of attributes that can be used when evaluating a match.

Fulfills BeanCounter::Strategy#tube_matches? contract.

Parameters:

  • tube (GemeraldBeanstalkStrategy::Tube)

    the tube to evaluate a match against.

  • options (defaults to: {})

    [HashSymbol => Numeric, Proc, Range, Regexp, String, Symbol] a Hash of options to use when evaluating a match.

Returns:

  • (Boolean)

    If tube exists and matches against the provided options, returns true. Otherwise returns false.

See Also:



149
150
151
152
# File 'lib/bean_counter/strategies/gemerald_beanstalk_strategy/strategy.rb', line 149

def tube_matches?(tube, options = {})
  return false if tube.nil?
  return matcher(MATCHABLE_TUBE_ATTRIBUTES, tube, options)
end