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 +2 -2
- data/lib/isono/logger.rb +1 -1
- data/lib/isono/node_modules/data_store.rb +27 -12
- data/lib/isono/node_modules/job_worker.rb +2 -1
- data/lib/isono/thread_pool.rb +27 -9
- data/lib/isono/version.rb +1 -1
- metadata +4 -4
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.
|
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-
|
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.
|
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.
|
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
|
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
|
-
|
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|
|
data/lib/isono/thread_pool.rb
CHANGED
@@ -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 >
|
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(
|
41
|
-
logger.
|
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
|
-
|
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
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:
|
4
|
+
hash: 19
|
5
5
|
prerelease: false
|
6
6
|
segments:
|
7
7
|
- 0
|
8
8
|
- 2
|
9
|
-
-
|
10
|
-
version: 0.2.
|
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-
|
19
|
+
date: 2011-06-02 00:00:00 +09:00
|
20
20
|
default_executable: cli
|
21
21
|
dependencies:
|
22
22
|
- !ruby/object:Gem::Dependency
|