isono 0.2.1 → 0.2.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/isono.gemspec CHANGED
@@ -2,11 +2,11 @@
2
2
 
3
3
  Gem::Specification.new do |s|
4
4
  s.name = %q{isono}
5
- s.version = "0.2.1"
5
+ s.version = "0.2.2"
6
6
 
7
7
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
8
8
  s.authors = ["axsh Ltd.", "Masahiro Fujiwara"]
9
- s.date = %q{2011-05-27}
9
+ s.date = %q{2011-06-02}
10
10
  s.default_executable = %q{cli}
11
11
  s.email = ["dev@axsh.net", "m-fujiwara@axsh.net"]
12
12
  s.executables = ["cli"]
data/lib/isono/logger.rb CHANGED
@@ -11,7 +11,7 @@ module Isono
11
11
  def self.initialize(l4r_output=Log4r::StdoutOutputter.new('stdout'))
12
12
  # Isono top level logger
13
13
  formatter = Log4r::PatternFormatter.new(:depth => 9999, # stack trace depth
14
- :pattern => "%d %c [%l]: %M",
14
+ :pattern => "%d %c thr=%h [%l]: %M",
15
15
  :date_format => "%Y/%m/%d %H:%M:%S"
16
16
  )
17
17
  l4r_output.formatter = formatter
@@ -10,6 +10,22 @@ module Isono
10
10
  config_section do
11
11
  desc "Destination database server to be connected."
12
12
  database_dsn ''
13
+
14
+ desc "Block for create new connection and its setup."
15
+ connection_block proc { |myself|
16
+ next if Sequel::DATABASES.first
17
+
18
+ db = Sequel.connect(myself.config_section.database_dsn)
19
+ DataStore.logger.info("connected to the database: #{myself.config_section.database_dsn}, #{db}")
20
+ }
21
+
22
+ desc "Block for disconnect DB connections"
23
+ disconnection_block proc { |myself|
24
+ Sequel::DATABASES.each { |v|
25
+ v.disconnect
26
+ DataStore.logger.info("disconnected database connection: #{v}")
27
+ }
28
+ }
13
29
  end
14
30
 
15
31
 
@@ -19,7 +35,8 @@ module Isono
19
35
 
20
36
  def self.pass(&blk)
