reliable-msg-agent 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.
data/History.txt CHANGED
@@ -1,4 +1,12 @@
1
1
 
2
+ == 0.0.2 2011-03-19
3
+
4
+ * resources/ was includ in gemfiles.
5
+ * renamed workers to consumers.
6
+ * refactored drb connect method.
7
+ * changed Agent#call arguments 2 to 3.
8
+ * added configuration examples to resources/
9
+
2
10
  == 0.0.1 2011-03-18
3
11
 
4
12
  * minimum feature
data/Rakefile CHANGED
@@ -16,7 +16,7 @@ spec = Gem::Specification.new do |s|
16
16
  s.summary = "This(it) is agent daemon for reliable-msg queue"
17
17
  s.description = s.summary
18
18
  s.executables = Dir.glob("bin/**/*").map { |f| File.basename(f) }
19
- s.files = %w(History.txt MIT-LICENSE README.rdoc Rakefile) + Dir.glob("{bin,ext,lib,spec}/**/*")
19
+ s.files = %w(History.txt MIT-LICENSE README.rdoc Rakefile) + Dir.glob("{bin,ext,lib,resources,spec}/**/*")
20
20
  s.require_path = "lib"
21
21
  s.bindir = "bin"
22
22
  s.author = "hamajyotan"
@@ -8,6 +8,17 @@ module ReliableMsg::Agent #:nodoc:
8
8
  @logger = logger
9
9
  end
10
10
 
11
+ # The method of processing the message is defined.
12
+ #
13
+ # if the evaluation result is nil or false,
14
+ # it is considered that it failes.
15
+ #
16
+ # === Args
17
+ #
18
+ # +msg+ :: fetched message from reliable-msg queue.
19
+ # +conf+ :: consumer configurations.
20
+ # +options+ :: the options (it is still unused.)
21
+ #
11
22
  def call msg, options = {}
12
23
  raise AgentError, "#call(msg,options={}) not implemented!"
13
24
  end
