class Pantry::Client

The Pantry Client. The Client runs on any server that needs provisioning, and communicates to the Server through various channels. Clients can be further configured to manage an application, for a given environment, and across any number of roles.

Attributes

last_received_message[R]

For testing / debugging purposes, keep hold of the last message this client received

Public Class Methods

new(application: nil, environment: nil, roles: [], identity: nil, network_stack_class: Communication::Client) click to toggle source
# File lib/pantry/client.rb, line 19
def initialize(application: nil, environment: nil, roles: [], identity: nil, network_stack_class: Communication::Client)
  @info      = Pantry::ClientInfo.new(
    application: application,
    environment: environment,
    roles:       roles       || [],
    identity:    identity    || current_hostname
  )

  @commands   = CommandHandler.new(self, Pantry.client_commands)
  @networking = network_stack_class.new_link(self)
end

Public Instance Methods

receive_file(file_size, file_checksum) click to toggle source

See Pantry::Server#receive_file

# File lib/pantry/client.rb, line 82
def receive_file(file_size, file_checksum)
  @networking.receive_file(file_size, file_checksum)
end
receive_message(message) click to toggle source

Callback from Networking when a message is received

# File lib/pantry/client.rb, line 48
def receive_message(message)
  Pantry.logger.debug("[#{identity}] Received message #{message.inspect}")

  if message_meant_for_us?(message)
    @last_received_message = message
    results = @commands.process(message)

    if message.requires_response?
      Pantry.logger.debug("[#{identity}] Responding with #{results.inspect}")
      send_results_back_to_requester(message, results)
    end
  else
    Pantry.logger.debug("[#{identity}] Message discarded, not for us")
  end
end
run() click to toggle source

Start up the Client. This sets up the appropriate communication channels to the server, sends a registration message so the Server knows who just connected, and then waits for information to come.

# File lib/pantry/client.rb, line 35
def run
  Pantry.set_proc_title("pantry client #{Pantry::VERSION} :: #{identity}")
  @networking.run
  send_registration_message
  Pantry.logger.info("[#{identity}] Client registered and waiting for commands")
end
send_file(file_path, receiver_uuid, file_uuid) click to toggle source

See Pantry::Server#send_file

# File lib/pantry/client.rb, line 87
def send_file(file_path, receiver_uuid, file_uuid)
  @networking.send_file(file_path, receiver_uuid, file_uuid)
end
send_message(message) click to toggle source

Send a Pantry::Message directly to its intended recipient. For a Client this is almost always the Server.

# File lib/pantry/client.rb, line 66
def send_message(message)
  @networking.send_message(message)
end
send_request(message) click to toggle source

Send a Pantry::Message but mark it as requiring a response. This will set up and return a Celluloid::Future that will contain the response once it is available.

# File lib/pantry/client.rb, line 73
def send_request(message)
  message.requires_response!

  Pantry.logger.debug("[#{identity}] Sending request #{message.inspect}")

  @networking.send_request(message)
end
shutdown() click to toggle source
# File lib/pantry/client.rb, line 42
def shutdown
  Pantry.logger.info("[#{identity}] Client Shutting down")
  @registration_timer.cancel if @registration_timer
end

Protected Instance Methods

current_hostname() click to toggle source
# File lib/pantry/client.rb, line 93
def current_hostname
  Socket.gethostname
end
message_meant_for_us?(message) click to toggle source

ZeroMQ’s Pub/Sub topic matching is too simplistic to catch all the cases we need to handle. Given that if any topic matches the incoming message, we get the message even if it wasn’t exactly meant for us. For example, if this client subscribes to the following topics:

* pantry
* pantry.test
* pantry.test.app

This client will receive messages sent to “pantry.test.web” because “pantry” and “pantry.test” both match (string start_with? check) the message. Thus, we add our own handling to the message check as a protective stop gap.

# File lib/pantry/client.rb, line 127
def message_meant_for_us?(message)
  filter.matches?(message.to)
end
send_registration_message() click to toggle source
# File lib/pantry/client.rb, line 97
def send_registration_message
  @networking.send_message(
    Pantry::Commands::RegisterClient.new(self).to_message
  )
  @registration_timer =
    after(Pantry.config.client_heartbeat_interval) { send_registration_message }
end
send_results_back_to_requester(message, results) click to toggle source
# File lib/pantry/client.rb, line 105
def send_results_back_to_requester(message, results)
  response_message = message.build_response

  [results].flatten(1).each do |entry|
    response_message << entry
  end

  @networking.send_message(response_message)
end