maxwell_agent 0.0.5 → 0.0.7

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,7 @@
1
+ module Maxwell
2
+ module Agent
3
+ class EventedWorker < Worker
4
+ include Celluloid::IO
5
+ end
6
+ end
7
+ end
@@ -1,27 +1,48 @@
1
1
  module Maxwell
2
2
  module Agent
3
3
  class Host
4
- include DynamicAttributes
4
+ attr_reader :attributes
5
+ require 'maxwell/agent/host/service'
5
6
 
6
- class Service
7
- include Work
8
- def initialize(attrs={})
9
- @hosts ||= []
7
+ class Serializer
8
+ include Coercable
9
+
10
+ coerce :services, ->(services) {
11
+ services.map { |service|
12
+ Service::Serializer.deserialize(service)
13
+ }}
14
+ def self.serialize(attrs)
15
+ attrs.services = attrs.services.map(&:serialize)
16
+ JSON.dump attrs
17
+ end
18
+
19
+ def self.deserialize(json)
20
+ hash = JSON.parse(json, symbolize_names: true)
21
+ Host.new(new.coerce_values!(hash))
10
22
  end
11
23
  end
12
24
 
25
+
13
26
  def initialize(attrs={})
14
- @services ||= []
15
- @hosts ||= []
27
+ @attributes = Attributes.new(attrs)
28
+ @attributes.services ||= []
29
+ end
30
+
31
+ def serialize
32
+ Serializer.serialize(attributes.dup)
16
33
  end
17
34
 
35
+
18
36
  def add_service(service)
19
- self.services << service
37
+ @attributes[:services] << service
20
38
  end
21
39
 
22
- def add_host(host)
23
- self.hosts << host
40
+ def services
41
+ @attributes[:services]
24
42
  end
43
+
25
44
  end
45
+
26
46
  end
27
47
  end
48
+
@@ -0,0 +1,49 @@
1
+ module Maxwell
2
+ module Agent
3
+ class Host
4
+ class Service
5
+ extend Forwardable
6
+ attr_reader :attributes
7
+ include Work
8
+
9
+ def_delegators :attributes,
10
+ :perform_at, :perform_at=,
11
+ :last_run, :last_run=,
12
+ :frequency, :frequency=,
13
+ :work_class, :work_class=
14
+
15
+ class Serializer
16
+ include Coercable
17
+
18
+ coerce :perform_at, Time
19
+ coerce :last_run, Time
20
+
21
+ def self.serialize(attrs)
22
+ attrs.last_run = attrs.last_run.to_s if attrs.last_run
23
+ attrs.perform_at = attrs.perform_at.to_s if attrs.perform_at
24
+ JSON.dump attrs
25
+ end
26
+
27
+ def self.deserialize(json)
28
+ hash = JSON.parse(json, symbolize_names: true)
29
+ Service.new(new.coerce_values!(hash))
30
+ end
31
+ end
32
+
33
+ def initialize(attrs={})
34
+ @attributes = Attributes.new(attrs)
35
+ set_default_attrs!
36
+ end
37
+
38
+ def serialize
39
+ Serializer.serialize(attributes.dup)
40
+ end
41
+
42
+ def to_json
43
+ serialize
44
+ end
45
+
46
+ end
47
+ end
48
+ end
49
+ end
@@ -0,0 +1,11 @@
1
+ module Maxwell
2
+ module Agent
3
+ class MiddlewareRunner
4
+ include Celluloid
5
+
6
+ def invoke(work)
7
+ Agent.middleware.invoke(work)
8
+ end
9
+ end
10
+ end
11
+ end
@@ -9,6 +9,10 @@ module Maxwell
9
9
  end
10
10
  end
11
11
 
12
+ def work_type
13
+ self.class.work_type
14
+ end
15
+
12
16
  module ClassMethods
13
17
  def perform(*args)
14
18
  probe = instance(*args)
@@ -25,6 +29,14 @@ module Maxwell
25
29
  def call_handler(probe)
26
30
  probe.handle if probe.respond_to?(:handle)
27
31
  end
32
+
33
+ def work_type
34
+ @work_type ||= :non_evented
35
+ end
36
+
37
+ def work_type=(value)
38
+ @work_type = value.to_sym
39
+ end
28
40
  end
29
41
  end
30
42
  end
