Class: Tincan::Receiver

Inherits:
Object
  • Object
show all
Defined in:
lib/tincan/receiver.rb

Overview

An object whose purpose is to listen to a variety of Redis queues and fire off notifications when triggered.

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(options = {}) ⇒ Tincan::Receiver

Creates and return a listener object, ready to listen. You can pass in either a hash or a block; the block takes priority.

Parameters:

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

    A list of keys/values to assign to this instance.



19
20
21
22
23
24
25
26
27
28
29
# File 'lib/tincan/receiver.rb', line 19

def initialize(options = {})
  if block_given?
    yield(self)
  else
    @config = options
    ivars =  %i(client_name listen_to redis_host redis_port namespace
                on_exception logger)
    ivars.each { |n| send("#{n}=".to_sym, @config[n]) }
  end
  self.redis_port ||= 6379
end

Instance Attribute Details

#client_nameObject

Returns the value of attribute client_name.



10
11
12
# File 'lib/tincan/receiver.rb', line 10

def client_name
  @client_name
end

#configObject (readonly)

Returns the value of attribute config.



9
10
11
# File 'lib/tincan/receiver.rb', line 9

def config
  @config
end

#listen_toObject

Returns the value of attribute listen_to.



10
11
12
# File 'lib/tincan/receiver.rb', line 10

def listen_to
  @listen_to
end

#loggerObject

Returns the value of attribute logger.



10
11
12
# File 'lib/tincan/receiver.rb', line 10

def logger
  @logger
end

#namespaceObject

Returns the value of attribute namespace.



10
11
12
# File 'lib/tincan/receiver.rb', line 10

def namespace
  @namespace
end

#on_exceptionObject

Returns the value of attribute on_exception.



10
11
12
# File 'lib/tincan/receiver.rb', line 10

def on_exception
  @on_exception
end

#redis_hostObject

Returns the value of attribute redis_host.



10
11
12
# File 'lib/tincan/receiver.rb', line 10

def redis_host
  @redis_host
end

#redis_portObject

Returns the value of attribute redis_port.



10
11
12
# File 'lib/tincan/receiver.rb', line 10

def redis_port
  @redis_port
end

Instance Method Details

#handle_message_for_object(object_name, message) ⇒ Object

Iterates through stored lambdas for a given object, and passes the message to all of them.

Parameters:

  • object_name (String)

    The object name gleamed from the list key.

  • message (Tincan::Message)

    The Message generated from the JSON hash retrieved from Redis.



78
79
80
81
82
83
# File 'lib/tincan/receiver.rb', line 78

def handle_message_for_object(object_name, message)
  logger.debug "Encountered #{object_name} message: #{message.object_data}"
  listen_to[object_name.to_sym].each do |stored_lambda|
    stored_lambda.call(message)
  end
end

#listenObject

Registers and subscribes. That is all.



88
89
90
91
# File 'lib/tincan/receiver.rb', line 88

def listen
  register
  subscribe
end

#message_for_id(message_id, object_name) ⇒ Tincan::Message

Asks the instance of Redis for the proper JSON data for a message, and then turns that into a Tincan::Message.

Parameters:

  • message_id (Integer)

    The numerical ID of the message to retrieve.

  • object_name (String)

    The object name of the message to retrieve; this helps the receiver determine which list it was posted to.

Returns:



102
103
104
105
106
107
# File 'lib/tincan/receiver.rb', line 102

def message_for_id(message_id, object_name)
  key = key_for_elements(object_name, 'messages', message_id)
  json = redis_client.get(key)
  return nil unless json
  Message.from_json(json)
end

#message_list_keysArray

A flattened list of message list keys, in the format of “namespace:object_name:client:messages”.

Returns:

  • (Array)

    An array of object_names formatted with client name, like “namespace:object_name:client:messages”.



113
114
115
116
117
118
119
# File 'lib/tincan/receiver.rb', line 113

def message_list_keys
  @message_list_keys ||= listen_to.keys.map do |object_name|
    %w(messages failures).map do |type|
      key_for_elements(object_name, client_name, type)
    end
  end.flatten
end

#redis_clientRedis

The instance of a Redis communicator that can subscribe messages.

Returns:

  • (Redis)

    The Redis client used by this object.



35
36
37
# File 'lib/tincan/receiver.rb', line 35

def redis_client
  @redis_client ||= ::Redis.new(host: redis_host, port: redis_port)
end

#registerTincan::Receiver

Registers this receiver against a Redis set based on the object name. Looks like “namespace:object_name:receivers”.

Returns:



44
45
46
47
48
49
50
51
# File 'lib/tincan/receiver.rb', line 44

def register
  listen_to.keys.each do |object_name|
    receiver_list_key = key_for_elements(object_name, 'receivers')
    logger.info "Registered against Tincan set #{receiver_list_key}"
    redis_client.sadd(receiver_list_key, client_name)
  end
  self
end

#store_failed_message(message_id, original_list) ⇒ Integer

Handles putting a message identifier into a failed “retries” list.

Parameters:

  • message_id (Integer)

    The identifier of the failed message.

  • original_list (String)

    The name of the originating list.

Returns:

  • (Integer)

    The number of failed entries in the same list.



57
58
59
60
61
# File 'lib/tincan/receiver.rb', line 57

def store_failed_message(message_id, original_list)
  logger.warn "Storing failure #{message_id} for list #{original_list}"
  failure = Failure.new(message_id, original_list)
  store_failure(failure)
end

#store_failure(failure) ⇒ Integer

Handles putting a message identifier into a failed “retries” list.

Parameters:

Returns:

  • (Integer)

    The number of failed entries in the same list.



66
67
68
69
# File 'lib/tincan/receiver.rb', line 66

def store_failure(failure)
  error_list = failure.queue_name.gsub('messages', 'failures')
  redis_client.rpush(error_list, failure.to_json)
end