ap4r 0.1.0 → 0.1.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,15 @@
1
+ ---
2
+ store:
3
+ type: disk
4
+ drb:
5
+ host:
6
+ port: 6438
7
+ acl: allow 127.0.0.1 allow 10.0.0.0/8
8
+ dispatchers:
9
+ -
10
+ targets: queue.*
11
+ threads: 1
12
+ #carriers:
13
+ # -
14
+ # source_uri: druby://another.host.local:6438
15
+ # threads: 1
@@ -1,9 +1,9 @@
1
1
  ---
2
2
  store:
3
- username: orca
4
3
  type: mysql
5
4
  host: localhost
6
5
  database: ap4r
6
+ username: ap4r
7
7
  password: ap4r
8
8
  drb:
9
9
  host:
@@ -11,5 +11,9 @@ drb:
11
11
  acl: allow 127.0.0.1 allow 10.0.0.0/8
12
12
  dispatchers:
13
13
  -
14
- queue: queue.orders.*
14
+ targets: queue.*
15
15
  threads: 1
16
+ #carriers:
17
+ # -
18
+ # source_uri: druby://another.host.local:6438
19
+ # threads: 1
data/lib/ap4r.rb CHANGED
@@ -1,17 +1,15 @@
1
- require 'rubygems'
2
- version = "> 0"
3
- if ARGV.size > 0 && ARGV[0][0]==95 && ARGV[0][-1]==95
4
- if Gem::Version.correct?(ARGV[0][1..-2])
5
- version = ARGV[0][1..-2]
6
- ARGV.shift
7
- end
8
- end
1
+ # Author:: Shunichi Shinohara
2
+ # Copyright:: Copyright (c) 2006 Future System Consulting Corp.
3
+ # Licence:: MIT Licence
9
4
 
10
- require_gem 'reliable-msg', version
5
+ require 'rubygems'
6
+ require_gem 'reliable-msg'
11
7
 
12
8
  hack = true
13
9
  debug_hack = true
14
10
 
11
+ require 'ap4r/version'
12
+
15
13
  if hack
16
14
  require "ap4r/queue_manager_ext"
17
15
  end
@@ -1,7 +1,14 @@
1
+ # Author:: Shunichi Shinohara
2
+ # Copyright:: Copyright (c) 2006 Future System Consulting Corp.
3
+ # Licence:: MIT Licence
4
+
1
5
  module ReliableMsg
2
6
  module MessageStore
3
7
  class Base
4
8
 
9
+ cattr_accessor :use_mysql_extention
10
+ @@use_mysql_extention = true
11
+
5
12
  def stale_queue targets
6
13
  queue_names = targets.split(/[\s;]/).
7
14
  select{|queue| !queue.empty? }.
@@ -25,5 +32,24 @@ module ReliableMsg
25
32
  end
26
33
 
27
34
  end
35
+
36
+ end
37
+ end
38
+
39
+ if ReliableMsg::MessageStore::Base.use_mysql_extention
40
+ class Mysql
41
+ alias original_query query
42
+ def query(q, &block)
43
+ maybe_result = original_query(q, &block)
44
+ puts "Mysql extention: query called by #{q}"
45
+ puts "Mysql#query returns #{maybe_result}(class: #{maybe_result.class})." if $DEBUG
46
+ return maybe_result unless block && maybe_result.kind_of?(Mysql::Result)
47
+ begin
48
+ puts "Mysql extention: about to yield result." if $DEBUG
49
+ block.call(maybe_result)
50
+ ensure
51
+ maybe_result.free
52
+ end
53
+ end
28
54
  end
29
55
  end
@@ -1,10 +1,28 @@
1
+ # Author:: Shunichi Shinohara
2
+ # Copyright:: Copyright (c) 2006 Future System Consulting Corp.
3
+ # Licence:: MIT Licence
4
+
1
5
  module ReliableMsg
6
+ # The +MultiQueue+ is a kind of clients.
7
+ # This offers two extentions to <tt>ReliableMsg::Queue</tt>
8
+ # 1. specify multiple target queues, by as comma-separated queue names.
9
+ # 1. specify prefix of a collection of queues by an asterisk at the end.
10
+ # Exapmles:
11
+ # * <tt>"a.b.c"</tt> targets single queue.
12
+ # * <tt>"a.b.c, x.y.z"</tt> targets two queues.
13
+ # * <tt>"a.b.*"</tt> targets a collection of queues such as "a.b.c", "a.b.d", etc.
14
+ # * <tt>"a.b.*, x.y.*"</tt> targets two collections.
2
15
  class MultiQueue < Client
