Class: Pantry::Command

Inherits:
Object
  • Object
show all
Defined in:
lib/pantry/command.rb

Overview

Commands are where the task-specific functionality is implemented, the core of how Pantry works. All Commands are required to implement the #perform method, which receives the Pantry::Message requesting the Command.

All commands must be registered with Pantry before they will be available for execution. Use Pantry.add_client_command or Pantry.add_server_command to register the Command.

Defined Under Namespace

Classes: TrackResponses

Class Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(*args) ⇒ Command

Initialize this Command Due to the multiple ways a Command is instantiated (via the CLI and from the Network stack) any Command initializer must support being called with zero parameters if it expects some.



27
28
# File 'lib/pantry/command.rb', line 27

def initialize(*args)
end

Class Attribute Details

.command_configObject (readonly)

Returns the value of attribute command_config.



21
22
23
# File 'lib/pantry/command.rb', line 21

def command_config
  @command_config
end

.command_nameObject (readonly)

Returns the value of attribute command_name.



20
21
22
# File 'lib/pantry/command.rb', line 20

def command_name
  @command_name
end

Class Method Details

.command(name, &block) ⇒ Object

Expose this Command to the CLI and configure the options and information that this Command needs from the CLI to function.

See OptParsePlus for documentation



16
17
18
19
# File 'lib/pantry/command.rb', line 16

def command(name, &block)
  @command_name   = name
  @command_config = block
end

.message_typeObject

The Type of this command, used to differentiate Messages. Defaults to the full scope of the name, though with the special

case of removing any “Pantry” related scoping such as Pantry
and Pantry::Commands

This value must be unique across the system or the messages will not be processed reliably.

Override this for a custom name.



134
135
136
# File 'lib/pantry/command.rb', line 134

def self.message_type
  self.name.gsub(/Pantry::Commands::/, '').gsub(/Pantry::/, '')
end

Instance Method Details

#finishedObject

Notify all listeners that this command has completed its tasks



111
112
113
# File 'lib/pantry/command.rb', line 111

def finished
  completion_future.signal(OpenStruct.new(:value => nil))
end

#finished?Boolean

Is this command finished?

Returns:

  • (Boolean)


116
117
118
# File 'lib/pantry/command.rb', line 116

def finished?
  completion_future.ready?
end

#perform(message) ⇒ Object

Run whatever this command needs to do. All Command subclasses must implement this method. If the message triggering this Command expects a response, the return value of this method will be that response.



49
50
# File 'lib/pantry/command.rb', line 49

def perform(message)
end

#prepare_message(options) ⇒ Object

Set up the Message that needs to be created to send this Command to the server to be processed. Used by the CLI. This method is given the ClientFilter of which clients should respond to this message (if any) and the extra arguments given on the command line.

If work needs to be done prior to the network communication for CLI use, override method to take care of that logic.

The message returned here is then passed through the network to the appropriate recipients (Clients, Server, or both) and used to trigger #perform on said recipient.



41
42
43
# File 'lib/pantry/command.rb', line 41

def prepare_message(options)
  to_message
end

#receive_client_response(response) ⇒ Object

Handle a response from a Client Command. This will be called for each Client executing and responding to the requested Command.



80
81
82
83
# File 'lib/pantry/command.rb', line 80

def receive_client_response(response)
  Pantry.ui.say("Response from #{response.from}:")
  Pantry.ui.say(response.body.inspect)
end

#receive_response(response) ⇒ Object

When a message comes back from the server as a response to or because of this command’s #perform, the command object on the CLI will receive that message here. This method will dispatch to either #receive_server_response or #receive_client_response depending on the type of Command run. In most cases, Commands should override the server/client specific receivers. Only override this method to fully customize Message response handling.



58
59
60
61
62
63
64
65
66
67
68
69
# File 'lib/pantry/command.rb', line 58

def receive_response(response)
  @response_tracker ||= TrackResponses.new
  @response_tracker.new_response(response)

  if @response_tracker.from_server?
    receive_server_response(response)
    finished
  elsif @response_tracker.from_client?
    receive_client_response(response)
    finished if @response_tracker.all_response_received?
  end
end

#receive_server_response(response) ⇒ Object

Handle a response from a Server Command. Override this for specific handling of Server Command responses.



73
74
75
76
# File 'lib/pantry/command.rb', line 73

def receive_server_response(response)
  Pantry.ui.say("Server response:")
  Pantry.ui.say(response.body.inspect)
end

#send_request(message) ⇒ Object

Send a request out, returning the Future which will eventually contain the response Message



87
88
89
# File 'lib/pantry/command.rb', line 87

def send_request(message)
  @server_or_client.send_request(message)
end

#send_request!(message) ⇒ Object

Send a request out and wait for the response. Will return the response once it is received.

This is a blocking call.



95
96
97
# File 'lib/pantry/command.rb', line 95

def send_request!(message)
  send_request(message).value
end

#server_or_clientObject Also known as: server, client

Get the server or client object handling this command



148
149
150
# File 'lib/pantry/command.rb', line 148

def server_or_client
  @server_or_client
end

#server_or_client=(server_or_client) ⇒ Object Also known as: client=, server=

Set a link back to the Server or Client that’s handling this command. This will be set by the CommandHandler before calling #perform.



141
142
143
# File 'lib/pantry/command.rb', line 141

def server_or_client=(server_or_client)
  @server_or_client = server_or_client
end

#to_messageObject

Create a new Message from the information in the current Command



100
101
102
# File 'lib/pantry/command.rb', line 100

def to_message
  Pantry::Message.new(self.class.message_type)
end

#wait_for_finish(timeout = nil) ⇒ Object

Blocking call that returns when the command has completed Can be given a timeout (in seconds) to wait for a response



106
107
108
# File 'lib/pantry/command.rb', line 106

def wait_for_finish(timeout = nil)
  completion_future.value(timeout)
end