class Attention::Instance

A publishable representation of the current server

When an instance is {#publish}ed, an event is sent in the format

{
   'added' => {
     'id' => '123',
     'ip' => '127.0.0.1',
     'port' => 9000
   }
}

When an instance is {#unpublish}ed, an event is sent in the format

{
   'removed' => {
     'id' => '123',
     'ip' => '127.0.0.1',
     'port' => 9000
   }
}

Attributes

id[R]
publisher[R]

@!visibility private

Public Class Methods

new(ip: nil, port: nil) click to toggle source

Creates an Instance @param ip [String] Optionally override the IP of the server @param port [Fixnum, Numeric] Optionally specify the port of the server

# File lib/attention/instance.rb, line 34
def initialize(ip: nil, port: nil)
  @id = Attention.redis.call.incr('instances').to_s
  @ip = ip
  @port = port
  @publisher = Publisher.new
end

Public Instance Methods

info() click to toggle source

Published information about this instance @return [Hash<id: Fixnum, ip: String, port: Numeric>] @option @return [Fixnum] :id The instance id

# File lib/attention/instance.rb, line 62
def info
  { id: @id, ip: ip }.tap do |h|
    h[:port] = @port if @port
  end
end
publish() click to toggle source

Publishes this server and starts the {#heartbeat}

# File lib/attention/instance.rb, line 42
def publish
  publisher.publish('instance', added: info) do |redis|
    redis.setex "instance_#{ @id }", Attention.options[:ttl], JSON.dump(info)
  end
  heartbeat
end
unpublish() click to toggle source

Unpublishes this server and stops the {#heartbeat}

# File lib/attention/instance.rb, line 50
def unpublish
  return unless @heartbeat
  @heartbeat.shutdown
  publisher.publish('instance', removed: info) do |redis|
    redis.del "instance_#{ @id }"
  end
  @heartbeat = nil
end

Private Instance Methods

heartbeat() click to toggle source

Uses a {Concurrent::TimerTask} to periodically tell Redis that this server is still online @!visibility public @api private

# File lib/attention/instance.rb, line 74
def heartbeat
  return @heartbeat if @heartbeat
  @heartbeat = Concurrent::TimerTask.new(execution_interval: heartbeat_frequency) do
    Attention.redis.call.setex "instance_#{ @id }", Attention.options[:ttl], JSON.dump(info)
  end
  @heartbeat.execute
  @heartbeat
end
heartbeat_frequency() click to toggle source

The frequency of the {#heartbeat} is based on Attention.options[:ttl] @!visibility public @api private

# File lib/attention/instance.rb, line 86
def heartbeat_frequency
  [1, Attention.options[:ttl] - 5].max
end
ip() click to toggle source

Attempts to automatically discover the IP address of the server

# File lib/attention/instance.rb, line 91
def ip
  return @ip if @ip
  address = Socket.ip_address_list.find &:ipv4_private?
  @ip = address && address.ip_address
end