cylons 0.0.1 → 0.0.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,5 +1,5 @@
1
1
  require 'dcell'
2
- require 'cylons/remote_proxy'
2
+
3
3
  module Cylons
4
4
  class RemoteDiscovery
5
5
  class << self
@@ -7,33 +7,44 @@ module Cylons
7
7
  attr_accessor :loaded, :loaded_remote_class_names
8
8
  alias_method :loaded?, :loaded
9
9
  end
10
-
11
- def self.load_remotes
10
+
11
+ def self.service_mappings
12
+ service_mapping_hash = {}
13
+
14
+ ::DCell::Node.all.each do |node|
15
+ namespace = node.id
16
+ filtered_nodes = (node.actors - [:node_manager, :dcell_server, :info])
17
+
18
+ remote_class_names = filtered_nodes.select{|name| name.to_s.include?("Service") }.each do |remote_class_name|
19
+ service_mapping_hash[remote_class_name] = node.id
20
+ end
21
+ end
22
+
23
+ service_mapping_hash
24
+ end
25
+
26
+ def self.namespace_for_agent(agent_name)
27
+ service_mappings["#{agent_name}Service".to_sym]
28
+ end
29
+
30
+ def self.remote_class_names
31
+ discovered_remote_class_names = []
32
+
12
33
  ::DCell::Node.all.each do |node|
13
34
  if node.id != ::Cylons.configuration.remote_namespace
14
35
  namespace = node.id
15
36
  remote_class_names = node.actors - [:node_manager, :dcell_server, :info]
16
37
  remote_class_names.select{|name| name.to_s.include?("Service") }.each do |remote_class_name|
17
- puts "Building Remote For: #{remote_class_name}"
18
- build_remote(namespace, remote_class_name)
38
+ discovered_remote_class_names << remote_class_name
19
39
  end if remote_class_names.any?
20
40
  end
21
41
  end
22
-
23
- @loaded = true
24
- end
25
-
26
- def self.build_remote(namespace, remote_class_name)
27
- proxy_class_name = remote_class_name.to_s.gsub('Service', '')
28
- Object.const_set(proxy_class_name, Class.new(Cylons::RemoteProxy))
29
-
30
- proxy_class = proxy_class_name.constantize
31
- proxy_class.load_schema
32
- proxy_class.remote = ::DCell::Node[namespace][remote_class_name]
42
+
43
+ discovered_remote_class_names
33
44
  end
34
-
45
+
35
46
  def self.remote_proxy_class_name(namespace, remote_class_name)
36
47
  "#{namespace}::#{remote_class_name.to_s}".gsub('Service', '')
37
48
  end
38
49
  end
39
- end
50
+ end
@@ -0,0 +1,32 @@
1
+ module Cylons
2
+ module RemotePagination
3
+ extend ::ActiveSupport::Concern
4
+
5
+ META_METHODS = [
6
+ :total_pages,
7
+ :current_page
8
+ ].freeze
9
+
10
+ SEARCH_OPTION_KEYS = [:opts, :options].freeze
11
+ MAX_PER_PAGE = 1000
12
+
13
+ module ClassMethods
14
+ def search(params = {})
15
+ search_options = params.extract!(*SEARCH_OPTION_KEYS)
16
+
17
+ search_options.delete_if {|k,v| v.nil? }
18
+
19
+ query_scope = params.inject(all) do |query, hash_pair|
20
+ query.__send__("by_#{hash_pair[0]}", hash_pair[1]).all
21
+ end.all
22
+
23
+ if search_options.present?
24
+ query_scope.paginate(:page => search_options[:options][:page], :per_page => search_options[:options][:per_page])
25
+ else
26
+ query_scope.paginate(:page => 1, :per_page => MAX_PER_PAGE)
27
+ end
28
+ end
29
+
30
+ end
31
+ end
32
+ end
@@ -6,44 +6,41 @@ module Cylons
6
6
  @remotes ||= []
7
7
  @loaded_remotes ||= []
8
8
  @remote_schemas ||= {}
9
-
9
+
10
10
  class << self
11
11
  attr_accessor :remotes, :loaded_remotes
12
12
  end
13
-
13
+
14
14
  def self.clear_registry
15
15
  ::DCell.registry.instance_variable_get("@global_registry").clear
16
16
  end
17
-
17
+
18
18
  def self.register(klass)
19
+ ::Cylons::Connection.connect unless ::Cylons::Connection.connected?
19
20
  @remotes << klass
20
21
  end
21
-
22
- def self.register_class?(namespaced_class_name)
23
- !defined?(namespaced_class_name.constantize)
24
- end
25
-
22
+
26
23
  def self.register_schemas
27
24
  @remotes.each do |remote|
28
25
  ::Cylons.logger.info remote
29
26
  register_remote_schema(remote)
30
27
  end
31
28
  end
32
-
29
+
33
30
  def self.remote_schemas
34
31
  ::DCell::Global.keys
35
32
  end
