Project

General

Profile

« Previous | Next » 

Revision e82a264b

Added by Marc Dequènes over 14 years ago

  • ID e82a264b9c5f51c4eb0d1cfffb37d5628c41bc88

[evol] added session management to the cyborg server (refs #31)

View differences:

bin/mapmaker
class Zones
include CyborgServerInterface
include CyborgServerStatefulInterface
def initialize
@dns = Services::DNS::System.new
......
end
def method_missing(method_name, *args)
if api_methods.include?(method_name.to_s)
Zone.new(method_name.to_s)
session = args.shift
zone_name = method_name.to_s
if api_methods.include?(zone_name)
resource_key = "dns/zones/#{zone_name}"
session.store.get(resource_key) { Zone.new(zone_name) }
else
super
end
end
class Zone < Services::DNS::Zone
include CyborgServerEmbededInterface
include CyborgServerEmbeddedInterface
end
end
end
lib/cyborghood/cyborg/interface.rb
end
end
module CyborgServerEmbededInterface
module CyborgServerEmbeddedInterface
def self.included(base)
base.class_eval("include CyborgServerInterfaceBase")
base.export_parent_methods
end
end
module CyborgServerStatefulInterface
end
module CyborgServerInterfaceBase
NODE_PATTERN = "((?:\/|(?:\/[a-zA-Z0-9._]+)+[?=]?))"
......
def api_methods
methods = self.class.exported_methods
methods += self.class.public_instance_methods(false) if self.class.auto_export_public_instance_methods
methods -= ["initialize", "__destroy", "method_missing"]
methods & self.methods
end
......
(api_klasses.keys + api_methods).sort
end
def find_node_action(node_name)
def find_node_action(session, node_name)
node_name.gsub!(/^\//, "")
next_node_name, other_nodes_names = node_name.split('/', 2)
......
# cannot use method(), as this method may not exist at all (but still
# be usuable through metaprogramming
return lambda do |*args|
r = self.send(next_node_name, *args)
r = child_node(next_node_name, session, *args)
# dynamic tree construction: method may return a node
if r.class.ancestors.include? CyborgHood::CyborgServerInterfaceBase
if r.is_a? CyborgHood::CyborgServerInterfaceBase
r.api_nodes
else
r
end
end
end
next_node = self.send(next_node_name)
next_node = child_node(next_node_name, session)
else
# unknown method
return
......
end
# search deeper
if next_node.class.ancestors.include? CyborgHood::CyborgServerInterfaceBase
next_node.find_node_action(other_nodes_names)
if next_node.is_a? CyborgHood::CyborgServerInterfaceBase
next_node.find_node_action(session, other_nodes_names)
else
# it is not a node, so there are no children
return
end
end
def child_node(next_node_name, session, *args)
args.unshift session if self.is_a? CyborgHood::CyborgServerStatefulInterface
self.send(next_node_name, *args)
end
def has_node?(cmd)
not find_node_action(cmd).nil?
not find_node_action(nil, cmd).nil?
end
# preliminary incoming message handling
def call(cmd, data)
action = find_node_action(cmd)
def call(session, cmd, data)
action = find_node_action(session, cmd)
return "551 unknown node" if action.nil?
if data.nil?
lib/cyborghood/cyborg/server.rb
@split_data_mode = false
@split_data_cmd = nil
@split_data = []
@session = Session.new
end
def send_line(msg)
......
def receive_command(cmd, data = nil)
logger.debug "Executing command '#{cmd}' [#{identifier}]"
send_line @interface.call(cmd, data)
send_line @interface.call(@session, cmd, data)
end
def receive_error(msg)
......
def unbind
logger.debug "Conversation finished with #{identifier}"
@session.clear
end
protected
......
EmptyInterface.instance
end
end
class Session
attr_reader :store
def initialize
@store = Store.new
end
def clear
@store.values.each do |obj|
obj.__destroy if obj.respond_to? :__destroy
end
@store.clear
end
class Store < Hash
def get(key)
obj = self[key]
if obj.nil? and block_given?
obj = yield
self[key] = obj
end
obj
end
end
end
end
lib/cyborghood/services/dns.rb
@temp_file = nil
@filename = @config.dns.master_zone_pattern.gsub("#ZONE#", @zone)
at_exit {cleanup_temp}
end
def content
......
raise CyberError.new(:unrecoverable, "services/dns", "zone activation failed") unless $?.success?
end
def __destroy
cleanup_temp
end
protected
def backup_filename

Also available in: Unified diff