cylons 0.0.1 → 0.0.2

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,69 +1,68 @@
1
1
  require 'cylons/associations'
2
2
 
3
3
  module Cylons
4
-
4
+
5
5
  #this is the local application remote which is dynamically built, from the registry
6
- class RemoteProxy
6
+ class Agent
7
7
  include ::ActiveModel::Dirty
8
8
  include ::ActiveModel::AttributeMethods
9
- include ActiveAttr::Model
10
- include ActiveAttr::MassAssignment
9
+ include ::ActiveAttr::Model
10
+ include ::ActiveAttr::MassAssignment
11
11
  include ::Cylons::Attributes
12
- extend ::Cylons::Associations::ClassMethods
13
-
12
+ include ::Cylons::Associations
13
+
14
+ class_attribute :unsucessful_remote_connection_attempts
15
+ self.unsucessful_remote_connection_attempts ||= 0
16
+
17
+ class << self
18
+ attr_accessor :schema, :built
19
+ end
20
+
21
+ @built = false
22
+
23
+ def self.inherited(subklass)
24
+ ::Cylons.connect unless ::Cylons.connected?
25
+ end
26
+
27
+ def self.build_agent
28
+ load_schema
29
+ @built = true
30
+ end
31
+
32
+ def self.service_class_name
33
+ "#{name}Service"
34
+ end
35
+
14
36
  def self.load_schema
15
- @schema = ::Cylons::RemoteRegistry.get_remote_schema(self.name.downcase)
16
-
37
+ ::Cylons.logger.debug { "Loading schema for #{name}" }
38
+
39
+ @schema = ::Cylons::RemoteRegistry.get_remote_schema(name.downcase)
40
+
17
41
  @schema.remote_attributes.each do |remote_attribute|
18
42
  attribute remote_attribute.to_sym
19
43
  end
20
-
44
+
21
45
  @schema.remote_associations.each do |association_hash|
22
46
  __send__("build_remote_#{association_hash[:association_type]}_association", association_hash)
23
47
  end
24
48
  end
25
-
26
- class << self
27
- attr_accessor :remote, :schema
28
- end
29
-
30
- attr_accessor :errors
31
-
32
- def destroy
33
- return unless self.attributes["id"]
34
- result = self.class.remote.destroy(self.attributes["id"])
35
- end
36
-
37
- #have to manually update attributes if id wasnt set, i believe attr_accessible oddity so maybe can rip out later
38
- def save
39
- if self.attributes["id"]
40
- result = self.class.remote.save(self.attributes["id"], self.attributes.with_indifferent_access.slice(*self.changed))
41
- self.changed_attributes.clear
42
- else
43
- result = self.class.remote.save(nil, self.attributes.with_indifferent_access.slice(*self.changed))
44
-
45
- if result.errors.messages.present?
46
- self.assign_attributes({:errors => result.errors})
47
- else
48
- self.assign_attributes(result.attributes)
49
- end
50
- end
51
-
52
- result
53
- end
54
49
 
55
50
  def self.all
56
51
  remote.all
57
52
  end
58
-
53
+
54
+ def self.agent_namespace
55
+ @agent_namespace ||= ::Cylons::RemoteDiscovery.namespace_for_agent(self.name)
56
+ end
57
+
59
58
  def self.count
60
59
  remote.count
61
60
  end
62
-
61
+
63
62
  def self.first
64
63
  remote.first
65
64
  end
66
-
65
+
67
66
  def self.find(id)
68
67
  remote.find(id)
69
68
  end
@@ -71,29 +70,87 @@ module Cylons
71
70
  def self.last
72
71
  remote.last
73
72
  end
74
-
73
+
75
74
  def self.create(params)
76
75
  remote.create(params)
77
76
  end
78
-
77
+
79
78
  def self.search(params)
80
79
  remote.search(params)
81
80
  end
82
-
81
+
83
82
  def self.scope_by(params)
84
83
  remote.scope_by(params)
85
84
  end
86
-
85
+
87
86
  def self.first_or_create(params)
88
87
  result = remote.scope_by(params).first
89
88
  result = remote.create(params) unless result.present?
90
89
  result
