ap4r 0.1.0 → 0.1.1

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.
@@ -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
+ #++