@@ -0,0 +1,114 @@
1
+
2
+ require "rubygems"
3
+ require "reliable-msg/agent"
4
+
5
+ require "monitor"
6
+
7
+ module ReliableMsg::Agent #:nodoc:
8
+ class Consumers
9
+
10
+ @@default_options = {
11
+ "source_uri" => "druby://localhost:6438",
12
+ "target" => "queue.*",
13
+ "every" => 1.0,
14
+ "threads" => 1,
15
+ }.freeze
16
+
17
+ def initialize logger, options
18
+ @logger = logger
19
+ @options = options
20
+ raise AgentError, "no configuration specified." unless @options
21
+ @locker = Monitor.new
22
+ @threads = nil
23
+ end
24
+
25
+ def start
26
+ @locker.synchronize {
27
+ raise AgentError, "workers already started." if alive?
28
+
29
+ @logger.info { "--- starting workers." }
30
+
31
+ @threads = []
32
+ @options.each { |opts|
33
+ conf = @@default_options.merge(opts || {})
34
+ conf["threads"].to_i.times {
35
+ @threads << Thread.fork(conf) { |c| consuming_loop(c) }
36
+ }
37
+ }
38
+ }
39
+ end
40
+
41
+ def stop
42
+ @locker.synchronize {
43
+ raise AgentError, "workers already stopped." unless alive?
44
+
45
+ @logger.info { "--- stopping workers." }
46
+
47
+ @threads.each { |t| t[:dying] = true }
48
+ @threads.each { |t| t.wakeup rescue nil } # for immediate stop
49
+ @threads.each { |t| t.join }
50
+ @threads = nil
51
+ }
52
+ end
53
+
54
+ def alive?; @locker.synchronize { !! @threads }; end
55
+
56
+ private
57
+
58
+ def consuming_loop conf
59
+ agent = Agent.new @logger
60
+ uri, every, target = conf["source_uri"], conf["every"], conf["target"]
61
+
62
+ until Thread.current[:dying]
63
+ begin
64
+ remote_qm = DRb::DRbObject.new_with_uri uri
65
+
66
+ queue_name = connect_qm(remote_qm, target, uri, every)
67
+ next unless queue_name
68
+
69
+ fetch(queue_name, uri) { |m|
70
+ raise AgentError, "agent proc failed." unless agent.call(m, conf)
71
+ }
72
+
73
+ rescue Exception => e
74
+ @logger.warn { "error in fetch-msg/agent-proc: #{e}\n#{e.backtrace.join("\n\t")}" }
75
+ end
76
+
77
+ sleep every
78
+ end
79
+ end
80
+
81
+ def connect_qm qm, target, uri, every
82
+ error_raised = false
83
+ begin
84
+ queue_name = qm.stale_queue target
85
+ @logger.warn { "Connect to #{uri} successfully at #{Time.now}" } if error_raised
86
+ return queue_name
87
+
88
+ rescue => e
89
+ @logger.warn { "Lost connection to #{uri} at #{Time.now} - #{e.message}" } unless error_raised
90
+ error_raised = true
91
+ sleep every
92
+ return nil if Thread.current[:dying]
93
+ retry
94
+ end
95
+ end
96
+
97
+ def fetch queue_name, source_uri
98
+ ReliableMsg::Queue.new(queue_name, :drb_uri => source_uri).get { |m|
99
+ begin
100
+ tx = Thread.current[ReliableMsg::Client::THREAD_CURRENT_TX]
101
+ Thread.current[ReliableMsg::Client::THREAD_CURRENT_TX] = nil
102
+
103
+ @logger.info { "message fetched - <#{m.id}>" }
104
+ yield m
105
+
106
+ ensure
107
+ Thread.current[ReliableMsg::Client::THREAD_CURRENT_TX] = tx
108
+ end
109
+ }
110
+ end
111
+
112
+ end
113
+ end
114
+
@@ -10,7 +10,7 @@ module ReliableMsg::Agent #:nodoc:
10
10
  @logger = logger
11
11
  @options = options
12
12
 
13
- @workers = Workers.new @logger, @options
13
+ @workers = Consumers.new @logger, @options["consumers"]
14
14
  @locker = Monitor.new
15
15
  end
16
16
 
@@ -18,9 +18,9 @@ module ReliableMsg::Agent #:nodoc:
18
18
  @locker.synchronize {
19
19
  raise AgentError, "service already started." if alive?
20
20
 
21
- @logger.info { "reliable-msg agent service starting..." }
21
+ @logger.info { "*** reliable-msg agent service starting..." }
22
22
  @workers.start
23
- @logger.info { "reliable-msg agent service started." }
23
+ @logger.info { "*** reliable-msg agent service started." }
24
24
  }
25
25
  end
26
26
 
@@ -28,9 +28,9 @@ module ReliableMsg::Agent #:nodoc:
28
28
  @locker.synchronize {
29
29
  raise AgentError, "service already stopped." unless alive?
30
30
 
31
- @logger.info { "reliable-msg agent service stopping..." }
31
+ @logger.info { "*** reliable-msg agent service stopping..." }
32
32
  @workers.stop
33
- @logger.info { "reliable-msg agent service stopped." }
33
+ @logger.info { "*** reliable-msg agent service stopped." }
34
34
  }
35
35
  end
36
36
 
@@ -7,7 +7,7 @@ module ReliableMsg::Agent #:nodoc:
7
7
  unless defined? MAJOR
8
8
  MAJOR = 0
9
9
  MINOR = 0
10
- TINY = 1
10
+ TINY = 2
11
11
  PRE = nil
12
12
 
13
13
  STRING = [MAJOR, MINOR, TINY, PRE].compact.join(".")
@@ -4,11 +4,11 @@ require "reliable-msg"
4
4
 