91
90
  end
92
-
91
+
93
92
  def self.first_or_initialize(params)
94
93
  result = remote.scope_by(params).first
95
94
  result ||= remote.new(params) unless result.present?
96
95
  result
97
96
  end
97
+
98
+ def self.remote
99
+ remote_connection_failed! unless remote?
100
+
101
+ build_agent unless built
102
+
103
+ ::DCell::Node[agent_namespace][service_class_name.to_sym]
104
+ end
105
+
106
+ def self.remote?
107
+ agent_namespace && remote_application? && remote_service?
108
+ end
109
+
110
+ def self.remote_application?
111
+ ::DCell::Node.all.any?{ |node|
112
+ node.id == agent_namespace
113
+ }
114
+ end
115
+
116
+ def self.remote_service?
117
+ ::DCell::Node[agent_namespace].actors.include?(service_class_name.to_sym)
118
+ end
119
+
120
+ def self.remote_connection_failed!
121
+ if self.unsucessful_remote_connection_attempts > ::Cylons.config.remote_connection_failure_threshold
122
+ self.unsucessful_remote_connection_attempts = 0
123
+ raise ::Cylons::CylonsRemoteServiceNotFound, "#{service_class_name} not found"
124
+ else
125
+ sleep(::Cylons.config.remote_connection_failure_timeout)
126
+ self.unsucessful_remote_connection_attempts += 1
127
+ remote_connection_failed! unless remote?
128
+ end
129
+ end
130
+
131
+ attr_accessor :errors
132
+
133
+ def destroy
134
+ return unless self.attributes["id"]
135
+ result = self.class.remote.destroy(self.attributes["id"])
136
+ end
137
+
138
+ #have to manually update attributes if id wasnt set, i believe attr_accessible oddity so maybe can rip out later
139
+ def save
140
+ if self.attributes["id"]
141
+ result = self.class.remote.save(self.attributes["id"], self.attributes.with_indifferent_access.slice(*self.changed))
142
+ self.changed_attributes.clear
143
+ else
144
+ result = self.class.remote.save(nil, self.attributes.with_indifferent_access.slice(*self.changed))
145
+
146
+ if result.errors.messages.present?
147
+ self.assign_attributes({:errors => result.errors})
148
+ else
149
+ self.assign_attributes(result.attributes)
150
+ end
151
+ end
152
+
153
+ result
154
+ end
98
155
  end
99
- end
156
+ end
@@ -0,0 +1,26 @@
1
+ require 'active_support/ordered_options'
2
+ require 'cylons'
3
+ require 'cylons/registry_adapter'
4
+
5
+ module Cylons
6
+ class Config < ::ActiveSupport::InheritableOptions
7
+ def initialize(*args)
8
+ super(*args)
9
+
10
+ self[:address] ||= ::Cylons::Interface.primary
11
+ self[:port] ||= (9000 + rand(100))
12
+ self[:logger] ||= ::Cylons::Logging.logger
13
+ self[:model_paths] ||= nil
14
+ self[:registry] ||= nil
15
+ self[:registry_adapter] ||= :zk
16
+ self[:registry_port] ||= nil
17
+ self[:remote_namespace] ||= nil
18
+ self[:remote_connection_failure_timeout] ||= 10
19
+ self[:remote_connection_failure_threshold] ||= 2
20
+ end
21
+
22
+ def registry
23
+ @registry ||= ::Cylons::RegistryAdapter.send(self[:registry_adapter])
24
+ end
25
+ end
26
+ end
@@ -5,40 +5,36 @@ module Cylons
5
5
  class << self
6
6
  @connected ||= false
7
7
  attr_accessor :connected
8
-
8
+
9
9
  alias_method :connected?, :connected
10
10
  end
11
-
11
+
12
12
  def self.validate_configuration
13
13
  raise ::Cylons::RemoteNamespaceNotSet unless ::Cylons.configuration.remote_namespace.present?
14
14
  end
15
-
16
- #todo: FixMe
17
- #super hacky.. pass in SKIP_CYLONS=true when running rake tasks for now, ew
18
- def self.connect?
19
- ENV['SKIP_CYLONS'].present?
20
- end
21
-
15
+
22
16
  def self.connect
