lib/plezi/handlers/controller_magic.rb in plezi-0.7.2 vs lib/plezi/handlers/controller_magic.rb in plezi-0.7.3
- old
+ new
@@ -191,11 +191,11 @@
# respond to save 'new' special case
return :save if request.request_method.match(/POST|PUT/) && params[:id].nil? || params[:id] == 'new'
# set DELETE method if simulated
request.request_method = 'DELETE' if params[:_method].to_s.downcase == 'delete'
# respond to special :id routing
- return params[:id].to_sym if params[:id] && available_public_methods.include?(params[:id].to_sym)
+ return params[:id].to_sym if params[:id] && self.class.available_public_methods.include?(params[:id].to_sym)
#review general cases
case request.request_method
when 'GET', 'HEAD'
return :index unless params[:id]
return :show
@@ -205,22 +205,10 @@
return :delete
end
false
end
- # lists the available methods that will be exposed to HTTP requests
- def available_public_methods
- # set class global to improve performance while checking for supported methods
- @@___available_public_methods___ ||= available_routing_methods - [:before, :after, :save, :show, :update, :delete, :initialize, :on_message, :pre_connect, :on_connect, :on_disconnect]
- end
-
- # lists the available methods that will be exposed to the HTTP router
- def available_routing_methods
- # set class global to improve performance while checking for supported methods
- @@___available_routing_methods___ ||= (((self.class.public_instance_methods - Object.public_instance_methods) - Plezi::ControllerMagic::InstanceMethods.instance_methods).delete_if {|m| m.to_s[0] == '_'})
- end
-
## WebSockets Magic
# WebSockets.
#
# Use this to brodcast an event to all 'sibling' websockets (websockets that have been created using the same Controller class).
@@ -259,11 +247,10 @@
# &block:: an optional block to be used as a callback.
#
# the method will be called asynchrnously for each sibling instance of this Controller class.
def collect method_name, *args, &block
return Plezi.callback(self, :collect, *args, &block) if block
-
r = []
ObjectSpace.each_object(self.class) { |controller| r << controller.method(method_name).call(*args) if controller.accepts_broadcast? && (controller.object_id != self.object_id) }
return r
end
@@ -278,39 +265,93 @@
end
module ClassMethods
public
+ # lists the available methods that will be exposed to HTTP requests
+ def available_public_methods
+ # set class global to improve performance while checking for supported methods
+ Plezi.cached?(self.superclass.name + "_p&rt") ? Plezi.get_cached(self.superclass.name + "_p&rt") : Plezi.cache_data(self.superclass.name + "_p&rt", available_routing_methods - [:before, :after, :save, :show, :update, :delete, :initialize, :on_message, :pre_connect, :on_connect, :on_disconnect])
+ end
+
+ # lists the available methods that will be exposed to the HTTP router
+ def available_routing_methods
+ # set class global to improve performance while checking for supported methods
+ Plezi.cached?(self.superclass.name + "_r&rt") ? Plezi.get_cached(self.superclass.name + "_r&rt") : Plezi.cache_data(self.superclass.name + "_r&rt", (((public_instance_methods - Object.public_instance_methods) - Plezi::ControllerMagic::InstanceMethods.instance_methods).delete_if {|m| m.to_s[0] == '_'}) )
+ end
+
+ # resets this controller's router, to allow for dynamic changes
+ def reset_routing_cache
+ Plezi.clear_cached(self.superclass.name + "_p&rt")
+ Plezi.clear_cached(self.superclass.name + "_r&rt")
+ available_routing_methods
+ available_public_methods
+ end
+
+ # a callback that resets the class router whenever a method (a potential route) is added
+ def method_added(id)
+ reset_routing_cache
+ end
+ # a callback that resets the class router whenever a method (a potential route) is removed
+ def method_removed(id)
+ reset_routing_cache
+ end
+ # a callback that resets the class router whenever a method (a potential route) is undefined (using #undef_method).
+ def method_undefined(id)
+ reset_routing_cache
+ end
+
# reviews the Redis connection, sets it up if it's missing and returns the Redis connection.
#
# todo: review thread status? (incase an exception killed it)
def redis_connection
+ # return false unless defined?(Redis) && ENV['PL_REDIS_URL']
+ # return @@redis if defined?(@@redis_sub_thread) && @@redis
+ # @@redis_uri ||= URI.parse(ENV['PL_REDIS_URL'])
+ # @@redis ||= Redis.new(host: @@redis_uri.host, port: @@redis_uri.port, password: @@redis_uri.password)
+ # @@redis_sub_thread = Thread.new do
+ # begin
+ # Redis.new(host: @@redis_uri.host, port: @@redis_uri.port, password: @@redis_uri.password).subscribe(redis_channel_name) do |on|
+ # on.message do |channel, msg|
+ # args = JSON.parse(msg)
+ # params = args.shift
+ # __inner_process_broadcast params['_pl_ignore_object'], params['_pl_method_broadcasted'].to_sym, args
+ # end
+ # end
+ # rescue Exception => e
+ # Plezi.error e
+ # retry
+ # end
+ # end
+ # raise "Redis connction failed for: #{ENV['PL_REDIS_URL']}" unless @@redis
+ # @@redis
return false unless defined?(Redis) && ENV['PL_REDIS_URL']
- return @@redis if defined?(@@redis_sub_thread) && @@redis
+ return Plezi.get_cached(self.superclass.name + "_b") if Plezi.cached?(self.superclass.name + "_b")
@@redis_uri ||= URI.parse(ENV['PL_REDIS_URL'])
- @@redis ||= Redis.new(host: @@redis_uri.host, port: @@redis_uri.port, password: @@redis_uri.password)
- @@redis_sub_thread = Thread.new do
+ Plezi.cache_data self.superclass.name + "_b", Redis.new(host: @@redis_uri.host, port: @@redis_uri.port, password: @@redis_uri.password)
+ raise "Redis connction failed for: #{ENV['PL_REDIS_URL']}" unless Plezi.cached?(self.superclass.name + "_b")
+ t = Thread.new do
begin
Redis.new(host: @@redis_uri.host, port: @@redis_uri.port, password: @@redis_uri.password).subscribe(redis_channel_name) do |on|
on.message do |channel, msg|
args = JSON.parse(msg)
params = args.shift
- __inner_process_broadcast params['_an_ignore_object'], params['_an_method_broadcasted'].to_sym, args
+ __inner_process_broadcast params['_pl_ignore_object'], params['_pl_method_broadcasted'].to_sym, args
end
end
rescue Exception => e
Plezi.error e
retry
end
end
- raise "Redis connction failed for: #{ENV['PL_REDIS_URL']}" unless @@redis
- @@redis
+ Plezi.cache_data self.superclass.name + "_t", t
+ Plezi.get_cached(self.superclass.name + "_b")
end
# returns a Redis channel name for this controller.
def redis_channel_name
- self.name.to_s
+ self.superclass.name.to_s
end
# broadcasts messages (methods) for this process
def __inner_process_broadcast ignore, method_name, args, &block
ObjectSpace.each_object(self) { |controller| Plezi.callback controller, method_name, *args, &block if controller.accepts_broadcast? && (!ignore || controller.uuid != ignore) }
@@ -319,10 +360,10 @@
# broadcasts messages (methods) between all processes (using Redis).
def __inner_redis_broadcast ignore, method_name, args, &block
return false unless redis_connection
raise "Radis broadcasts cannot accept blocks (no inter-process callbacks of memory sharing)!" if block
# raise "Radis broadcasts accept only one paramater, which is an optional Hash (no inter-process memory sharing)" if args.length > 1 || (args[0] && !args[0].is_a?(Hash))
- args.unshift ({_an_method_broadcasted: method_name, _an_ignore_object: ignore})
+ args.unshift ({_pl_method_broadcasted: method_name, _pl_ignore_object: ignore})
redis_connection.publish(redis_channel_name, args.to_json )
true
end
# WebSockets.