36
-
33
+
37
34
  def self.register_remote_schema(klass)
38
35
  ::DCell::Global["#{klass.name.downcase}_schema".to_sym] = ::Cylons::RemoteSchema.new(klass)
39
36
  end
40
-
37
+
41
38
  def self.remote_schema?(name)
42
- ::DCell::Global.has_key? "#{name}_schema".to_sym
39
+ ::DCell::Global.keys.include? "#{name}_schema".to_sym
43
40
  end
44
-
41
+
45
42
  def self.get_remote_schema(name)
46
43
  ::DCell::Global["#{name}_schema".to_sym]
47
44
  end
48
- end
49
- end
45
+ end
46
+ end
@@ -1,7 +1,7 @@
1
1
  module Cylons
2
2
  class RemoteSchema
3
3
  attr_accessor :remote_associations, :remote_attributes, :remote_search_scopes, :remote_klass
4
-
4
+
5
5
  def initialize(klass)
6
6
  @remote_attributes ||= klass.attribute_names
7
7
  @remote_associations ||= klass.remote_associations
@@ -9,4 +9,4 @@ module Cylons
9
9
  @remote_klass ||= klass.name.downcase.to_sym
10
10
  end
11
11
  end
12
- end
12
+ end
@@ -1,86 +1,78 @@
1
- require 'ransack'
2
1
  module Cylons
3
2
  module RPC
4
3
  extend ::ActiveSupport::Concern
5
-
6
- included do
7
- include ::ActiveModel::Dirty
8
- include ::Cylons::Attributes
9
-
10
- def all
11
- execute(:all)
12
- end
13
-
14
- def create(params)
15
- execute(:create, params)
16
- end
17
-
18
- def destroy(id)
19
- execute(:destroy, id)
20
- end
21
-
22
- def execute(rpc_method, request_params = {})
23
- begin
24
- @last_response = self.class.model.send(rpc_method.to_sym, request_params)
25
- rescue => e
26
- puts e.inspect
27
- @last_response = {:error => e.message}
28
- end
4
+ include ::ActiveModel::Dirty
5
+ include ::Cylons::Attributes
6
+
7
+ #need to wrap because to_a will leak connections otherwise
8
+ def all
9
+ ::ActiveRecord::Base.connection_pool.with_connection do
10
+ execute(:all).to_a
29
11
  end
30
-
31
- def execute_with_args(rpc_method, *args)
12
+ end
13
+
14
+ def create(params)
15
+ execute(:create, params)
16
+ end
17
+
18
+ def destroy(id)
19
+ execute(:destroy, id)
20
+ end
21
+
22
+ def execute(rpc_method, *args)
23
+ puts Thread.current.object_id
24
+
25
+ ::ActiveRecord::Base.connection_pool.with_connection do
26
+ puts ::ActiveRecord::Base.connection_pool.instance_variable_get("@connections").size
32
27
  begin
33
- @last_response = self.class.model.send(rpc_method.to_sym, *args)
28
+ if args.any?
29
+ @last_response = self.class.model.send(rpc_method.to_sym, *args)
30
+ else
31
+ @last_response = self.class.model.send(rpc_method.to_sym)
32
+ end
33
+
34
+ @last_response
34
35
  rescue => e
35
36
  puts e.inspect
36
- puts e.message
37
- puts @last_response.inspect
38
37
  @last_response = {:error => e.message}
39
38
  end
40
39
  end
41
-
42
- def find(id)
43
- execute(:find, id)
44
- end
45
-
46
- def first
47
- execute(:first)
48
- end
49
-
50
- def first_or_create(params)
51
- execute(:first_or_create, params)
52
- end
40
+ end
53
41
 
54
- def last
55
- execute(:last)
56
- end
57
-
58
- #todo: Refactor this, hacky
59
- def search(params)
60
- response = execute(:search, params)
61
-
62
- if response.respond_to?(:result)
63
- return response.result.to_a
64
- else
65
- return response
66
- end
67
- end
68
-
69
- def scope_by(params)
70
- execute(:scope_by, params).to_a
71
- end
72
-
73
- def save(id = nil, attributes)
74
- if(id)
75
- execute_with_args(:update, id, attributes)
76
- else
77
- execute(:create, attributes)
78
- end
42
+ def find(id)
43
+ execute(:find, id)
44
+ end
45
+
46
+ def first
47
+ execute(:first)
48
+ end
49
+
50
+ def first_or_create(params)
51
+ execute(:first_or_create, params)
52
+ end
53
+
54
+ def last
55
+ execute(:last)
56
+ end
57
+
58
+ def search(params)
59
+ response = execute(:search, params)
60
+ end
61
+
62
+ def scope_by(params)
63
+ execute(:scope_by, params)
64
+ end
65
+
66
+ def save(id = nil, attributes)
67
+ if(id)
68
+ execute(:update, id, attributes)
69
+ else
70
+ execute(:create, attributes)
79
71
  end