23
- return if connect?
17
+ return if ::Cylons.silence?
18
+
24
19
  validate_configuration
20
+
25
21
  ::Cylons.logger.info "STARTING DCELL FOR #{::Cylons.configuration.remote_namespace} NOW"
26
-
22
+
27
23
  ::Cylons.logger.info "Cylons attempting to connect to registry at #{node_address}"
28
24
 
29
25
  ::DCell.start :id => ::Cylons.configuration.remote_namespace,
30
26
  :addr => node_address,
31
27
  :registry => registry_hash
32
-
28
+
33
29
  @connected = true
34
30
  end
35
-
31
+
36
32
  def self.node_address
37
33
  "tcp://#{::Cylons.configuration.address}:#{::Cylons.configuration.port}"
38
34
  end
39
-
35
+
40
36
  def self.registry_hash
41
37
  ::Cylons.configuration.registry
42
38
  end
43
39
  end
44
- end
40
+ end
@@ -2,10 +2,11 @@ module Cylons
2
2
  class CylonsError < StandardError; end
3
3
  class CylonsConfigurationError < CylonsError; end
4
4
  class CylonsRemoteError < CylonsError; end
5
+ class CylonsRemoteServiceNotFound < CylonsError; end
5
6
  class CylonsRemoteProxyError < CylonsError; end
6
7
  class CylonsRecordNotFound < CylonsRemoteError; end
7
8
  class InvalidRegistryAdapter < CylonsConfigurationError; end
8
9
  class CouldNotConnectToRegistry < CylonsConfigurationError; end
9
10
  class RemoteNamespaceNotSet < CylonsConfigurationError; end
10
11
  class HowDoYouKillThatWhichHasNoLife < CylonsRemoteProxyError; end
11
- end
12
+ end
@@ -4,27 +4,21 @@ require 'cylons/remote_registry'
4
4
 
5
5
  module Cylons
6
6
  class LocalRegistry
7
-
8
7
  @remotes ||= []
9
8
  @loaded_remotes ||= []
10
-
9
+
11
10
  class << self
12
11
  attr_accessor :remotes, :loaded_remotes
13
12
  end
14
-
13
+
15
14
  def self.register(klass)
16
15
  @remotes << klass
17
16
  end
18
-
19
- def self.register_class?(namespaced_class_name)
20
- !defined?(namespaced_class_name.constantize)
21
- end
22
-
17
+
23
18
  def self.register_remote_schemas
24
19
  @remotes.each do |remote|
25
20
  ::Cylons::RemoteRegistry.register_remote_schema(remote)
26
21
  end
27
22
  end
28
-
29
- end
30
- end
23
+ end
24
+ end
@@ -0,0 +1,41 @@
1
+ require 'logger'
2
+
3
+ module Cylons
4
+ module Logging
5
+ def self.initialize_logger(log_target=$stdout, log_level=::Logger::INFO)
6
+ @counter ||= 0
7
+ @counter = @counter + 1
8
+ @logger = ::Logger.new(log_target)
9
+ @logger.level = log_level
10
+ @logger
11
+ end
12
+
13
+ def self.logger
14
+ defined?(@logger) ? @logger : initialize_logger
15
+ end
16
+
17
+ def self.logger=(new_logger)
18
+ @logger = new_logger
19
+ end
20
+
21
+ def logger
22
+ ::Cylons::Logging.logger
23
+ end
24
+
25
+ def log_exception(ex)
26
+ logger.error { ex.message }
27
+ logger.error { ex.backtrace[0..5].join("\n") }
28
+ logger.debug { ex.backtrace.join("\n") }
29
+ end
30
+
31
+ def log_signature
32
+ @_log_signature ||= "[#{self.class == Class ? self.name : self.class.name}]"
33
+ end
34
+
35
+ def sign_message(message)
36
+ "#{log_signature} #{message}"
37
+ end
38
+ end
39
+ end
40
+
41
+ # Taken from [protobuf](https://github.com/localshred/protobuf)
@@ -2,37 +2,16 @@ require 'cylons'
2
2
  require 'rails'
3
3
  require 'rails/railtie'