21
37
  @instance.db_writer_thread.pass {
22
- @instance.db.transaction {
38
+ @instance.establish_connection
39
+ Sequel::DATABASES.first.transaction {
23
40
  blk.call
24
41
  }
25
42
  }
@@ -27,29 +44,27 @@ module Isono
27
44
 
28
45
  def self.barrier(&blk)
29
46
  @instance.db_writer_thread.barrier {
30
- @instance.db.transaction {
47
+ @instance.establish_connection
48
+ Sequel::DATABASES.first.transaction {
31
49
  blk.call
32
50
  }
33
51
  }
34
52
  end
35
53
 
36
- attr_reader :db_writer_thread, :db
54
+ attr_reader :db_writer_thread
37
55
 
38
56
  initialize_hook do
39
- @db_writer_thread = ThreadPool.new(1)
40
-
41
- @db_writer_thread.barrier {
42
- #@db = Sequel.connect(config_section.database_dsn, {:logger=>logger})
43
- @db = Sequel.connect(config_section.database_dsn)
44
- logger.debug("connected to the database: #{config_section.database_dsn}, #{@db}")
45
- }
46
-
57
+ @db_writer_thread = ThreadPool.new(1, 'DataStore')
47
58
  DataStore.create_instance(node)
48
59
  end
49
60
 
50
61
  terminate_hook do
51
62
  @db_writer_thread.shutdown
52
- @db.disconnect
63
+ config_section.disconnection_block.call(myinstance)
64
+ end
65
+
66
+ def establish_connection
67
+ config_section.connection_block.call(self)
53
68
  end
54
69
 
55
70
  end
@@ -10,11 +10,12 @@ module Isono
10
10
  JOB_CTX_KEY=:job_worker_ctx
11
11
 
12
12
  config_section do |c|
13
+ desc "Concurrency number of worker thread."
13
14
  c.concurrency = 1
14
15
  end
15
16
 
16
17
  initialize_hook do
17
- @thread_pool = ThreadPool.new(config_section.concurrency.to_i)
18
+ @thread_pool = ThreadPool.new(config_section.concurrency.to_i, 'JobWorker')
18
19
  @active_jobs = {}
19
20
 
20
21
  RpcChannel.new(node).register_endpoint("job-stats.#{node.node_id}", proc { |req, res|
@@ -8,37 +8,48 @@ module Isono
8
8
  class WorkerTerminateError < StandardError; end
9
9
  class TimeoutError < StandardError; end
10
10
 
11
- attr_reader :queue
11
+ attr_reader :queue, :name
12
12
 
13
13
  def initialize(worker_num=1, name=nil, opts={})
14
- set_instance_logger(name)
15
14
  @queue = ::Queue.new
16
15
  @name = name
17
16
  @opts = {:stucked_queue_num=>20}.merge(opts)
18
17
  @last_stuck_warn_at = Time.now
19
18
 
20
19
  @worker_threads = {}
21
- worker_num.times {
20
+ worker_num.times { |wid|
22
21
  t = Thread.new {
22
+ # Log4r::PatternFormatter can refer thread name as %h.
23
+ Thread.current[:name] = "#{name}[#{wid}/#{worker_num}]" if name
23
24
  begin
24
25
  while op = @queue.pop
25
- if @queue.size > @opts[:stucked_queue_num] && Time.now - @last_stuck_warn_at > 5.0
26
+ if @queue.size > @opts[:stucked_queue_num] && Time.now - @last_stuck_warn_at > 30.0
26
27
  logger.warn("too many stucked jobs: #{@queue.size}")
27
28
  @last_stuck_warn_at = Time.now
28
29
  end
29
-
30
+
31
+ op_start_at = Time.now
30
32
  op.call
33
+ op_elapsed = Time.now - op_start_at
34
+ on_task_end(op_start_at, op_elapsed)
31
35
  end
32
36
  rescue WorkerTerminateError
33
37
  # someone indicated to terminate this thread
34
38
  # exit from the current loop
35
39
  break
36
- rescue Exception => e
40
+ rescue ::Exception => e
37
41
  logger.error(e)
42
+ # worker thread should never die except from the
43
+ # termination using shutdown() method.
44
+ # any errors thrown by op.call will be caught here and
45
+ # back to @queue.pop.
46
+ retry
38
47
  ensure
48
+ tid = Thread.current.__id__
49
+ tname = Thread.current[:name] || Thread.current.to_s
39
50
  EM.schedule {
40
- @worker_threads.delete(Thread.current.__id__)
41
- logger.debug("#{Thread.current} is being terminated")
51
+ @worker_threads.delete(tid)
52
+ logger.info("Thread #{tname} is being terminated")
42
53
  }
43
54
  end
44
55
 
@@ -168,7 +179,14 @@ module Isono
168
179
 
169
180
 
170
181
  private
171
- def thread_loop
182
+ # This hook allows to log the task took too long time.
183
+ #
184
+ # def on_task_end(op_start_at, op_elapsed)
185
+ # if op_elapsed > 10.0
186
+ # logger.warn("Task took 10sec")
187
+ # end
188
+ # end
189
+ def on_task_end(op_start_at, op_elapsed)
172
190
  end
173
191
 
174
192
  end
data/lib/isono/version.rb CHANGED
@@ -1,5 +1,5 @@
1
1
  # -*- coding: utf-8 -*-
2
2
 
3
3
  module Isono
4
- VERSION='0.2.1'
4
+ VERSION='0.2.2'
5
5
  end
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: isono
3
3
  version: !ruby/object:Gem::Version
4
- hash: 21
4
+ hash: 19
5
5
  prerelease: false
6
6
  segments:
7
7
  - 0
8
8
  - 2
9
- - 1
10
- version: 0.2.1
9
+ - 2
10
+ version: 0.2.2
11
11
  platform: ruby
12
12
  authors:
13
13
  - axsh Ltd.
@@ -16,7 +16,7 @@ autorequire:
16
16
  bindir: bin
17
17
  cert_chain: []
18
18
 
19
- date: 2011-05-27 00:00:00 +09:00
19
+ date: 2011-06-02 00:00:00 +09:00
20
20
  default_executable: cli
21
21
  dependencies:
22
22
  - !ruby/object:Gem::Dependency