16
+ # Creates a new +MultiQueue+ with target queues specified by +multi_queue+.
17
+ # See <tt>ReliableMsg::Queue</tt> for +options+.
3
18
  def initialize multi_queue, options = nil
4
19
  @multi_queue = multi_queue
5
20
  @options = options
6
21
  end
7
22
 
23
+ # Gets a message from target queues.
24
+ # Internally, first search a queue with the most stale message,
25
+ # and get a message from the queue by <tt>ReliableMsg::Queue#get</tt>
8
26
  def get selector = nil, &block
9
27
  queue_name = repeated {|qm|
10
28
  qm.stale_queue @multi_queue
@@ -14,6 +32,7 @@ module ReliableMsg
14
32
  queue.get selector, &block
15
33
  end
16
34
 
35
+ # Returns multi queue expression as +String+.
17
36
  def name
18
37
  @multi_queue
19
38
  end
@@ -1,3 +1,7 @@
1
+ # Author:: Shunichi Shinohara
2
+ # Copyright:: Copyright (c) 2006 Future System Consulting Corp.
3
+ # Licence:: MIT Licence
4
+
1
5
  require 'ap4r/message_store_ext'
2
6
  require 'ap4r/multi_queue'
3
7
  require 'ap4r/retention_history'
@@ -11,11 +15,13 @@ require 'thread'
11
15
  require 'pp'
12
16
 
13
17
  module ReliableMsg
14
- module LifecycleListener
18
+ module LifecycleListener #:nodoc:
15
19
 
16
20
  end
17
21
 
18
22
  class QueueManager
23
+ # Gets a queue name which has the most stale message
24
+ # in queues specified by +multi_queue+.
19
25
  def stale_queue multi_queue
20
26
  @store.stale_queue multi_queue
21
27
  end
@@ -24,7 +30,11 @@ module ReliableMsg
24
30
  alias :stop_original :stop
25
31
  alias :initialize_original :initialize
26
32
 
27
- def initialize options = nil
33
+ # Hooks original initialize method to add lifecyle listeners.
34
+ #--
35
+ # TODO: Make dispatchers and carriers lifecyle listeners
36
+ # and separate them from QueueManager.
37
+ def initialize options = nil #:notnew:
28
38
  initialize_original options
29
39
  @global_lock ||= Mutex.new
30
40
  @lifecycle_listeners = []
@@ -59,8 +69,8 @@ module ReliableMsg
59
69
  end
60
70
 
61
71
  def start_dispatchers
62
- return unless @config.disps
63
- @logger.info{ "about to start dispatchers with config #{@config.disps.to_yaml}" }
72
+ return unless @config.dispatchers
73
+ @logger.info{ "about to start dispatchers with config #{@config.dispatchers.to_yaml}" }
64
74
  @disps = ThreadGroup.new
65
75
  @config.dispatchers.each{ |conf|
66
76
  conf["threads"].to_i.times { |index|
@@ -74,6 +84,8 @@ module ReliableMsg
74
84
  begin
75
85
  mq.get{|m|
76
86
  logger.debug{"dispatcher get message\n#{m.to_yaml}"} if m
87
+ # TODO: divede into comcrete classes by protocols.
88
+
77
89
  # version 1 SOAP
78
90
  # driver = SOAP::WSDLDriverFactory.new(m[:target_url]).create_rpc_driver
79
91
  # logger.debug(driver)
@@ -135,6 +147,8 @@ module ReliableMsg
135
147
  end
136
148
  #logger.debug{ "carrier gets a message\n#{m.to_yaml}" }
137
149
 
150
+ # TODO: decide the better one, and delete another.
151
+
138
152
  #version 1: use thread fork so queue manager use a different tx
139
153
  # TODO probably should have a thread as an instance variable or in a thread local
140
154
  #Thread.fork(m) {|m|
@@ -1,9 +1,22 @@
1
+ # Author:: Shunichi Shinohara
2
+ # Copyright:: Copyright (c) 2006 Future System Consulting Corp.
3
+ # Licence:: MIT Licence
4
+
1
5
  require 'drb/drb'
2
6
 
3
7
  module ReliableMsg
4
8
  class QueueManager
5
9
  attr_reader :store, :transactions, :mutex, :config
6
10
 
11
+ # Accepts ruby code as a string, evaluates it on +self+,
12
+ # and returns the result as a formatted string.
13
+ # Formats can be one of followings.
14
+ # * <tt>:inspect</tt> : default value
15
+ # * <tt>:yaml</tt>
16
+ # * <tt>:json</tt>
17
+ # * <tt>:xml</tt>
18
+ # Apart from <tt>:inspect</tt>, format can fail depending on
19
+ # the result object.
7
20
  def eval_to_inspect code, inspect_mode = :inspect
8
21
  # TODO: too sloppy implementation
9
22
  result = Thread.new(code, inspect_mode){ |c, mode|
@@ -1,6 +1,13 @@
1
+ # Author:: Shunichi Shinohara
2
+ # Copyright:: Copyright (c) 2006 Future System Consulting Corp.
3
+ # Licence:: MIT Licence
4
+
1
5
  require 'active_support'
2
6
 
3
7
  module ReliableMsg
8
+ # This class is too much experimental.
9
+ # The aim: for performance monitoring, records unprocessed message count
10
+ # in every queues at some interval.
4
11
  class RetentionHistory
5
12
  include DRbUndumped
6
13
 
@@ -0,0 +1,11 @@
1
+ # Author:: Shunichi Shinohara
2
+ # Copyright:: Copyright (c) 2006 Future System Consulting Corp.
3
+ # Licence:: MIT Licence
4
+
5
+ module AP4R
6
+ module Script #:nodoc:
7
+ class Base
8
+ cattr_accessor :logger, :ap4r_base
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,27 @@
1
+ # Author:: Shunichi Shinohara
2
+ # Copyright:: Copyright (c) 2006 Future System Consulting Corp.
3
+ # Licence:: MIT Licence
4
+
5
+ require 'rubygems'
6
+ require 'ap4r'
7
+
8
+ module AP4R
9
+ module Script
10
+ class QueueManagerControl < Base
11
+ def start argv, options = {}
12
+ ARGV.unshift('manager', 'start')
13
+ run_rm_client
14
+ end
15
+
16
+ def stop argv, options = {}
17
+ ARGV.unshift('manager', 'stop')
18
+ run_rm_client
19
+ end
20
+
21
+ private
22
+ def run_rm_client
23
+ ReliableMsg::CLI.new.run
24
+ end
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,17 @@
1
+ # Author:: Shunichi Shinohara
2
+ # Copyright:: Copyright (c) 2006 Future System Consulting Corp.
3
+ # Licence:: MIT Licence
4
+
5
+ $:.unshift(File.join(File.dirname(__FILE__), '../../'))
6
+
7
+ require 'logger'
8
+ begin
9
+ require 'active_support'
10
+ rescue LoadError
11
+ require 'rubygems'
12
+ require_gem 'active_support'
13
+ end
14
+
15
+ require 'ap4r/script/base'
16
+ AP4R::Script::Base.logger = Logger.new(STDOUT)
17
+ AP4R::Script::Base.ap4r_base = File.join(File.dirname(__FILE__) , '../../../')
@@ -0,0 +1,65 @@
1
+ # Author:: Shunichi Shinohara
2
+ # Copyright:: Copyright (c) 2006 Future System Consulting Corp.
3
+ # Licence:: MIT Licence
4
+
5
+ require 'fileutils'
6
+ require 'optparse'
7
+
8
+ module AP4R
9
+ module Script
10
+ class WorkspaceGenerator < Base
11
+ AP4R_Directories = %w(config log script tmp)
12
+
13
+ def run argv, options
14
+ OptionParser.new {|opt|
15
+ opt.on('-m'){
16
+ # merge to rails project but not implemented yet...
17
+ }
18
+
19
+ opt.parse!(argv)
20
+ }
21
+
22
+ dir = argv.last
23
+ unless dir
24
+ logger.warn{"Specify a name of application root directory."}
25
+ exit(1)
26
+ end
27
+
28
+ root_dir = File.expand_path(dir)
29
+
30
+ logger.info{"make application root directory [#{root_dir}] ... "}
31
+ FileUtils.mkdir_p(root_dir)
32
+
33
+ logger.info{"make directories for AP4R [#{AP4R_Directories.join(", ")}] ..."}
34
+ FileUtils.mkdir_p(AP4R_Directories.map{|d| File.join(root_dir, d)})
35
+
36
+ %w(config script).each{ |recursive_copy_dir|
37
+ copy_files(File.join(ap4r_base, recursive_copy_dir),
38
+ File.join(root_dir, recursive_copy_dir))
39
+ }
40
+
41
+ logger.info{"\n[#{root_dir}] has successfully set up!\n"}
42
+
43
+ end
44
+
45
+ private
46
+ def copy_files(src_dir, dest_dir, excludes = /^\.|~$/, recursive = true)
47
+ logger.info{"copy files from #{File.expand_path(src_dir)} to #{dest_dir} ..."}
48
+ Dir.foreach(src_dir) {|name|
49
+ next if name =~ excludes
50
+ path = File.join(src_dir, name)
51
+ FileUtils.cp(path, dest_dir) if FileTest.file?(path)
52
+
53
+ if recursive && FileTest.directory?(path)
54
+ next_dest_dir = File.join(dest_dir, name)
55
+ FileUtils.mkdir_p(next_dest_dir)
56
+ copy_files(path, next_dest_dir, excludes, recursive)
57
+ end
58
+ }
59
+ end
60
+
61
+ end
62
+ end
63
+ end
64
+
65
+
@@ -1,3 +1,7 @@
1
+ # Author:: Shunichi Shinohara
2
+ # Copyright:: Copyright (c) 2006 Future System Consulting Corp.
3
+ # Licence:: MIT Licence
4
+
1
5
  require 'rubygems'
2
6
  require 'log4r'
3
7
  require 'log4r/yamlconfigurator'
@@ -0,0 +1,93 @@
1
+ # Author:: Shunichi Shinohara
2
+ # Copyright:: Copyright (c) 2006 Future System Consulting Corp.
3
+ # Licence:: MIT Licence
4
+
5
+ $KCODE = 'u'
6
+
7
+ require 'singleton'
8
+ require 'rubygems'
9
+ require 'ap4r'
10
+ require 'ap4r/util/queue_client'
11
+
12
+ class AP4R::Configuration #:nodoc:
13
+ SETTINGS_FILES_DEFAULT = %w( config/ap4r_settings.rb )
14
+
15
+ class Services #:nodoc:
16
+ include Singleton
17
+ include Enumerable
18
+
19
+ def initialize
20
+ @list = []
21
+ end
22
+
23
+ def add(*args)
24
+ client = AP4R::Util::QueueClient.new(*args)
25
+ @list << (client)
26
+ end
27
+
28
+ def each(&block)
29
+ @list.each(&block)
30
+ end
31
+ end
32
+
33
+ class << self
34
+ def setup
35
+ yield Services.instance
36
+ end
37
+
38
+ def services
39
+ Services.instance
40
+ end
41
+
42
+ def load_setting_files(settings_files = SETTINGS_FILES_DEFAULT)
43
+ settings_files.each{ |file|
44
+ load(file) if FileTest.file?(file)
45
+ }
46
+ end
47
+ end
48
+
49
+ end
50
+
51
+ # This class is TOO MUCH EXPERIMENTAL.
52
+ #
53
+ # IRM is the interactive reliable-msg shell.
54
+ class IRM
55
+ class << self
56
+ def [](name)
57
+ sym_name = name.to_sym
58
+ AP4R::Configuration.services.find{|service| service.name == sym_name }
59
+ end
60
+ end
61
+ end
62
+
63
+ #--
64
+
65
+ def each(&block)
66
+ AP4R::Configuration.services.each(&block)
67
+ end
68
+ extend Enumerable
69
+
70
+ AP4R::Configuration.load_setting_files
71
+
72
+ $original_main = self
73
+
74
+ class Object
75
+ AP4R::Configuration.services.each {|s|
76
+ module_eval <<-EOS
77
+ def #{s.name.to_s}
78
+ irb_change_workspace(IRM[:#{s.name.to_s}])
79
+ end
80
+ EOS
81
+ }
82
+
83
+ def main
84
+ irb_change_workspace($original_main)
85
+ nil
86
+ end
87
+
88
+ end
89
+
90
+ require 'irb'
91
+ IRB.start
92
+
93
+ #++