Class: Marvin::Distributed::Server
- Inherits:
-
Protocol
- Object
- EventMachine::Protocols::LineAndTextProtocol
- Protocol
- Marvin::Distributed::Server
show all
- Defined in:
- lib/marvin/distributed/server.rb
Instance Attribute Summary collapse
Attributes inherited from Protocol
#callbacks
Class Method Summary
collapse
Instance Method Summary
collapse
Methods inherited from Protocol
#handle_enable_ssl, #handle_enabled_ssl, #handle_noop, #handle_response, #host_with_port, #receive_line, #send_message, #send_message_reply, #ssl_handshake_completed
Constructor Details
#initialize(*args) ⇒ Server
21
22
23
24
|
# File 'lib/marvin/distributed/server.rb', line 21
def initialize(*args)
@configuration = args.last.is_a?(Marvin::Nash) ? args.pop : Marvin::Nash.new
super(*args)
end
|
Instance Attribute Details
#configuration ⇒ Object
Returns the value of attribute configuration.
19
20
21
|
# File 'lib/marvin/distributed/server.rb', line 19
def configuration
@configuration
end
|
#processing ⇒ Object
Returns the value of attribute processing.
19
20
21
|
# File 'lib/marvin/distributed/server.rb', line 19
def processing
@processing
end
|
Class Method Details
.next ⇒ Object
149
150
151
|
# File 'lib/marvin/distributed/server.rb', line 149
def self.next
@@free_connections.shift
end
|
.start ⇒ Object
140
141
142
143
144
145
146
147
|
# File 'lib/marvin/distributed/server.rb', line 140
def self.start
opts = Marvin::Settings.distributed || Marvin::Nash.new
opts = opts.server || Marvin::Nash.new
host = opts.host || "0.0.0.0"
port = (opts.port || 8943).to_i
logger.info "Starting distributed server on #{host}:#{port} (requires authentication = #{opts.token?})"
EventMachine.start_server(host, port, self, opts)
end
|
Instance Method Details
#authenticated? ⇒ Boolean
127
128
129
|
# File 'lib/marvin/distributed/server.rb', line 127
def authenticated?
@authenticated ||= false
end
|
#complete_processing ⇒ Object
108
109
110
111
|
# File 'lib/marvin/distributed/server.rb', line 108
def complete_processing
@@free_connections << self
@processing = false
end
|
#dispatch(client, name, options) ⇒ Object
49
50
51
52
53
54
55
56
57
|
# File 'lib/marvin/distributed/server.rb', line 49
def dispatch(client, name, options)
@processing = true
send_message(:event, {
"event-name" => name.to_s,
"event-options" => options,
"client-host" => client.host_with_port,
"client-nick" => client.nickname
})
end
|
#fails_auth! ⇒ Object
131
132
133
134
135
136
137
138
|
# File 'lib/marvin/distributed/server.rb', line 131
def fails_auth!
if requires_auth?
logger.debug "Authentication missing for distributed client"
send_message(:unauthorized)
close_connection_after_writing
return true
end
end
|
#handle_action(options = {}) ⇒ Object
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
|
# File 'lib/marvin/distributed/server.rb', line 86
def handle_action(options = {})
return if fails_auth!
logger.debug "Handling action from on #{self.host_with_port}"
target = lookup_client_for(options["client-host"])
action = options["action"]
arguments = [*options["arguments"]]
return if target.blank? || action.blank?
begin
a = action.to_sym
if self.action_whitelist.include?(a) && target.respond_to?(a)
res = target.send(a, *arguments)
if @callback_id.present? && res.respond_to?(:to_json)
send_message_reply(:noop, {"return-value" => res.to_json})
end
else
logger.warn "Client attempted invalid action #{a.inspect}"
end
rescue Exception => e
Marvin::ExceptionTracker.log(e)
end
end
|
#handle_authenticate(options = {}) ⇒ Object
59
60
61
62
63
64
65
66
67
68
|
# File 'lib/marvin/distributed/server.rb', line 59
def handle_authenticate(options = {})
return unless requires_auth?
logger.info "Attempting authentication for distributed client"
if options["token"].present? && options["token"] == configuration.token
@authenticated = true
send_message(:authenticated)
else
send_message(:authentication_failed)
end
end
|
#handle_completed(options = {}) ⇒ Object
70
71
72
73
74
|
# File 'lib/marvin/distributed/server.rb', line 70
def handle_completed(options = {})
return if fails_auth!
logger.debug "Completed message from #{self.host_with_port}"
complete_processing
end
|
#handle_exception(options = {}) ⇒ Object
76
77
78
79
80
81
82
83
84
|
# File 'lib/marvin/distributed/server.rb', line 76
def handle_exception(options = {})
return if fails_auth!
logger.info "Handling exception on #{self.host_with_port}"
name = options["name"]
message = options["message"]
backtrace = options["backtrace"]
logger.warn "Error in remote client - #{name}: #{message}"
[*backtrace].each { |line| logger.warn "--> #{line}" } if backtrace.present?
end
|
#lookup_client_for(key) ⇒ Object
117
118
119
120
121
|
# File 'lib/marvin/distributed/server.rb', line 117
def lookup_client_for(key)
Marvin::IRC::Client.connections.detect do |c|
c.host_with_port == key
end
end
|
#post_connect ⇒ Object
37
38
39
40
41
|
# File 'lib/marvin/distributed/server.rb', line 37
def post_connect
logger.debug "Remote client available, welcoming"
send_message(:welcome)
complete_processing
end
|
#post_init ⇒ Object
26
27
28
29
30
31
32
33
34
35
|
# File 'lib/marvin/distributed/server.rb', line 26
def post_init
@callbacks = {}
logger.info "Got distributed client connection with #{self.host_with_port}"
if should_use_ssl?
handle_enable_ssl
else
@connected = true
post_connect
end
end
|
#requires_auth? ⇒ Boolean
123
124
125
|
# File 'lib/marvin/distributed/server.rb', line 123
def requires_auth?
configuration.token? && !authenticated?
end
|
#start_processing ⇒ Object
113
114
115
|
# File 'lib/marvin/distributed/server.rb', line 113
def start_processing
@processing = true
end
|
#unbind ⇒ Object
43
44
45
46
47
|
# File 'lib/marvin/distributed/server.rb', line 43
def unbind
logger.info "Lost distributed client connection with #{self.host_with_port}"
@@free_connections.delete(self)
super
end
|