@@ -0,0 +1,18 @@
1
+ module Maxwell
2
+ module Agent
3
+ module RedisObjects
4
+ def redis(&block)
5
+ Agent.redis(&block)
6
+ end
7
+
8
+ def self.included(base)
9
+ base.send(:include, ::Celluloid)
10
+ end
11
+ end
12
+ end
13
+ end
14
+
15
+ require 'maxwell/agent/redis_objects/set'
16
+ require 'maxwell/agent/redis_objects/sorted_set'
17
+
18
+
@@ -0,0 +1,42 @@
1
+ module Maxwell
2
+ module Agent
3
+ module RedisObjects
4
+ class Set
5
+ include RedisObjects
6
+ attr_reader :name
7
+
8
+ def initialize(name)
9
+ @name = name
10
+ end
11
+
12
+ def add(object)
13
+ redis {|redis| redis.sadd name, object.to_json }
14
+ end
15
+
16
+ def remove(object)
17
+ redis {|redis| redis.srem name, object.to_json }
18
+ end
19
+
20
+ def all
21
+ redis {|redis| redis.smembers name}
22
+ end
23
+
24
+ def count
25
+ redis {|redis| redis.scard name }
26
+ end
27
+
28
+ def exists?(object)
29
+ if redis {|redis| redis.sismember name, object.to_json }
30
+ true
31
+ else
32
+ false
33
+ end
34
+ end
35
+
36
+ def find_by(key, value)
37
+ all.reject {|host| host if host.key != value }
38
+ end
39
+ end
40
+ end
41
+ end
42
+ end
@@ -0,0 +1,35 @@
1
+ module Maxwell
2
+ module Agent
3
+ module RedisObjects
4
+ class SortedSet
5
+ include RedisObjects
6
+ attr_reader :name
7
+
8
+ def initialize(name)
9
+ @name = name
10
+ end
11
+
12
+ def add(score, object)
13
+ redis { |redis| redis.zadd name, score, object.to_json }
14
+ end
15
+
16
+ def count
17
+ redis {|redis| redis.zcard name }
18
+ end
19
+
20
+ def all
21
+ redis {|redis| redis.zrange name, 0, -1 }
22
+ end
23
+
24
+ def first
25
+ redis { |redis| redis.zrange(name, 0, 0)[0] }
26
+ end
27
+
28
+ def remove(item)
29
+ redis { |redis| redis.zrem name, item.to_json }
30
+ end
31
+
32
+ end
33
+ end
34
+ end
35
+ end
@@ -1,6 +1,9 @@
1
1
  require 'maxwell/agent/worker'
2
+ require 'maxwell/agent/standard_worker'
3
+ require 'maxwell/agent/evented_worker'
2
4
  require 'maxwell/agent/scheduler'
3
5
  require 'maxwell/agent/work_schedule'
6
+ require 'maxwell/agent/middleware_runner'
4
7
 
5
8
  module Maxwell
6
9
  module Agent
@@ -12,25 +15,25 @@ module Maxwell
12
15
  Agent.configuration.worker_concurrency
13
16
  end
14
17
 
15
- supervise Agent::WorkSchedule, as: :work_schedule
16
- pool Agent::Worker, as: :worker, size: worker_pool_size
17
- supervise Agent::Scheduler, as: :scheduler
18
-
19
- def [](actor_name)
20
- @registry[actor_name]
21
- end
22
-
23
18
  def initialize(opts)
24
19
  super
25
- wait_for_actor_boot
20
+
21
+ pool Agent::MiddlewareRunner, size: self.class.worker_pool_size
22
+ supervise_as :work_schedule, Agent::WorkSchedule
23
+ pool Agent::StandardWorker, as: :worker, size: self.class.worker_pool_size
24
+ supervise_as :evented_worker, Agent::EventedWorker
25
+ supervise_as :scheduler, Agent::Scheduler,
26
+ work_schedule: self[:work_schedule],
27
+ worker: self[:worker],
28
+ evented_worker: self[:evented_worker]
29
+
30
+
31
+ self[:scheduler].async.run
32
+
26
33
  end
27
34
 
28
- def wait_for_actor_boot
29
- loop do
30
- break if self[:work_schedule] &&
31
- self[:worker] &&
32
- self[:scheduler]
33
- end
35
+ def [](actor_name)
36
+ @registry[actor_name]
34
37
  end
35
38
  end
36
39
  end
@@ -3,15 +3,16 @@ module Maxwell
3
3
  class Scheduler
4
4
  include Celluloid
5
5
 
6
- def initialize
7
- async.run
8
- end
6
+ attr_reader :work_schedule, :evented_worker, :worder
9
7
 