5
5
  module ReliableMsg #:nodoc:
6
6
  module Agent #:nodoc:
7
- autoload :Version , "reliable-msg/agent/version"
7
+ autoload :Agent , "reliable-msg/agent/agent"
8
8
  autoload :AgentError, "reliable-msg/agent/error"
9
+ autoload :Consumers , "reliable-msg/agent/consumers"
9
10
  autoload :Service , "reliable-msg/agent/service"
10
- autoload :Workers , "reliable-msg/agent/workers"
11
- autoload :Agent , "reliable-msg/agent/agent"
11
+ autoload :Version , "reliable-msg/agent/version"
12
12
  end
13
13
  end
14
14
 
@@ -0,0 +1,13 @@
1
+ ---
2
+ user: agent
3
+ group: agent
4
+ logger: " Proc.new { |file| l = Logger.new(file); l.level = Logger::DEBUG; l } "
5
+ agent: /etc/reliable-msg-agent/agent.rb
6
+
7
+ consumers:
8
+ -
9
+ source_uri: druby://localhost:6438
10
+ every: 1.0
11
+ target: queue.*
12
+ threads: 1
13
+
@@ -0,0 +1,21 @@
1
+
2
+ # this script is evaluated by the context of ReliableMsg::Agnet::Agent class.
3
+
4
+ require "yaml"
5
+
6
+ #
7
+ # The method of processing the message is defined.
8
+ #
9
+ # if the evaluation result is nil or false,
10
+ # it is considered that it failes.
11
+ #
12
+ # === Args
13
+ #
14
+ # +msg+ :: fetched message from reliable-msg queue.
15
+ # +conf+ :: consumer configurations.
16
+ # +options+ :: the options (it is still unused.)
17
+ #
18
+ def call msg, conf, options = {}
19
+ @logger.info { "message received\n#{msg.to_yaml}" }
20
+ end
21
+
@@ -0,0 +1,26 @@
1
+ ---
2
+ user: agent
3
+ group: agent
4
+ logger: " Proc.new { |file| l = Logger.new(file); l.level = Logger::DEBUG; l } "
5
+ agent: /etc/reliable-msg-agent/agent.rb
6
+
7
+ consumers:
8
+ -
9
+ source_uri: druby://localhost:6438
10
+ every: 1.0
11
+ target: queue.foo
12
+ threads: 3
13
+ modify_rules:
14
+ url: " Proc.new { |url| url.port = 3001 + rand(3); url } "
15
+ http:
16
+ timeout: 30
17
+ -
18
+ source_uri: druby://localhost:6438
19
+ every: 1.0
20
+ target: queue.bar
21
+ threads: 3
22
+ modify_rules:
23
+ url: " Proc.new { |url| url.port = 4001 + rand(3); url } "
24
+ http:
25
+ timeout: 60
26
+
@@ -0,0 +1,32 @@
1
+
2
+ # this script is evaluated by the context of ReliableMsg::Agnet::Agent class.
3
+
4
+ require "yaml"
5
+ require "ap4r"
6
+
7
+ #
8
+ # The method of processing the message is defined.
9
+ #
10
+ # if the evaluation result is nil or false,
11
+ # it is considered that it failes.
12
+ #
13
+ # === Args
14
+ #
15
+ # +msg+ :: fetched message from reliable-msg queue.
16
+ # +conf+ :: consumer configurations.
17
+ # +options+ :: the options (it is still unused.)
18
+ #
19
+ def call msg, conf, options = {}
20
+
21
+ # The following codes use the mechanism of sending the message by ap4r.
22
+ dispatcher = Ap4r::Dispatchers.new nil, [], @logger
23
+
24
+ @logger.debug { "dispatcher get message\n#{msg.to_yaml}" }
25
+ response = dispatcher.send(:get_dispather_instance,
26
+ msg.headers[:dispatch_mode],
27
+ msg,
28
+ conf).call
29
+ @logger.debug { "dispatcher get response\n#{response.to_yaml}" }
30
+
31
+ end
32
+
@@ -0,0 +1,13 @@
1
+ ---
2
+ user: agent
3
+ group: agent
4
+ logger: " Proc.new { |file| l = Logger.new(file); l.level = Logger::WARN; l } "
5
+ agent: /etc/reliable-msg-agent/agent.rb
6
+
7
+ consumers:
8
+ -
9
+ source_uri: druby://localhost:6438
10
+ every: 1.0
11
+ target: queue.*
12
+ threads: 1
13
+
@@ -0,0 +1,13 @@
1
+ ---
2
+ user: agent
3
+ group: agent
4
+ logger: " Proc.new { |file| Logger.new(file, 'daily') } "
5
+ agent: /etc/reliable-msg-agent/agent.rb
6
+
7
+ consumers:
8
+ -
9
+ source_uri: druby://localhost:6438
10
+ every: 1.0
11
+ target: queue.*
12
+ threads: 1
13
+
@@ -0,0 +1,13 @@
1
+ ---
2
+ user: agent
3
+ group: agent
4
+ logger: " Proc.new { |file| Logger.new(file, 7, 10*1024*1024) } "
5
+ agent: /etc/reliable-msg-agent/agent.rb
6
+
7
+ consumers:
8
+ -
9
+ source_uri: druby://localhost:6438
10
+ every: 1.0
11
+ target: queue.*
12
+ threads: 1
13
+
@@ -0,0 +1,21 @@
1
+
2
+ # this script is evaluated by the context of ReliableMsg::Agnet::Agent class.
3
+
4
+ require "yaml"
5
+
6
+ #
7
+ # The method of processing the message is defined.
8
+ #
9
+ # if the evaluation result is nil or false,
10
+ # it is considered that it failes.
11
+ #
12
+ # === Args
13
+ #
14
+ # +msg+ :: fetched message from reliable-msg queue.
15
+ # +conf+ :: consumer configurations.
16
+ # +options+ :: the options (it is still unused.)
17
+ #
18
+ def call msg, conf, options = {}
19
+ @logger.info { "message received\n#{msg.to_yaml}" }
20
+ end
21
+
@@ -0,0 +1,41 @@
1
+ #!/bin/sh
2
+ # reliable-msg-agent start/stop script.
3
+ # chkconfig: - 85 15
4
+ # description: relilable-msg-agent start/stop script.
5
+ . /etc/rc.d/init.d/functions
6
+
7
+ prog=reliable-msg-agentd
8
+
9
+ base=reliable-msg-agent
10
+ cnf=/etc/reliable-msg-agent/agent.conf
11
+ pid=/var/reliable-msg-agent/agent.pid
12
+ log=/var/reliable-msg-agent/agent.log
13
+
14
+ start() {
15
+ echo $"Start ReliableMsg-Agent ..."
16
+ $base start -c $cnf -p $pid -l $log -d
17
+ }
18
+
19
+ stop() {
20
+ echo $"Stop ReliableMsg-Agent ..."
21
+ $base stop -p $pid
22
+ }
23
+
24
+ case "$1" in
25
+ start)
26
+ start
27
+ ;;
28
+ stop)
29
+ stop
30
+ ;;
31
+ restart)
32
+ stop
33
+ start
34
+ ;;
35
+ status)
36
+ status -p $pid $prog
37
+ ;;
38
+ *)
39
+ echo $"Usage: $prog {start|stop|restart|status}"
40
+ esac
41
+
@@ -0,0 +1,50 @@
1
+
2
+ require File.dirname(__FILE__) + "/spec_helper.rb"
3
+
4
+ require "logger"
5
+
6
+ describe ReliableMsg::Agent::Consumers do
7
+ before do
8
+ logger = Logger.new(nil)
9
+ conf = [
10
+ {
11
+ "source_uri" => "druby://localhost:6438",
12
+ "target" => "queue.*",
13
+ "every" => 1.0,
14
+ "threads" => 1,
15
+ "modify_rules" => {
16
+ "url" => "Proc.new { |url| url.host = '127.0.0.1'; url.port = 80; url }",
17
+ },
18
+ "http" => {
19
+ "timeout" => 60,
20
+ }
21
+ },
22
+ ]
23
+ @w = ReliableMsg::Agent::Consumers.new logger, conf
24
+ end
25
+
26
+ it "should be able to #start" do
27
+ @w.start
28
+ end
29
+
30
+ it "should not be alive" do
31
+ @w.alive?.should_not be_true
32
+ end
33
+
34
+ describe "When started" do
35
+ before do
36
+ @w.start
37
+ end
38
+
39
+ it "should be alive" do
40
+ @w.alive?.should be_true
41
+ end
42
+
43
+ end
44
+
45
+ after do
46
+ @w.stop rescue nil
47
+ @w = nil
48
+ end
49
+ end
50
+
data/spec/service_spec.rb CHANGED
@@ -5,8 +5,18 @@ require "logger"
5
5
 