80
-
81
- def update(attributes)
82
- execute_with_args(:update, attributes.keys, attributes.values)
83
- end
72
+ end
73
+
74
+ def update(attributes)
75
+ execute(:update, attributes.keys, attributes.values)
84
76
  end
85
77
  end
86
- end
78
+ end
@@ -4,41 +4,51 @@ require 'cylons/remote_registry'
4
4
  module Cylons
5
5
  class ServiceManager
6
6
  def self.start
7
- ::Cylons.logger.info "LOADING REMOTES"
8
- puts "LOADING REMOTES"
9
- ::Cylons::RemoteDiscovery.load_remotes unless ::Cylons::RemoteDiscovery.loaded?
10
- puts "STARTING LOCAL REMOTE SERVICES"
11
- ::Cylons.logger.info "STARTING LOCAL REMOTE SERVICES"
7
+ ::Cylons.logger.info "STARTING CYLON SERVICES"
12
8
  start_services
13
9
  end
14
-
10
+
11
+ #todo: split supervision and building
15
12
  def self.start_service(model_klass)
16
- service_klass = build_service(model_klass)
17
- service_klass.supervise_as service_klass.name.to_sym
13
+ unless service_defined?(model_klass)
14
+ service_klass = build_service(model_klass)
15
+
16
+ service_klass.supervise_as service_klass.name.to_sym
17
+ end
18
18
  end
19
-
19
+
20
20
  def self.build_service(model_klass)
21
21
  proxy_service_class_name = "#{model_klass.name}Service"
22
- Object.const_set(proxy_service_class_name, Class.new(::Cylons::Service))
22
+ ::Object.const_set(proxy_service_class_name, ::Class.new(::Cylons::Service))
23
23
  service_klass = proxy_service_class_name.constantize
24
-
25
24
  service_klass.model = model_klass
26
- puts "REGISTERING_SERVICE_FOR #{model_klass}"
25
+
26
+ ::Cylons.logger.info "REGISTERING_SERVICE_FOR #{model_klass}"
27
+
27
28
  service_klass
28
29
  end
29
-
30
+
31
+ def self.service_defined?(model_klass)
32
+ proxy_service_class_name = "#{model_klass.name}Service"
33
+
34
+ const_defined?(:"#{proxy_service_class_name}")
35
+ end
36
+
30
37
  def self.start_services
31
38
  ::Cylons::RemoteRegistry.remotes.each do |remote|
32
39
  start_service(remote)
33
40
  end if remotes?
34
41
  end
35
-
36
- def self.service_klass_name
37
- "#{klass.name}Service"
38
- end
39
-
42
+
40
43
  def self.remotes?
41
44
  ::Cylons::RemoteRegistry.remotes.any?
42
- end
45
+ end
46
+
47
+ def self.stop
48
+ ::Cylons::RemoteRegistry.remotes.each do |remote|
49
+ ::Cylons.logger.info{ "Shutting Down #{remote.name}"}
50
+ remote.stop
51
+ end
52
+ end
43
53
  end
44
- end
54
+ end
@@ -1,3 +1,3 @@
1
1
  module Cylons
2
- VERSION = "0.0.1"
2
+ VERSION = "0.0.2"
3
3
  end
@@ -0,0 +1,24 @@
1
+ # The DCell specs start a completely separate Ruby VM running this code
2
+ # for complete integration testing using 0MQ over TCP
3
+
4
+ require 'rubygems'
5
+ require 'bundler'
6
+ require 'active_record'
7
+ Bundler.setup
8
+
9
+ require 'cylons'
10
+
11
+ ENV["RPC"] = "1"
12
+
13
+ ::Cylons.configure do |config|
14
+ #if you are running multiple machines, connect to the ZK registry machine via:
15
+ # config.registry_address = "X.X.X.X"
16
+ config.remote_namespace = "InventoryTest"
17
+ # config.registry_adapter = :zk
18
+ end
19
+
20
+ class Product < ActiveRecord::Base
21
+ include ::Cylons::Remote
22
+ end
23
+
24
+ ::Cylons::ServiceManager.start
@@ -0,0 +1,15 @@
1
+ require 'spec_helper'
2
+
3
+ describe ::Cylons::Connection do
4
+ subject { described_class }
5
+
6
+ its(:connected) { should be true }
7
+
8
+ describe ".validate_configuration" do
9
+ it "should raise error if no remote namespace present" do
10
+ ::Cylons.configuration.remote_namespace.stub(:present?).and_return(false)
11
+ expect{ subject.validate_configuration }.to raise_error ::Cylons::RemoteNamespaceNotSet
12
+ end
13
+ end
14
+
15
+ end
@@ -0,0 +1,7 @@
1
+ require 'spec_helper'
2
+
3
+ describe ::Cylons::Interface do
4
+ subject { described_class }
5
+
6
+ its(:primary) { should eq ::IPSocket.getaddress(::Socket.gethostname) }
7
+ end