woolen_common 0.0.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.
- checksums.yaml +15 -0
- data/README.md +31 -0
- data/ext/woolen_common/extconf.rb +26 -0
- data/ext/woolen_common/linux.h +3 -0
- data/ext/woolen_common/win.c +18 -0
- data/ext/woolen_common/win.h +4 -0
- data/ext/woolen_common/win/puts_color.c +139 -0
- data/ext/woolen_common/win/puts_color.h +5 -0
- data/ext/woolen_common/woolen_common.c +20 -0
- data/ext/woolen_common/woolen_common.h +7 -0
- data/lib/woolen_common.rb +39 -0
- data/lib/woolen_common/abstract_middleware/builder.rb +138 -0
- data/lib/woolen_common/abstract_middleware/map_cfg_manager.rb +52 -0
- data/lib/woolen_common/abstract_middleware/runner.rb +72 -0
- data/lib/woolen_common/action_pool_proxy.rb +28 -0
- data/lib/woolen_common/actionpool.rb +10 -0
- data/lib/woolen_common/actionpool/pool.rb +295 -0
- data/lib/woolen_common/actionpool/queue.rb +41 -0
- data/lib/woolen_common/actionpool/thread.rb +181 -0
- data/lib/woolen_common/addr_helper.rb +93 -0
- data/lib/woolen_common/cache.rb +305 -0
- data/lib/woolen_common/common_helper.rb +42 -0
- data/lib/woolen_common/config_manager.rb +36 -0
- data/lib/woolen_common/drb_helper.rb +125 -0
- data/lib/woolen_common/ffi/win32_kernel32.rb +86 -0
- data/lib/woolen_common/logger.rb +419 -0
- data/lib/woolen_common/pcap/mu/fixnum_ext.rb +8 -0
- data/lib/woolen_common/pcap/mu/pcap/ethernet.rb +164 -0
- data/lib/woolen_common/pcap/mu/pcap/header.rb +76 -0
- data/lib/woolen_common/pcap/mu/pcap/io_pair.rb +68 -0
- data/lib/woolen_common/pcap/mu/pcap/io_wrapper.rb +77 -0
- data/lib/woolen_common/pcap/mu/pcap/ip.rb +62 -0
- data/lib/woolen_common/pcap/mu/pcap/ipv4.rb +274 -0
- data/lib/woolen_common/pcap/mu/pcap/ipv6.rb +149 -0
- data/lib/woolen_common/pcap/mu/pcap/packet.rb +106 -0
- data/lib/woolen_common/pcap/mu/pcap/pkthdr.rb +162 -0
- data/lib/woolen_common/pcap/mu/pcap/reader.rb +62 -0
- data/lib/woolen_common/pcap/mu/pcap/reader/http_family.rb +175 -0
- data/lib/woolen_common/pcap/mu/pcap/sctp.rb +369 -0
- data/lib/woolen_common/pcap/mu/pcap/sctp/chunk.rb +124 -0
- data/lib/woolen_common/pcap/mu/pcap/sctp/chunk/data.rb +135 -0
- data/lib/woolen_common/pcap/mu/pcap/sctp/chunk/init.rb +101 -0
- data/lib/woolen_common/pcap/mu/pcap/sctp/chunk/init_ack.rb +69 -0
- data/lib/woolen_common/pcap/mu/pcap/sctp/parameter.rb +111 -0
- data/lib/woolen_common/pcap/mu/pcap/sctp/parameter/ip_address.rb +49 -0
- data/lib/woolen_common/pcap/mu/pcap/stream_packetizer.rb +74 -0
- data/lib/woolen_common/pcap/mu/pcap/tcp.rb +522 -0
- data/lib/woolen_common/pcap/mu/pcap/udp.rb +81 -0
- data/lib/woolen_common/pcap/mu/scenario/pcap.rb +175 -0
- data/lib/woolen_common/pcap/mu/scenario/pcap/fields.rb +51 -0
- data/lib/woolen_common/pcap/mu/scenario/pcap/rtp.rb +72 -0
- data/lib/woolen_common/pcap/pcap.rb +115 -0
- data/lib/woolen_common/pcap/readme.md +72 -0
- data/lib/woolen_common/ruby_ext/blank.rb +126 -0
- data/lib/woolen_common/ruby_ext/drb_ext.rb +7 -0
- data/lib/woolen_common/ruby_ext/string.rb +116 -0
- data/lib/woolen_common/ruby_ext/win32_ole.rb +4 -0
- data/lib/woolen_common/ruby_proxy.rb +5 -0
- data/lib/woolen_common/ruby_proxy/client.rb +305 -0
- data/lib/woolen_common/ruby_proxy/config.rb +44 -0
- data/lib/woolen_common/ruby_proxy/exceptions.rb +17 -0
- data/lib/woolen_common/ruby_proxy/proxy.rb +157 -0
- data/lib/woolen_common/ruby_proxy/proxy_global_set.rb +44 -0
- data/lib/woolen_common/ruby_proxy/proxy_load.rb +34 -0
- data/lib/woolen_common/ruby_proxy/server.rb +53 -0
- data/lib/woolen_common/splib.rb +36 -0
- data/lib/woolen_common/splib/Array.rb +33 -0
- data/lib/woolen_common/splib/CodeReloader.rb +59 -0
- data/lib/woolen_common/splib/Constants.rb +44 -0
- data/lib/woolen_common/splib/Conversions.rb +47 -0
- data/lib/woolen_common/splib/Exec.rb +132 -0
- data/lib/woolen_common/splib/Float.rb +13 -0
- data/lib/woolen_common/splib/HumanIdealRandomIterator.rb +40 -0
- data/lib/woolen_common/splib/Monitor.rb +214 -0
- data/lib/woolen_common/splib/PriorityQueue.rb +110 -0
- data/lib/woolen_common/splib/Sleep.rb +10 -0
- data/lib/woolen_common/splib/UrlShorteners.rb +48 -0
- data/lib/woolen_common/ssh_proxy.rb +146 -0
- data/lib/woolen_common/system_helper.rb +123 -0
- data/lib/woolen_common/system_monitor.rb +23 -0
- data/lib/woolen_common/system_monitor/linux_monitor.rb +250 -0
- data/lib/woolen_common/system_monitor/windows_monitor.rb +145 -0
- data/lib/woolen_common/type_helper.rb +42 -0
- data/lib/woolen_common/ver_ctrl_middle_ware.rb +92 -0
- data/lib/woolen_common/version.rb +3 -0
- metadata +210 -0
@@ -0,0 +1,52 @@
|
|
1
|
+
# -*- encoding : utf-8 -*-
|
2
|
+
require "#{File.join(File.dirname(__FILE__),'..', 'logger')}"
|
3
|
+
module WoolenCommon
|
4
|
+
module Middleware
|
5
|
+
class MapCfgManager
|
6
|
+
include WoolenCommon::ToolLogger
|
7
|
+
MERGE_TYPE_REPLACE = 'replace'
|
8
|
+
MERGE_TYPE_HASH = 'hash'
|
9
|
+
MERGE_TYPE_ARRAY = 'array'
|
10
|
+
attr_accessor :cfg_hash,:merge_type
|
11
|
+
def initialize(cfg_path,cfg_type='yml',merge_type = MERGE_TYPE_REPLACE)
|
12
|
+
case cfg_type
|
13
|
+
when 'yml'
|
14
|
+
@cfg_hash = YmlCfgManager.load cfg_path
|
15
|
+
else
|
16
|
+
error "不支持的配置文件格式:#{cfg_type}"
|
17
|
+
end
|
18
|
+
@merge_type = merge_type
|
19
|
+
end
|
20
|
+
|
21
|
+
def add_cfg(cfg_path,cfg_type='yml')
|
22
|
+
case cfg_type
|
23
|
+
when 'yml'
|
24
|
+
add_cfg = YmlCfgManager.load cfg_path
|
25
|
+
else
|
26
|
+
add_cfg = {}
|
27
|
+
error "不支持的配置文件格式:#{cfg_type}"
|
28
|
+
end
|
29
|
+
@cfg_hash.merge! add_cfg do |key,old_val,new_val|
|
30
|
+
case @merge_type
|
31
|
+
when MERGE_TYPE_REPLACE
|
32
|
+
ret_val = new_val
|
33
|
+
when MERGE_TYPE_HASH
|
34
|
+
ret_val = {:old_val=>old_val,:new_val=>new_val}
|
35
|
+
when MERGE_TYPE_ARRAY
|
36
|
+
ret_val = [new_val,old_val]
|
37
|
+
else
|
38
|
+
ret_val = old_val
|
39
|
+
end
|
40
|
+
trace "merge key :#{key},the old_val :#{old_val},the new_val :#{new_val},ret_val :#{ret_val}"
|
41
|
+
ret_val
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
class YmlCfgManager
|
47
|
+
def self.load(path)
|
48
|
+
YAML.load_file(path) || {}
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
@@ -0,0 +1,72 @@
|
|
1
|
+
# -*- encoding : utf-8 -*-
|
2
|
+
module WoolenCommon
|
3
|
+
module Middleware
|
4
|
+
# This is a basic runner for middleware stacks. This runner does
|
5
|
+
# the default expected behavior of running the middleware stacks
|
6
|
+
# in order, then reversing the order.
|
7
|
+
class Runner
|
8
|
+
# A middleware which does nothing
|
9
|
+
EMPTY_MIDDLEWARE = lambda { |env| }
|
10
|
+
|
11
|
+
# Build a new middleware runner with the given middleware
|
12
|
+
# stack.
|
13
|
+
#
|
14
|
+
# Note: This class usually doesn't need to be used directly.
|
15
|
+
# Instead, take a look at using the {Builder} class, which is
|
16
|
+
# a much friendlier way to build up a middleware stack.
|
17
|
+
#
|
18
|
+
# @param [Array] stack An array of the middleware to run.
|
19
|
+
def initialize(stack)
|
20
|
+
# We need to take the stack of middleware and initialize them
|
21
|
+
# all so they call the proper next middleware.
|
22
|
+
@kickoff = build_call_chain(stack)
|
23
|
+
end
|
24
|
+
|
25
|
+
# Run the middleware stack with the given state bag.
|
26
|
+
#
|
27
|
+
# @param [Object] env The state to pass into as the initial
|
28
|
+
# environment data. This is usual a hash of some sort.
|
29
|
+
def call(env)
|
30
|
+
# We just call the kickoff middleware, which is responsible
|
31
|
+
# for properly calling the next middleware, and so on and so
|
32
|
+
# forth.
|
33
|
+
@kickoff.call(env)
|
34
|
+
end
|
35
|
+
|
36
|
+
protected
|
37
|
+
|
38
|
+
# This takes a stack of middlewares and initializes them in a way
|
39
|
+
# that each middleware properly calls the next middleware.
|
40
|
+
def build_call_chain(stack)
|
41
|
+
# We need to instantiate the middleware stack in reverse
|
42
|
+
# order so that each middleware can have a reference to
|
43
|
+
# the next middleware it has to call. The final middleware
|
44
|
+
# is always the empty middleware, which does nothing but return.
|
45
|
+
stack.reverse.inject(EMPTY_MIDDLEWARE) do |next_middleware, current_middleware|
|
46
|
+
# Unpack the actual item
|
47
|
+
klass, args, block = current_middleware
|
48
|
+
|
49
|
+
# Default the arguments to an empty array. Otherwise in Ruby 1.8
|
50
|
+
# a `nil` args will actually pass `nil` into the class. Not what
|
51
|
+
# we want!
|
52
|
+
args ||= []
|
53
|
+
|
54
|
+
if klass.is_a?(Class)
|
55
|
+
# If the klass actually is a class, then instantiate it with
|
56
|
+
# the app and any other arguments given.
|
57
|
+
klass.new(next_middleware, *args, &block)
|
58
|
+
elsif klass.respond_to?(:call)
|
59
|
+
# Make it a lambda which calls the item then forwards up
|
60
|
+
# the chain.
|
61
|
+
lambda do |env|
|
62
|
+
klass.call(env)
|
63
|
+
next_middleware.call(env)
|
64
|
+
end
|
65
|
+
else
|
66
|
+
raise "Invalid middleware, doesn't respond to `call`: #{klass.inspect}"
|
67
|
+
end
|
68
|
+
end
|
69
|
+
end
|
70
|
+
end
|
71
|
+
end
|
72
|
+
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
# -*- encoding : utf-8 -*-
|
2
|
+
require 'singleton'
|
3
|
+
require "#{File.join(File.dirname(__FILE__), 'actionpool')}"
|
4
|
+
require "#{File.join(File.dirname(__FILE__), 'logger')}"
|
5
|
+
# 防止1.8.7不存在
|
6
|
+
class BasicObject
|
7
|
+
end
|
8
|
+
module WoolenCommon
|
9
|
+
class ActionPoolProxy < BasicObject
|
10
|
+
MAX_THREAD = 10
|
11
|
+
|
12
|
+
class << self
|
13
|
+
include WoolenCommon::ToolLogger
|
14
|
+
def get_pool
|
15
|
+
@action_pool ||= ::ActionPool::Pool.new(:min_thread => 1, :max_thread => MAX_THREAD)
|
16
|
+
end
|
17
|
+
|
18
|
+
def process(*args,&block)
|
19
|
+
trace "invoke the action pool process,args:#{args}"
|
20
|
+
begin
|
21
|
+
self.get_pool.process(*args,&block)
|
22
|
+
rescue Exception => e
|
23
|
+
error "we get the invoke process error::#{e.message}",e
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
@@ -0,0 +1,10 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
begin
|
3
|
+
require 'fastthread'
|
4
|
+
rescue LoadError
|
5
|
+
# we don't care if it's available
|
6
|
+
# just load it if it's around
|
7
|
+
end
|
8
|
+
require "#{File.join(File.dirname(__FILE__), 'splib')}"
|
9
|
+
Splib.load :Array, :Monitor
|
10
|
+
require "#{File.join(File.dirname(__FILE__),'actionpool', 'pool')}"
|
@@ -0,0 +1,295 @@
|
|
1
|
+
require "#{File.join(File.dirname(__FILE__), 'thread')}"
|
2
|
+
require "#{File.join(File.dirname(__FILE__), 'queue')}"
|
3
|
+
require 'logger'
|
4
|
+
require 'thread'
|
5
|
+
|
6
|
+
module ActionPool
|
7
|
+
# Raised when pool is closed
|
8
|
+
class PoolClosed < StandardError
|
9
|
+
end
|
10
|
+
class Pool
|
11
|
+
|
12
|
+
# :min_threads:: minimum number of threads in pool
|
13
|
+
# :max_threads:: maximum number of threads in pool
|
14
|
+
# :t_to:: thread timeout waiting for action to process
|
15
|
+
# :a_to:: maximum time action may be worked on before aborting
|
16
|
+
# :logger:: logger to print logging messages to
|
17
|
+
# Creates a new pool
|
18
|
+
def initialize(args={})
|
19
|
+
raise ArgumentError.new('Hash required for initialization') unless args.is_a?(Hash)
|
20
|
+
@logger = args[:logger] && args[:logger].is_a?(Logger) ? args[:logger] : Logger.new(nil)
|
21
|
+
@queue = ActionPool::Queue.new
|
22
|
+
@threads = []
|
23
|
+
@lock = Splib::Monitor.new
|
24
|
+
@thread_timeout = args[:t_to] ? args[:t_to] : 0
|
25
|
+
@action_timeout = args[:a_to] ? args[:a_to] : 0
|
26
|
+
@max_threads = args[:max_threads] ? args[:max_threads] : 100
|
27
|
+
@min_threads = args[:min_threads] ? args[:min_threads] : 10
|
28
|
+
@min_threads = @max_threads if @max_threads < @min_threads
|
29
|
+
@respond_to = args[:respond_thread] || ::Thread.current
|
30
|
+
@open = true
|
31
|
+
fill_pool
|
32
|
+
end
|
33
|
+
|
34
|
+
# Pool is closed
|
35
|
+
def pool_closed?
|
36
|
+
!@open
|
37
|
+
end
|
38
|
+
|
39
|
+
# Pool is open
|
40
|
+
def pool_open?
|
41
|
+
@open
|
42
|
+
end
|
43
|
+
|
44
|
+
# arg:: :open or :closed
|
45
|
+
# Set pool status
|
46
|
+
def status(arg)
|
47
|
+
@open = arg == :open
|
48
|
+
fill_pool if @open
|
49
|
+
end
|
50
|
+
|
51
|
+
# args:: :force forces a new thread.
|
52
|
+
# :nowait will create a thread if threads are waiting
|
53
|
+
# Create a new thread for pool.
|
54
|
+
# Returns newly created thread or nil if pool is at maximum size
|
55
|
+
def create_thread(*args)
|
56
|
+
return if pool_closed?
|
57
|
+
thread = nil
|
58
|
+
@lock.synchronize do
|
59
|
+
if(((size == working || args.include?(:nowait)) && @threads.size < @max_threads) || args.include?(:force))
|
60
|
+
thread = ActionPool::Thread.new(:pool => self, :respond_thread => @respond_to, :a_timeout => @action_timeout,
|
61
|
+
:t_timeout => @thread_timeout, :logger => @logger, :autostart => false)
|
62
|
+
@threads << thread
|
63
|
+
end
|
64
|
+
end
|
65
|
+
thread.start if thread
|
66
|
+
thread
|
67
|
+
end
|
68
|
+
|
69
|
+
# Fills the pool with the minimum number of threads
|
70
|
+
# Returns array of created threads
|
71
|
+
def fill_pool
|
72
|
+
threads = []
|
73
|
+
if(@open)
|
74
|
+
@lock.synchronize do
|
75
|
+
required = min - size
|
76
|
+
if(required > 0)
|
77
|
+
required.times do
|
78
|
+
thread = ActionPool::Thread.new(:pool => self, :respond_thread => @respond_to,
|
79
|
+
:a_timeout => @action_timeout, :t_timeout => @thread_timeout, :logger => @logger,
|
80
|
+
:autostart => false)
|
81
|
+
@threads << thread
|
82
|
+
threads << thread
|
83
|
+
end
|
84
|
+
end
|
85
|
+
end
|
86
|
+
end
|
87
|
+
threads.each{|t|t.start}
|
88
|
+
threads
|
89
|
+
end
|
90
|
+
|
91
|
+
# force:: force immediate stop
|
92
|
+
# Stop the pool
|
93
|
+
def shutdown(force=false)
|
94
|
+
status(:closed)
|
95
|
+
args = []
|
96
|
+
args.push(:force) if force
|
97
|
+
@logger.info("Pool is now shutting down #{force ? 'using force' : ''}")
|
98
|
+
@queue.clear if force
|
99
|
+
@queue.wait_empty
|
100
|
+
while(t = @threads.pop) do
|
101
|
+
t.stop(*args)
|
102
|
+
end
|
103
|
+
unless(force)
|
104
|
+
flush
|
105
|
+
@threads.each{|t|t.join}
|
106
|
+
end
|
107
|
+
nil
|
108
|
+
end
|
109
|
+
|
110
|
+
# action:: proc to be executed or array of [proc, [*args]]
|
111
|
+
# Add a new proc/lambda to be executed (alias for queue)
|
112
|
+
def <<(action)
|
113
|
+
case action
|
114
|
+
when Proc
|
115
|
+
queue(action)
|
116
|
+
when Array
|
117
|
+
raise ArgumentError.new('Actions to be processed by the pool must be a proc/lambda or [proc/lambda, [*args]]') unless action.size == 2 and action[0].is_a?(Proc) and action[1].is_a?(Array)
|
118
|
+
queue(action[0], action[1])
|
119
|
+
else
|
120
|
+
raise ArgumentError.new('Actions to be processed by the pool must be a proc/lambda or [proc/lambda, [*args]]')
|
121
|
+
end
|
122
|
+
nil
|
123
|
+
end
|
124
|
+
|
125
|
+
# action:: proc to be executed
|
126
|
+
# Add a new proc/lambda to be executed
|
127
|
+
def queue(action, *args)
|
128
|
+
raise PoolClosed.new("Pool #{self} is currently closed") if pool_closed?
|
129
|
+
raise ArgumentError.new('Expecting block') unless action.is_a?(Proc)
|
130
|
+
@queue << [action, args]
|
131
|
+
::Thread.pass
|
132
|
+
create_thread
|
133
|
+
end
|
134
|
+
|
135
|
+
# jobs:: Array of proc/lambdas
|
136
|
+
# Will queue a list of jobs into the pool
|
137
|
+
def add_jobs(jobs)
|
138
|
+
raise PoolClosed.new("Pool #{self} is currently closed") if pool_closed?
|
139
|
+
raise ArgumentError.new("Expecting an array but received: #{jobs.class}") unless jobs.is_a?(Array)
|
140
|
+
@queue.pause
|
141
|
+
begin
|
142
|
+
jobs.each do |job|
|
143
|
+
case job
|
144
|
+
when Proc
|
145
|
+
@queue << [job, []]
|
146
|
+
when Array
|
147
|
+
raise ArgumentError.new('Jobs to be processed by the pool must be a proc/lambda or [proc/lambda, [*args]]') unless job.size == 2 and job[0].is_a?(Proc) and job[1].is_a?(Array)
|
148
|
+
@queue << [job.shift, job]
|
149
|
+
else
|
150
|
+
raise ArgumentError.new('Jobs to be processed by the pool must be a proc/lambda or [proc/lambda, [*args]]')
|
151
|
+
end
|
152
|
+
end
|
153
|
+
ensure
|
154
|
+
num = jobs.size - @threads.select{|t|t.waiting?}.size
|
155
|
+
num.times{ create_thread(:nowait) } if num > 0
|
156
|
+
@queue.unpause
|
157
|
+
end
|
158
|
+
true
|
159
|
+
end
|
160
|
+
|
161
|
+
# block:: block to process
|
162
|
+
# Adds a block to be processed
|
163
|
+
def process(*args, &block)
|
164
|
+
queue(block, *args)
|
165
|
+
nil
|
166
|
+
end
|
167
|
+
|
168
|
+
# Current size of pool
|
169
|
+
def size
|
170
|
+
@threads.size
|
171
|
+
end
|
172
|
+
|
173
|
+
# Maximum allowed number of threads
|
174
|
+
def max
|
175
|
+
@max_threads
|
176
|
+
end
|
177
|
+
|
178
|
+
# Minimum allowed number of threads
|
179
|
+
def min
|
180
|
+
@min_threads
|
181
|
+
end
|
182
|
+
|
183
|
+
# m:: new max
|
184
|
+
# Set maximum number of threads
|
185
|
+
def max=(m)
|
186
|
+
m = m.to_i
|
187
|
+
raise ArgumentError.new('Maximum value must be greater than 0') unless m > 0
|
188
|
+
@max_threads = m
|
189
|
+
@min_threads = m if m < @min_threads
|
190
|
+
resize if m < size
|
191
|
+
m
|
192
|
+
end
|
193
|
+
|
194
|
+
# m:: new min
|
195
|
+
# Set minimum number of threads
|
196
|
+
def min=(m)
|
197
|
+
m = m.to_i
|
198
|
+
raise ArgumentError.new("Minimum value must be greater than 0 and less than or equal to maximum (#{max})") unless m > 0 && m <= max
|
199
|
+
@min_threads = m
|
200
|
+
m
|
201
|
+
end
|
202
|
+
|
203
|
+
# t:: ActionPool::Thread to remove
|
204
|
+
# Removes a thread from the pool
|
205
|
+
def remove(t)
|
206
|
+
raise ArgumentError.new('Expecting an ActionPool::Thread object') unless t.is_a?(ActionPool::Thread)
|
207
|
+
t.stop
|
208
|
+
del = @threads.include?(t)
|
209
|
+
@threads.delete(t) if del
|
210
|
+
fill_pool
|
211
|
+
del
|
212
|
+
end
|
213
|
+
|
214
|
+
# Maximum number of seconds a thread
|
215
|
+
# is allowed to idle in the pool.
|
216
|
+
# (nil means thread life is infinite)
|
217
|
+
def thread_timeout
|
218
|
+
@thread_timeout
|
219
|
+
end
|
220
|
+
|
221
|
+
# Maximum number of seconds a thread
|
222
|
+
# is allowed to work on a given action
|
223
|
+
# (nil means thread is given unlimited
|
224
|
+
# time to work on action)
|
225
|
+
def action_timeout
|
226
|
+
@action_timeout
|
227
|
+
end
|
228
|
+
|
229
|
+
# t:: timeout in seconds (nil for infinite)
|
230
|
+
# Set maximum allowed time thead may idle in pool
|
231
|
+
def thread_timeout=(t)
|
232
|
+
t = t.to_f
|
233
|
+
raise ArgumentError.new('Value must be greater than zero or nil') unless t >= 0
|
234
|
+
@thread_timeout = t
|
235
|
+
@threads.each{|thread|thread.thread_timeout = t}
|
236
|
+
t
|
237
|
+
end
|
238
|
+
|
239
|
+
# t:: timeout in seconds (nil for infinte)
|
240
|
+
# Set maximum allowed time thread may work
|
241
|
+
# on a given action
|
242
|
+
def action_timeout=(t)
|
243
|
+
t = t.to_f
|
244
|
+
raise ArgumentError.new('Value must be greater than zero or nil') unless t >= 0
|
245
|
+
@action_timeout = t
|
246
|
+
@threads.each{|thread|thread.action_timeout = t}
|
247
|
+
t
|
248
|
+
end
|
249
|
+
|
250
|
+
# Returns the next action to be processed
|
251
|
+
def action
|
252
|
+
@queue.pop
|
253
|
+
end
|
254
|
+
|
255
|
+
# Number of actions in the queue
|
256
|
+
def action_size
|
257
|
+
@queue.size
|
258
|
+
end
|
259
|
+
|
260
|
+
# Flush the thread pool. Mainly used for forcibly resizing
|
261
|
+
# the pool if existing threads have a long thread life waiting
|
262
|
+
# for input.
|
263
|
+
def flush
|
264
|
+
mon = Splib::Monitor.new
|
265
|
+
@threads.size.times{ queue{ mon.wait } }
|
266
|
+
@queue.wait_empty
|
267
|
+
sleep(0.01)
|
268
|
+
mon.broadcast
|
269
|
+
end
|
270
|
+
|
271
|
+
# Returns current number of threads in the pool working
|
272
|
+
def working
|
273
|
+
@threads.select{|t|t.running?}.size
|
274
|
+
end
|
275
|
+
|
276
|
+
def thread_stats
|
277
|
+
@threads.map{|t|[t.object_id,t.status]}
|
278
|
+
end
|
279
|
+
|
280
|
+
private
|
281
|
+
|
282
|
+
# Resize the pool
|
283
|
+
def resize
|
284
|
+
@logger.info("Pool is being resized to stated maximum: #{max}")
|
285
|
+
until(size <= max) do
|
286
|
+
t = nil
|
287
|
+
t = @threads.find{|t|t.waiting?}
|
288
|
+
t = @threads.shift unless t
|
289
|
+
t.stop
|
290
|
+
end
|
291
|
+
flush
|
292
|
+
nil
|
293
|
+
end
|
294
|
+
end
|
295
|
+
end
|