6
6
  describe ReliableMsg::Agent::Service do
7
7
  before do
8
- l = Logger.new(nil)
9
- @s = ReliableMsg::Agent::Service.new l
8
+ logger = Logger.new(nil)
9
+ conf = {
10
+ "consumers" => [
11
+ {
12
+ "source_uri" => "druby://localhost:6438",
13
+ "target" => "queue.*",
14
+ "every" => 1.0,
15
+ "threads" => 1,
16
+ },
17
+ ],
18
+ }
19
+ @s = ReliableMsg::Agent::Service.new logger, conf
10
20
  end
11
21
 
12
22
  it "should be able to #start" do
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: reliable-msg-agent
3
3
  version: !ruby/object:Gem::Version
4
- hash: 29
4
+ hash: 27
5
5
  prerelease: false
6
6
  segments:
7
7
  - 0
8
8
  - 0
9
- - 1
10
- version: 0.0.1
9
+ - 2
10
+ version: 0.0.2
11
11
  platform: ruby
12
12
  authors:
13
13
  - hamajyotan
@@ -15,7 +15,7 @@ autorequire:
15
15
  bindir: bin
16
16
  cert_chain: []
17
17
 
18
- date: 2011-03-18 00:00:00 +09:00
18
+ date: 2011-03-19 00:00:00 +09:00
19
19
  default_executable:
20
20
  dependencies:
21
21
  - !ruby/object:Gem::Dependency
@@ -47,15 +47,24 @@ files:
47
47
  - Rakefile
48
48
  - bin/reliable-msg-agent
49
49
  - lib/reliable-msg/agent/error.rb
50
- - lib/reliable-msg/agent/workers.rb
51
50
  - lib/reliable-msg/agent/version.rb
52
51
  - lib/reliable-msg/agent/service.rb
53
52
  - lib/reliable-msg/agent/agent.rb
53
+ - lib/reliable-msg/agent/consumers.rb
54
54
  - lib/reliable-msg/agent/scripts/script_runner.rb
55
55
  - lib/reliable-msg/agent.rb
56
+ - resources/agent.conf
57
+ - resources/reliable-msg-agentd
58
+ - resources/examples/simple-agent.rb
59
+ - resources/examples/log-rotate-size-agent.conf
60
+ - resources/examples/log-level-change-agent.conf
61
+ - resources/examples/log-rotate-daily-agent.conf
62
+ - resources/examples/ap4r-dispatch-agent.rb
63
+ - resources/examples/ap4r-dispatch-agent.conf
64
+ - resources/agent.rb
56
65
  - spec/spec_helper.rb
57
66
  - spec/service_spec.rb
58
- - spec/workers_spec.rb
67
+ - spec/consumers_spec.rb
59
68
  has_rdoc: true