4
4
  require 'active_record'
5
- require 'ransack'
6
- require 'ransack/search'
7
- require 'ransack/adapters/active_record/base'
8
- require 'will_paginate'
5
+ require 'will_paginate/array'
9
6
 
10
7
  module Cylons
11
8
  class Railtie < ::Rails::Railtie
12
- config.after_initialize do
13
- ::Cylons::RemoteDiscovery.load_remotes unless ::Cylons.silence? || ::Cylons::RemoteDiscovery.loaded?
14
- end
15
-
16
9
  ::ActiveSupport.on_load(:cylons) do
17
10
  ::Cylons::Connection.connect unless ::Cylons.silence? || ::Cylons::RemoteDiscovery.loaded? || ::Cylons::Connection.connected?
18
- ::Cylons::RemoteDiscovery.load_remotes unless ::Cylons.silence? || ::Cylons::RemoteDiscovery.loaded?
19
- end
20
-
21
- #todo: overwrite ransack search method to auto paginate by default, or pull ransack out..
11
+ end if ::Cylons.connect?
12
+
22
13
  ::ActiveSupport.on_load(:active_record) do
23
- ::ActiveRecord::Base.extend ::Ransack::Adapters::ActiveRecord::Base
24
14
  require 'will_paginate/active_record'
25
-
26
- case ::ActiveRecord::VERSION::STRING
27
- when /^3\.0\./
28
- require 'ransack/adapters/active_record/3.0/context'
29
- when /^3\.1\./
30
- require 'ransack/adapters/active_record/3.1/context'
31
- when /^3\.2\./
32
- require 'ransack/adapters/active_record/3.2/context'
33
- else
34
- require 'ransack/adapters/active_record/context'
35
- end
36
15
  end
37
16
  end
38
- end
17
+ end
@@ -15,8 +15,17 @@ module Cylons
15
15
  def self.zk(options = {})
16
16
  zk_registry_hash = zk_defaults.dup
17
17
  zk_registry_hash[:server] = ::Cylons.configuration.registry_address if ::Cylons.configuration.registry_address
18
- zk_registry_hash[:server] = ::Cylons.configuration.registry_port if ::Cylons.configuration.registry_port
18
+ zk_registry_hash[:registry_port] = ::Cylons.configuration.registry_port if ::Cylons.configuration.registry_port
19
19
  zk_registry_hash
20
20
  end
21
+
22
+ def self.redis_defaults
23
+ {:adapter => 'redis', :port => 6379, :address => "127.0.0.1"}
24
+ end
25
+
26
+ def self.redis(options = {})
27
+ redis_registry_hash = redis_defaults.dup
28
+ redis_registry_hash
29
+ end
21
30
  end
22
31
  end
@@ -1,29 +1,18 @@
1
1
  require 'cylons/remote_registry'
2
2
  require 'cylons/active_record_extensions'
3
3
 
4
- #todo: fix
5
- #think RemoteRegistry needs to be split into a local registry, which the remote registry
6
- #is pushed information to, or pulls information from, because the damn dcell wont stop
7
- #trying to connect or throwing not configured errors when rake tasks and what not,
8
- #need complete separation of local/remote
9
- #update, think I mostly fixed issue but leaving note here becaue better separation
10
- #still needs to be done.
11
4
  module Cylons
12
5
  module Remote
13
-
14
- def self.included(klass)
15
- klass.class_eval do
16
- @remote_associations ||= []
17
-
18
- class << self
19
- attr_accessor :remote_associations
20
- end
21
-
22
- extend ::Cylons::ActiveRecordExtensions::ClassMethods
23
- extend ::Cylons::Associations::ClassMethods
24
-
25
- ::Cylons::RemoteRegistry.register(klass)
26
- end
6
+ extend ::ActiveSupport::Concern
7
+
8
+ include ::Cylons::ActiveRecordExtensions
9
+ include ::Cylons::Associations
10
+
11
+ included do
12
+ class_attribute :remote_associations
13
+ self.remote_associations = []
14
+
15
+ ::Cylons::RemoteRegistry.register(self)
27
16
  end
28
17
  end
29
- end
18
+ end