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.
Files changed (86) hide show
  1. checksums.yaml +15 -0
  2. data/README.md +31 -0
  3. data/ext/woolen_common/extconf.rb +26 -0
  4. data/ext/woolen_common/linux.h +3 -0
  5. data/ext/woolen_common/win.c +18 -0
  6. data/ext/woolen_common/win.h +4 -0
  7. data/ext/woolen_common/win/puts_color.c +139 -0
  8. data/ext/woolen_common/win/puts_color.h +5 -0
  9. data/ext/woolen_common/woolen_common.c +20 -0
  10. data/ext/woolen_common/woolen_common.h +7 -0
  11. data/lib/woolen_common.rb +39 -0
  12. data/lib/woolen_common/abstract_middleware/builder.rb +138 -0
  13. data/lib/woolen_common/abstract_middleware/map_cfg_manager.rb +52 -0
  14. data/lib/woolen_common/abstract_middleware/runner.rb +72 -0
  15. data/lib/woolen_common/action_pool_proxy.rb +28 -0
  16. data/lib/woolen_common/actionpool.rb +10 -0
  17. data/lib/woolen_common/actionpool/pool.rb +295 -0
  18. data/lib/woolen_common/actionpool/queue.rb +41 -0
  19. data/lib/woolen_common/actionpool/thread.rb +181 -0
  20. data/lib/woolen_common/addr_helper.rb +93 -0
  21. data/lib/woolen_common/cache.rb +305 -0
  22. data/lib/woolen_common/common_helper.rb +42 -0
  23. data/lib/woolen_common/config_manager.rb +36 -0
  24. data/lib/woolen_common/drb_helper.rb +125 -0
  25. data/lib/woolen_common/ffi/win32_kernel32.rb +86 -0
  26. data/lib/woolen_common/logger.rb +419 -0
  27. data/lib/woolen_common/pcap/mu/fixnum_ext.rb +8 -0
  28. data/lib/woolen_common/pcap/mu/pcap/ethernet.rb +164 -0
  29. data/lib/woolen_common/pcap/mu/pcap/header.rb +76 -0
  30. data/lib/woolen_common/pcap/mu/pcap/io_pair.rb +68 -0
  31. data/lib/woolen_common/pcap/mu/pcap/io_wrapper.rb +77 -0
  32. data/lib/woolen_common/pcap/mu/pcap/ip.rb +62 -0
  33. data/lib/woolen_common/pcap/mu/pcap/ipv4.rb +274 -0
  34. data/lib/woolen_common/pcap/mu/pcap/ipv6.rb +149 -0
  35. data/lib/woolen_common/pcap/mu/pcap/packet.rb +106 -0
  36. data/lib/woolen_common/pcap/mu/pcap/pkthdr.rb +162 -0
  37. data/lib/woolen_common/pcap/mu/pcap/reader.rb +62 -0
  38. data/lib/woolen_common/pcap/mu/pcap/reader/http_family.rb +175 -0
  39. data/lib/woolen_common/pcap/mu/pcap/sctp.rb +369 -0
  40. data/lib/woolen_common/pcap/mu/pcap/sctp/chunk.rb +124 -0
  41. data/lib/woolen_common/pcap/mu/pcap/sctp/chunk/data.rb +135 -0
  42. data/lib/woolen_common/pcap/mu/pcap/sctp/chunk/init.rb +101 -0
  43. data/lib/woolen_common/pcap/mu/pcap/sctp/chunk/init_ack.rb +69 -0
  44. data/lib/woolen_common/pcap/mu/pcap/sctp/parameter.rb +111 -0
  45. data/lib/woolen_common/pcap/mu/pcap/sctp/parameter/ip_address.rb +49 -0
  46. data/lib/woolen_common/pcap/mu/pcap/stream_packetizer.rb +74 -0
  47. data/lib/woolen_common/pcap/mu/pcap/tcp.rb +522 -0
  48. data/lib/woolen_common/pcap/mu/pcap/udp.rb +81 -0
  49. data/lib/woolen_common/pcap/mu/scenario/pcap.rb +175 -0
  50. data/lib/woolen_common/pcap/mu/scenario/pcap/fields.rb +51 -0
  51. data/lib/woolen_common/pcap/mu/scenario/pcap/rtp.rb +72 -0
  52. data/lib/woolen_common/pcap/pcap.rb +115 -0
  53. data/lib/woolen_common/pcap/readme.md +72 -0
  54. data/lib/woolen_common/ruby_ext/blank.rb +126 -0
  55. data/lib/woolen_common/ruby_ext/drb_ext.rb +7 -0
  56. data/lib/woolen_common/ruby_ext/string.rb +116 -0
  57. data/lib/woolen_common/ruby_ext/win32_ole.rb +4 -0
  58. data/lib/woolen_common/ruby_proxy.rb +5 -0
  59. data/lib/woolen_common/ruby_proxy/client.rb +305 -0
  60. data/lib/woolen_common/ruby_proxy/config.rb +44 -0
  61. data/lib/woolen_common/ruby_proxy/exceptions.rb +17 -0
  62. data/lib/woolen_common/ruby_proxy/proxy.rb +157 -0
  63. data/lib/woolen_common/ruby_proxy/proxy_global_set.rb +44 -0
  64. data/lib/woolen_common/ruby_proxy/proxy_load.rb +34 -0
  65. data/lib/woolen_common/ruby_proxy/server.rb +53 -0
  66. data/lib/woolen_common/splib.rb +36 -0
  67. data/lib/woolen_common/splib/Array.rb +33 -0
  68. data/lib/woolen_common/splib/CodeReloader.rb +59 -0
  69. data/lib/woolen_common/splib/Constants.rb +44 -0
  70. data/lib/woolen_common/splib/Conversions.rb +47 -0
  71. data/lib/woolen_common/splib/Exec.rb +132 -0
  72. data/lib/woolen_common/splib/Float.rb +13 -0
  73. data/lib/woolen_common/splib/HumanIdealRandomIterator.rb +40 -0
  74. data/lib/woolen_common/splib/Monitor.rb +214 -0
  75. data/lib/woolen_common/splib/PriorityQueue.rb +110 -0
  76. data/lib/woolen_common/splib/Sleep.rb +10 -0
  77. data/lib/woolen_common/splib/UrlShorteners.rb +48 -0
  78. data/lib/woolen_common/ssh_proxy.rb +146 -0
  79. data/lib/woolen_common/system_helper.rb +123 -0
  80. data/lib/woolen_common/system_monitor.rb +23 -0
  81. data/lib/woolen_common/system_monitor/linux_monitor.rb +250 -0
  82. data/lib/woolen_common/system_monitor/windows_monitor.rb +145 -0
  83. data/lib/woolen_common/type_helper.rb +42 -0
  84. data/lib/woolen_common/ver_ctrl_middle_ware.rb +92 -0
  85. data/lib/woolen_common/version.rb +3 -0
  86. 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