10
- def work_schedule
11
- runner[:work_schedule]
8
+ def initialize(opts={})
9
+ @work_schedule ||= opts.fetch(:work_schedule)
10
+ @evented_worker ||= opts.fetch(:evented_worker)
11
+ @worker ||= opts.fetch(:worker)
12
12
  end
13
13
 
14
14
  def run
15
+ set_links
15
16
  loop do
16
17
  sleep Agent.configuration.work_poll
17
18
  schedule_work
@@ -19,16 +20,19 @@ module Maxwell
19
20
  end
20
21
 
21
22
  def schedule_work
22
- work = work_schedule.get
23
- worker.async.perform(work) if work
24
- end
25
-
26
- def worker
27
- runner[:worker]
23
+ if work = work_schedule.get
24
+ if work.evented?
25
+ evented_worker.async.perform(work)
26
+ else
27
+ worker.async.perform(work)
28
+ end
29
+ end
28
30
  end
29
-
30
- def runner
31
- links.detect {|link| Celluloid::SupervisionGroup === link }
31
+ private
32
+ def set_links
33
+ link(@evented_worker)
34
+ link(@worker)
35
+ link(@work_schedule)
32
36
  end
33
37
 
34
38
  end
@@ -0,0 +1,7 @@
1
+ module Maxwell
2
+ module Agent
3
+ class StandardWorker < Worker
4
+ include Celluloid
5
+ end
6
+ end
7
+ end
@@ -1,5 +1,5 @@
1
1
  module Maxwell
2
2
  module Agent
3
- VERSION = "0.0.5"
3
+ VERSION = "0.0.7"
4
4
  end
5
5
  end
@@ -3,52 +3,10 @@ module Maxwell
3
3
  module Work
4
4
  class MissingRequiredAttributeError < StandardError; end
5
5
 
6
- REQUIRED_ATTRIBUTES = [:name, :work_class]
7
- #WORK_ATTRIBUTES = [:last_run, :frequency, :perform_at].
8
- # concat(REQUIRED_ATTRIBUTES)
9
-
10
- def self.included(base)
11
- base.send(:include, DynamicAttributes)
12
- end
13
-
14
-
15
6
  def self.load(json)
16
- work = from_json(json)
17
- work.delete('klass').constantize.new.load(work)
7
+ Agent::Host::Service::Serializer.deserialize(json)
18
8
  end
19
9
 
20
- def self.from_json(json)
21
- JSON.parse(json)
22
- end
23
-
24
- def load(attrs={})
25
- attrs.each do |key, value|
26
- send("#{key}=", value )
27
- end
28
- self
29
- end
30
-
31
- def to_json
32
- verify_required_attributes!
33
- instance_variables.inject({}) do |result, attr|
34
- result.merge(attr.to_s.gsub('@','') => instance_variable_get(attr))
35
- end.merge({klass: self.class}).to_json
36
- end
37
-
38
- def verify_required_attributes!
39
- REQUIRED_ATTRIBUTES.each do |required_attr|
40
- raise MissingRequiredAttributeError,
41
- "Must set #{required_attr}" unless send(required_attr)
42
- end
43
- end
44
-
45
- def last_run
46
- super || self.last_run = Time.new(0)
47
- end
48
-
49
- def frequency
50
- super || self.frequency = 30.minutes
51
- end
52
10
 
53
11
  def work_now?
54
12
  case
@@ -62,7 +20,7 @@ module Maxwell
62
20
  case
63
21
  when perform_at then perform_at + last_run.to_i
64
22
  when (last_run && frequency) then last_run + frequency
65
- else Time.new
23
+ else Time.new(0)
66
24
  end
67
25
  end
68
26
 
@@ -74,7 +32,22 @@ module Maxwell
74
32
  work_class.perform(*arguments)
75
33
  end
76
34
 
35
+ def evented?
36
+ work_class.work_type == :evented
37
+ end
38
+
39
+ def verify_required_attributes!
40
+ case
41
+ when work_class.nil? then raise MissingRequiredAttributeError
42
+ end
43
+ end
44
+
77
45
  private
46
+ def set_default_attrs!
47
+ self.last_run ||= Time.new(0)
48
+ self.frequency ||= 30.minutes
49
+ end
50
+
78
51
  def time_since_last_run
79
52
  Time.now.to_i - last_run.to_i
80
53
  end
@@ -87,6 +60,8 @@ module Maxwell
87
60
  def stale?
88
61
  time_since_last_run >= frequency
89
62
  end
63
+
64
+
90
65
  end
91
66
  end
92
67
  end