isono 0.2.1 → 0.2.2

Sign up to get free protection for your applications and to get access to all the features.
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