60
69
  homepage: https://github.com/hamajyotan/reliable-msg-agent
61
70
  licenses: []
@@ -1,90 +0,0 @@
1
-
2
- require "rubygems"
3
- require "reliable-msg/agent"
4
-
5
- require "monitor"
6
-
7
- module ReliableMsg::Agent #:nodoc:
8
- class Workers
9
-
10
- @@default_options = {
11
- :uri => "druby://localhost:6438",
12
- :every => 1.0,
13
- :target => "queue.*",
14
- :threads => 1,
15
- }.freeze
16
-
17
- def initialize logger, options = {}
18
- @logger = logger
19
- @options = options
20
- @locker = Monitor.new
21
- @threads = nil
22
- end
23
-
24
- def start
25
- @locker.synchronize {
26
- raise AgentError, "workers already started." if alive?
27
-
28
- @logger.info { "starting workers." }
29
-
30
- threads = (t = @options[:threads].to_i) <= 0 ? 1 : t
31
- @threads = (1..threads).inject([]) { |t, i|
32
- t << Thread.fork { worker_loop }
33
- }
34
- }
35
- end
36
-
37
- def stop
38
- @locker.synchronize {
39
- raise AgentError, "workers already stopped." unless alive?
40
-
41
- @logger.info { "stopping workers." }
42
-
43
- @threads.each { |t| t[:dying] = true }
44
- @threads.each { |t| t.wakeup rescue nil }
45
- @threads.each { |t| t.join }
46
- @threads = nil
47
- }
48
- end
49
-
50
- def alive?
51
- @locker.synchronize { !! @threads }
52
- end
53
-
54
- private
55
-
56
- def worker_loop
57
- agent = Agent.new @logger
58
- uri = @options[:uri] || @@default_options[:uri]
59
- every = @options[:every] || @@default_options[:every]
60
- target = @options[:target] || @@default_options[:target]
61
-
62
- until Thread.current[:dying]
63
- begin
64
- sleep every
65
-
66
- remote_qm = DRb::DRbObject.new_with_uri uri
67
- queue_name = remote_qm.stale_queue target
68
- next unless queue_name
69
-
70
- q = ReliableMsg::Queue.new queue_name, :drb_uri => uri
71
- q.get { |m|
72
- begin
73
- tx = Thread.current[ReliableMsg::Client::THREAD_CURRENT_TX]
74
- Thread.current[ReliableMsg::Client::THREAD_CURRENT_TX] = nil
75
-
76
- @logger.info { "message received - <#{m.id}>" }
77
- raise AgentError, "agent proc failed." unless agent.call(m.dup)
78
- ensure
79
- Thread.current[ReliableMsg::Client::THREAD_CURRENT_TX] = tx
80
- end
81
- }
82
- rescue Exception => e
83
- @logger.warn { "error in fetch-msg/agent-proc: #{e}\n#{e.backtrace.join("\n\t")}" }
84
- end
85
- end
86
- end
87
-
88
- end
89
- end
90
-
data/spec/workers_spec.rb DELETED
@@ -1,36 +0,0 @@
1
-
2
- require File.dirname(__FILE__) + "/spec_helper.rb"
3
-
4
- require "logger"
5
-
6
- describe ReliableMsg::Agent::Workers do
7
- before do
8
- l = Logger.new(nil)
9
- @w = ReliableMsg::Agent::Workers.new l
10
- end
11
-
12
- it "should be able to #start" do
13
- @w.start
14
- end
15
-
16
- it "should not be alive" do
17
- @w.alive?.should_not be_true
18
- end
19
-
20
- describe "When started" do
21
- before do
22
- @w.start
23
- end
24
-
25
- it "should be alive" do
26
- @w.alive?.should be_true
27
- end
28
-
29
- end
30
-
31
- after do
32
- @w.stop rescue nil
33
- @w = nil
34
- end
35
- end
36
-