eye 0.8.celluloid15 → 0.8.pre
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.travis.yml +3 -5
- data/CHANGES.md +3 -7
- data/README.md +2 -5
- data/Rakefile +6 -6
- data/bin/leye +4 -9
- data/bin/loader_eye +15 -14
- data/examples/delayed_job.eye +3 -3
- data/examples/dependency.eye +11 -10
- data/examples/notify.eye +4 -3
- data/examples/plugin/main.eye +5 -5
- data/examples/plugin/plugin.rb +2 -10
- data/examples/process_thin.rb +8 -8
- data/examples/processes/em.rb +12 -18
- data/examples/processes/forking.rb +5 -5
- data/examples/processes/sample.rb +44 -46
- data/examples/puma.eye +8 -9
- data/examples/rbenv.eye +5 -5
- data/examples/sidekiq.eye +3 -3
- data/examples/stress_test.eye +4 -4
- data/examples/syslog.eye +1 -1
- data/examples/test.eye +2 -1
- data/examples/thin-farm.eye +8 -7
- data/examples/triggers.eye +15 -13
- data/examples/unicorn.eye +13 -12
- data/eye.gemspec +14 -16
- data/lib/eye.rb +3 -2
- data/lib/eye/application.rb +6 -5
- data/lib/eye/checker.rb +25 -44
- data/lib/eye/checker/children_count.rb +1 -1
- data/lib/eye/checker/file_ctime.rb +1 -1
- data/lib/eye/checker/http.rb +15 -13
- data/lib/eye/checker/nop.rb +0 -1
- data/lib/eye/checker/socket.rb +63 -60
- data/lib/eye/checker/ssl_socket.rb +5 -5
- data/lib/eye/child_process.rb +4 -6
- data/lib/eye/cli.rb +46 -74
- data/lib/eye/cli/commands.rb +5 -4
- data/lib/eye/cli/render.rb +41 -61
- data/lib/eye/cli/server.rb +16 -19
- data/lib/eye/client.rb +0 -1
- data/lib/eye/config.rb +33 -36
- data/lib/eye/controller.rb +3 -2
- data/lib/eye/controller/commands.rb +1 -1
- data/lib/eye/controller/helpers.rb +2 -2
- data/lib/eye/controller/load.rb +17 -19
- data/lib/eye/controller/options.rb +5 -1
- data/lib/eye/controller/send_command.rb +23 -21
- data/lib/eye/controller/status.rb +15 -17
- data/lib/eye/dsl.rb +1 -6
- data/lib/eye/dsl/application_opts.rb +3 -4
- data/lib/eye/dsl/chain.rb +2 -2
- data/lib/eye/dsl/child_process_opts.rb +3 -3
- data/lib/eye/dsl/config_opts.rb +7 -7
- data/lib/eye/dsl/group_opts.rb +3 -3
- data/lib/eye/dsl/helpers.rb +1 -1
- data/lib/eye/dsl/main.rb +3 -4
- data/lib/eye/dsl/opts.rb +28 -31
- data/lib/eye/dsl/process_opts.rb +7 -13
- data/lib/eye/dsl/pure_opts.rb +9 -13
- data/lib/eye/dsl/validation.rb +35 -48
- data/lib/eye/group.rb +8 -23
- data/lib/eye/group/chain.rb +6 -6
- data/lib/eye/loader.rb +3 -3
- data/lib/eye/local.rb +4 -9
- data/lib/eye/logger.rb +4 -11
- data/lib/eye/notify.rb +6 -10
- data/lib/eye/notify/jabber.rb +1 -1
- data/lib/eye/notify/mail.rb +2 -2
- data/lib/eye/notify/slack.rb +3 -4
- data/lib/eye/process.rb +0 -2
- data/lib/eye/process/children.rb +4 -4
- data/lib/eye/process/commands.rb +39 -38
- data/lib/eye/process/config.rb +16 -22
- data/lib/eye/process/controller.rb +19 -5
- data/lib/eye/process/data.rb +9 -11
- data/lib/eye/process/monitor.rb +76 -86
- data/lib/eye/process/notify.rb +10 -10
- data/lib/eye/process/scheduler.rb +31 -36
- data/lib/eye/process/states.rb +5 -7
- data/lib/eye/process/states_history.rb +3 -9
- data/lib/eye/process/system.rb +20 -35
- data/lib/eye/process/trigger.rb +5 -1
- data/lib/eye/process/watchers.rb +9 -12
- data/lib/eye/reason.rb +1 -4
- data/lib/eye/server.rb +1 -2
- data/lib/eye/system.rb +15 -22
- data/lib/eye/system_resources.rb +9 -18
- data/lib/eye/trigger.rb +16 -18
- data/lib/eye/trigger/check_dependency.rb +4 -7
- data/lib/eye/trigger/flapping.rb +7 -24
- data/lib/eye/trigger/starting_guard.rb +6 -7
- data/lib/eye/trigger/stop_children.rb +2 -2
- data/lib/eye/trigger/transition.rb +1 -1
- data/lib/eye/trigger/wait_dependency.rb +2 -3
- data/lib/eye/utils.rb +3 -4
- data/lib/eye/utils/alive_array.rb +4 -9
- data/lib/eye/utils/celluloid_chain.rb +10 -12
- data/lib/eye/utils/leak_19.rb +10 -0
- data/lib/eye/utils/mini_active_support.rb +16 -16
- data/lib/eye/utils/pmap.rb +0 -2
- data/lib/eye/utils/tail.rb +2 -2
- metadata +8 -39
- data/.rubocop.yml +0 -141
- data/examples/custom_check.eye +0 -24
- data/examples/custom_trigger.eye +0 -30
- data/examples/leye_example/Eyefile +0 -10
data/eye.gemspec
CHANGED
@@ -1,29 +1,29 @@
|
|
1
1
|
require File.expand_path('../lib/eye', __FILE__)
|
2
2
|
|
3
3
|
Gem::Specification.new do |gem|
|
4
|
-
gem.authors =
|
5
|
-
gem.email =
|
4
|
+
gem.authors = "Konstantin Makarchev"
|
5
|
+
gem.email = "eye-rb@googlegroups.com"
|
6
6
|
|
7
7
|
gem.description = gem.summary = \
|
8
|
-
|
9
|
-
gem.homepage =
|
8
|
+
%q{Process monitoring tool. Inspired from Bluepill and God. Requires Ruby(MRI) >= 1.9.3-p194. Uses Celluloid and Celluloid::IO.}
|
9
|
+
gem.homepage = "http://github.com/kostya/eye"
|
10
10
|
|
11
|
-
gem.files = `git ls-files`.split($\).reject
|
12
|
-
gem.executables = gem.files.grep(%r
|
13
|
-
#
|
14
|
-
gem.name =
|
15
|
-
gem.require_paths = [
|
11
|
+
gem.files = `git ls-files`.split($\).reject{|n| n =~ %r[png|gif\z]}.reject{|n| n =~ %r[^(test|spec|features)/]}
|
12
|
+
gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
|
13
|
+
#gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
|
14
|
+
gem.name = "eye"
|
15
|
+
gem.require_paths = ["lib"]
|
16
16
|
gem.version = Eye::VERSION
|
17
|
-
gem.license =
|
17
|
+
gem.license = "MIT"
|
18
18
|
|
19
19
|
gem.required_ruby_version = '>= 1.9.2'
|
20
20
|
gem.required_rubygems_version = '>= 1.3.6'
|
21
21
|
|
22
|
-
gem.add_dependency 'celluloid', '~> 0.
|
23
|
-
gem.add_dependency 'celluloid-io', '~> 0.
|
22
|
+
gem.add_dependency 'celluloid', '~> 0.17.0'
|
23
|
+
gem.add_dependency 'celluloid-io', '~> 0.17.0'
|
24
24
|
gem.add_dependency 'state_machine'
|
25
25
|
gem.add_dependency 'thor'
|
26
|
-
gem.add_dependency 'sigar',
|
26
|
+
gem.add_dependency 'sigar', '~> 0.7.3'
|
27
27
|
|
28
28
|
gem.add_development_dependency 'rake'
|
29
29
|
gem.add_development_dependency 'rspec', '< 2.14'
|
@@ -31,15 +31,13 @@ Gem::Specification.new do |gem|
|
|
31
31
|
gem.add_development_dependency 'ruby-graphviz'
|
32
32
|
gem.add_development_dependency 'forking'
|
33
33
|
gem.add_development_dependency 'fakeweb'
|
34
|
-
gem.add_development_dependency 'eventmachine',
|
34
|
+
gem.add_development_dependency 'eventmachine', ">= 1.0.3"
|
35
35
|
gem.add_development_dependency 'sinatra'
|
36
36
|
gem.add_development_dependency 'thin'
|
37
37
|
gem.add_development_dependency 'xmpp4r'
|
38
38
|
gem.add_development_dependency 'slack-notifier'
|
39
39
|
gem.add_development_dependency 'coveralls'
|
40
|
-
gem.add_development_dependency 'tins', '1.6.0' # for coveralls
|
41
40
|
gem.add_development_dependency 'simplecov', '>= 0.8.1'
|
42
41
|
gem.add_development_dependency 'parallel_tests', '<= 1.3.1'
|
43
42
|
gem.add_development_dependency 'parallel_split_test'
|
44
|
-
gem.add_development_dependency 'rubocop'
|
45
43
|
end
|
data/lib/eye.rb
CHANGED
@@ -1,5 +1,5 @@
|
|
1
1
|
module Eye
|
2
|
-
VERSION =
|
2
|
+
VERSION = "0.8.pre"
|
3
3
|
ABOUT = "Eye v#{VERSION} (c) 2012-2015 @kostya"
|
4
4
|
PROCLINE = "eye monitoring v#{VERSION}"
|
5
5
|
|
@@ -8,7 +8,7 @@ module Eye
|
|
8
8
|
autoload :Server, 'eye/server'
|
9
9
|
autoload :Logger, 'eye/logger'
|
10
10
|
autoload :System, 'eye/system'
|
11
|
-
autoload :SystemResources,
|
11
|
+
autoload :SystemResources,'eye/system_resources'
|
12
12
|
autoload :Checker, 'eye/checker'
|
13
13
|
autoload :Trigger, 'eye/trigger'
|
14
14
|
autoload :Group, 'eye/group'
|
@@ -21,6 +21,7 @@ module Eye
|
|
21
21
|
autoload :Config, 'eye/config'
|
22
22
|
autoload :Reason, 'eye/reason'
|
23
23
|
autoload :Sigar, 'eye/sigar'
|
24
|
+
|
24
25
|
autoload :Controller, 'eye/controller'
|
25
26
|
autoload :Control, 'eye/control'
|
26
27
|
autoload :Cli, 'eye/cli'
|
data/lib/eye/application.rb
CHANGED
@@ -21,12 +21,13 @@ class Eye::Application
|
|
21
21
|
@groups << group
|
22
22
|
end
|
23
23
|
|
24
|
+
# sort processes in name order
|
24
25
|
def resort_groups
|
25
|
-
@groups.sort
|
26
|
+
@groups = @groups.sort { |a, b| a.hidden ? 1 : (b.hidden ? -1 : (a.name <=> b.name)) }
|
26
27
|
end
|
27
28
|
|
28
|
-
def status_data(
|
29
|
-
h = { name: @name, type: :application, subtree: @groups.map
|
29
|
+
def status_data(debug = false)
|
30
|
+
h = { name: @name, type: :application, subtree: @groups.map{|gr| gr.status_data(debug) }}
|
30
31
|
h[:debug] = debug_data if debug
|
31
32
|
h
|
32
33
|
end
|
@@ -52,13 +53,13 @@ class Eye::Application
|
|
52
53
|
|
53
54
|
def sub_object?(obj)
|
54
55
|
res = @groups.include?(obj)
|
55
|
-
res = @groups.any?
|
56
|
+
res = @groups.any?{|gr| gr.sub_object?(obj)} if !res
|
56
57
|
res
|
57
58
|
end
|
58
59
|
|
59
60
|
def processes
|
60
61
|
out = []
|
61
|
-
@groups.each
|
62
|
+
@groups.each{|gr| out += gr.processes.to_a }
|
62
63
|
Eye::Utils::AliveArray.new(out)
|
63
64
|
end
|
64
65
|
|
data/lib/eye/checker.rb
CHANGED
@@ -1,5 +1,4 @@
|
|
1
1
|
class Eye::Checker
|
2
|
-
|
3
2
|
include Eye::Dsl::Validation
|
4
3
|
|
5
4
|
autoload :Memory, 'eye/checker/memory'
|
@@ -7,35 +6,35 @@ class Eye::Checker
|
|
7
6
|
autoload :Http, 'eye/checker/http'
|
8
7
|
autoload :FileCTime, 'eye/checker/file_ctime'
|
9
8
|
autoload :FileSize, 'eye/checker/file_size'
|
10
|
-
autoload :FileTouched,
|
9
|
+
autoload :FileTouched,'eye/checker/file_touched'
|
11
10
|
autoload :Socket, 'eye/checker/socket'
|
12
11
|
autoload :SslSocket, 'eye/checker/ssl_socket'
|
13
12
|
autoload :Nop, 'eye/checker/nop'
|
14
13
|
autoload :Runtime, 'eye/checker/runtime'
|
15
14
|
autoload :Cputime, 'eye/checker/cputime'
|
16
15
|
autoload :ChildrenCount, 'eye/checker/children_count'
|
17
|
-
autoload :ChildrenMemory,
|
16
|
+
autoload :ChildrenMemory,'eye/checker/children_memory'
|
18
17
|
|
19
|
-
TYPES = {
|
20
|
-
|
21
|
-
|
22
|
-
|
18
|
+
TYPES = {:memory => 'Memory', :cpu => 'Cpu', :http => 'Http',
|
19
|
+
:ctime => 'FileCTime', :fsize => 'FileSize', :file_touched => 'FileTouched',
|
20
|
+
:socket => 'Socket', :nop => 'Nop', :runtime => 'Runtime', :cputime => 'Cputime',
|
21
|
+
:children_count => "ChildrenCount", :children_memory => "ChildrenMemory", :ssl_socket => 'SslSocket' }
|
23
22
|
|
24
23
|
attr_accessor :value, :values, :options, :pid, :type, :check_count, :process
|
25
24
|
|
26
25
|
param :every, [Fixnum, Float], false, 5
|
27
26
|
param :times, [Fixnum, Array], nil, 1
|
28
|
-
param :fires, [Symbol, Array
|
27
|
+
param :fires, [Symbol, Array], nil, nil, [:stop, :restart, :unmonitor, :start, :delete, :nothing, :notify]
|
29
28
|
param :initial_grace, [Fixnum, Float]
|
30
29
|
param :skip_initial_fails, [TrueClass, FalseClass]
|
31
30
|
|
32
31
|
def self.name_and_class(type)
|
33
32
|
type = type.to_sym
|
34
|
-
return {
|
33
|
+
return {:name => type, :type => type} if TYPES[type]
|
35
34
|
|
36
|
-
if type =~
|
37
|
-
ctype =
|
38
|
-
return {
|
35
|
+
if type =~ /\A(.*?)_?[0-9]+\z/
|
36
|
+
ctype = $1.to_sym
|
37
|
+
return {:name => type, :type => ctype} if TYPES[ctype]
|
39
38
|
end
|
40
39
|
end
|
41
40
|
|
@@ -51,7 +50,7 @@ class Eye::Checker
|
|
51
50
|
def self.create(pid, options = {}, process = nil)
|
52
51
|
get_class(options[:type]).new(pid, options, process)
|
53
52
|
|
54
|
-
rescue
|
53
|
+
rescue Exception, Timeout::Error => ex
|
55
54
|
log_ex(ex)
|
56
55
|
nil
|
57
56
|
end
|
@@ -80,11 +79,11 @@ class Eye::Checker
|
|
80
79
|
end
|
81
80
|
|
82
81
|
def logger_tag
|
83
|
-
@
|
82
|
+
@process.logger.prefix if @process
|
84
83
|
end
|
85
84
|
|
86
85
|
def logger_sub_tag
|
87
|
-
|
86
|
+
"check:#{check_name}"
|
88
87
|
end
|
89
88
|
|
90
89
|
def last_human_values
|
@@ -97,24 +96,22 @@ class Eye::Checker
|
|
97
96
|
end
|
98
97
|
|
99
98
|
def check
|
100
|
-
if initial_grace
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
@options[:initial_grace] = nil
|
106
|
-
end
|
99
|
+
if initial_grace && (Time.now - @initialized_at < initial_grace)
|
100
|
+
debug { 'skipped initial grace' }
|
101
|
+
return true
|
102
|
+
else
|
103
|
+
@options[:initial_grace] = nil
|
107
104
|
end
|
108
105
|
|
109
106
|
@value = get_value_safe
|
110
107
|
@good_value = good?(value)
|
111
|
-
@values << {
|
108
|
+
@values << {:value => @value, :good => @good_value}
|
112
109
|
|
113
110
|
result = true
|
114
111
|
@check_count += 1
|
115
112
|
|
116
113
|
if @values.size == max_tries
|
117
|
-
bad_count = @values.count
|
114
|
+
bad_count = @values.count{|v| !v[:good] }
|
118
115
|
result = false if bad_count >= min_tries
|
119
116
|
end
|
120
117
|
|
@@ -126,10 +123,10 @@ class Eye::Checker
|
|
126
123
|
end
|
127
124
|
end
|
128
125
|
|
129
|
-
info
|
126
|
+
info "#{last_human_values} => #{result ? 'OK' : 'Fail'}"
|
130
127
|
result
|
131
128
|
|
132
|
-
rescue
|
129
|
+
rescue Exception, Timeout::Error => ex
|
133
130
|
log_ex(ex)
|
134
131
|
end
|
135
132
|
|
@@ -192,12 +189,7 @@ class Eye::Checker
|
|
192
189
|
process.notify :warn, "Bounded #{check_name}: #{last_human_values} send to #{actions}"
|
193
190
|
|
194
191
|
actions.each do |action|
|
195
|
-
|
196
|
-
if action.is_a?(Proc)
|
197
|
-
process.schedule :execute_proc, reason, &action
|
198
|
-
else
|
199
|
-
process.schedule action, reason
|
200
|
-
end
|
192
|
+
process.schedule action, Eye::Reason.new("bounded #{check_name}")
|
201
193
|
end
|
202
194
|
end
|
203
195
|
|
@@ -206,11 +198,9 @@ class Eye::Checker
|
|
206
198
|
end
|
207
199
|
|
208
200
|
class Defer < Eye::Checker
|
209
|
-
|
210
201
|
def get_value_safe
|
211
|
-
Celluloid::Future.new
|
202
|
+
Celluloid::Future.new{ get_value }.value
|
212
203
|
end
|
213
|
-
|
214
204
|
end
|
215
205
|
|
216
206
|
def self.register(base)
|
@@ -224,34 +214,27 @@ class Eye::Checker
|
|
224
214
|
end
|
225
215
|
|
226
216
|
class CustomCell < Eye::Checker
|
227
|
-
|
228
217
|
def self.inherited(base)
|
229
218
|
super
|
230
219
|
register(base)
|
231
220
|
end
|
232
|
-
|
233
221
|
end
|
234
222
|
|
235
223
|
class Custom < Defer
|
236
|
-
|
237
224
|
def self.inherited(base)
|
238
225
|
super
|
239
226
|
register(base)
|
240
227
|
end
|
241
|
-
|
242
228
|
end
|
243
229
|
|
244
230
|
class CustomDefer < Defer
|
245
|
-
|
246
231
|
def self.inherited(base)
|
247
232
|
super
|
248
233
|
register(base)
|
249
234
|
end
|
250
|
-
|
251
235
|
end
|
252
236
|
|
253
237
|
class Measure < Eye::Checker
|
254
|
-
|
255
238
|
param :below, [Fixnum, Float]
|
256
239
|
param :above, [Fixnum, Float]
|
257
240
|
|
@@ -272,7 +255,5 @@ class Eye::Checker
|
|
272
255
|
'-'
|
273
256
|
end
|
274
257
|
end
|
275
|
-
|
276
258
|
end
|
277
|
-
|
278
259
|
end
|
@@ -32,7 +32,7 @@ private
|
|
32
32
|
|
33
33
|
def ordered_by_date_children_pids
|
34
34
|
children = process.children.values
|
35
|
-
children.sort_by { |ch| Eye::SystemResources.start_time(ch.pid).to_i }.map
|
35
|
+
children.sort_by { |ch| Eye::SystemResources.start_time(ch.pid).to_i }.map &:pid
|
36
36
|
end
|
37
37
|
|
38
38
|
end
|
data/lib/eye/checker/http.rb
CHANGED
@@ -21,43 +21,46 @@ class Eye::Checker::Http < Eye::Checker::Defer
|
|
21
21
|
@uri = URI.parse(url)
|
22
22
|
@proxy_uri = URI.parse(proxy_url) if proxy_url
|
23
23
|
@kind = case kind
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
24
|
+
when Fixnum then Net::HTTPResponse::CODE_TO_OBJ[kind.to_s]
|
25
|
+
when String, Symbol then Net.const_get("HTTP#{kind.to_s.camelize}") rescue Net::HTTPSuccess
|
26
|
+
else Net::HTTPSuccess
|
27
|
+
end
|
28
28
|
@open_timeout = (open_timeout || 3).to_f
|
29
29
|
@read_timeout = (read_timeout || timeout || 15).to_f
|
30
30
|
end
|
31
31
|
|
32
32
|
def get_value
|
33
|
-
res = session.start
|
34
|
-
{
|
33
|
+
res = session.start{ |http| http.get(@uri.request_uri) }
|
34
|
+
{:result => res}
|
35
35
|
|
36
36
|
rescue Timeout::Error => ex
|
37
37
|
debug { ex.inspect }
|
38
38
|
|
39
39
|
if defined?(Net::OpenTimeout) # for ruby 2.0
|
40
40
|
mes = ex.is_a?(Net::OpenTimeout) ? "OpenTimeout<#{@open_timeout}>" : "ReadTimeout<#{@read_timeout}>"
|
41
|
-
{
|
41
|
+
{:exception => mes}
|
42
42
|
else
|
43
|
-
{
|
43
|
+
{:exception => "Timeout<#{@open_timeout},#{@read_timeout}>"}
|
44
44
|
end
|
45
45
|
|
46
46
|
rescue => ex
|
47
|
-
{
|
47
|
+
{:exception => "Error<#{ex.message}>"}
|
48
48
|
end
|
49
49
|
|
50
50
|
def good?(value)
|
51
51
|
return false unless value[:result]
|
52
|
-
|
52
|
+
|
53
|
+
unless value[:result].kind_of?(@kind)
|
54
|
+
return false
|
55
|
+
end
|
53
56
|
|
54
57
|
if pattern
|
55
58
|
matched = if pattern.is_a?(Regexp)
|
56
|
-
|
59
|
+
pattern === value[:result].body
|
57
60
|
else
|
58
61
|
value[:result].body.include?(pattern.to_s)
|
59
62
|
end
|
60
|
-
value[:notice] = "missing '#{pattern}'" unless matched
|
63
|
+
value[:notice] = "missing '#{pattern.to_s}'" unless matched
|
61
64
|
matched
|
62
65
|
else
|
63
66
|
true
|
@@ -99,5 +102,4 @@ private
|
|
99
102
|
Net::HTTP.new(@uri.host, @uri.port)
|
100
103
|
end
|
101
104
|
end
|
102
|
-
|
103
105
|
end
|
data/lib/eye/checker/nop.rb
CHANGED
data/lib/eye/checker/socket.rb
CHANGED
@@ -27,75 +27,78 @@ class Eye::Checker::Socket < Eye::Checker::Defer
|
|
27
27
|
|
28
28
|
if addr =~ %r[\Atcp://(.*?):(.*?)\z]
|
29
29
|
@socket_family = :tcp
|
30
|
-
@socket_addr =
|
31
|
-
@socket_port =
|
30
|
+
@socket_addr = $1
|
31
|
+
@socket_port = $2.to_i
|
32
32
|
elsif addr =~ %r[\Aunix:(.*)\z]
|
33
33
|
@socket_family = :unix
|
34
|
-
@socket_path =
|
34
|
+
@socket_path = $1
|
35
35
|
end
|
36
36
|
end
|
37
37
|
|
38
38
|
def get_value
|
39
39
|
sock = begin
|
40
|
-
Timeout
|
40
|
+
Timeout::timeout(@open_timeout){ open_socket }
|
41
41
|
rescue Timeout::Error
|
42
|
-
return { exception
|
42
|
+
return { :exception => "OpenTimeout<#{@open_timeout}>" }
|
43
43
|
end
|
44
44
|
|
45
|
-
|
45
|
+
if send_data
|
46
|
+
begin
|
47
|
+
Timeout::timeout(@read_timeout) do
|
48
|
+
_write_data(sock, send_data)
|
49
|
+
result = _read_data(sock)
|
46
50
|
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
if protocol == :raw
|
56
|
-
return { result: @buffer }
|
57
|
-
else
|
58
|
-
return { exception: "ReadTimeout<#{@read_timeout}>" }
|
51
|
+
{ :result => result }
|
52
|
+
end
|
53
|
+
rescue Timeout::Error
|
54
|
+
if protocol == :raw
|
55
|
+
return { :result => @buffer }
|
56
|
+
else
|
57
|
+
return { :exception => "ReadTimeout<#{@read_timeout}>" }
|
58
|
+
end
|
59
59
|
end
|
60
|
+
else
|
61
|
+
{ :result => :listen }
|
60
62
|
end
|
61
63
|
|
62
64
|
rescue Exception => e
|
63
|
-
{ exception
|
65
|
+
{ :exception => "Error<#{e.message}>" }
|
64
66
|
|
65
67
|
ensure
|
66
68
|
sock.close if sock
|
67
69
|
end
|
68
70
|
|
69
71
|
def good?(value)
|
70
|
-
return false
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
end
|
72
|
+
return false if !value[:result]
|
73
|
+
|
74
|
+
if expect_data
|
75
|
+
if expect_data.is_a?(Proc)
|
76
|
+
match = begin
|
77
|
+
!!expect_data[value[:result]]
|
78
|
+
rescue Timeout::Error, Exception => ex
|
79
|
+
mes = "proc match failed with '#{ex.message}'"
|
80
|
+
error(mes)
|
81
|
+
value[:notice] = mes
|
82
|
+
return false
|
83
|
+
end
|
83
84
|
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
85
|
+
unless match
|
86
|
+
warn "proc #{expect_data} not matched (#{value[:result].truncate(30)}) answer"
|
87
|
+
value[:notice] = 'missing proc validation'
|
88
|
+
end
|
88
89
|
|
89
|
-
|
90
|
-
|
90
|
+
return match
|
91
|
+
end
|
91
92
|
|
92
|
-
|
93
|
-
|
93
|
+
return true if expect_data.is_a?(Regexp) && expect_data.match(value[:result])
|
94
|
+
return true if value[:result].to_s == expect_data.to_s
|
94
95
|
|
95
|
-
|
96
|
-
|
96
|
+
warn "#{expect_data} not matched (#{value[:result].truncate(30)}) answer"
|
97
|
+
value[:notice] = "missing '#{expect_data.to_s}'"
|
98
|
+
return false
|
99
|
+
end
|
97
100
|
|
98
|
-
|
101
|
+
return true
|
99
102
|
end
|
100
103
|
|
101
104
|
def human_value(value)
|
@@ -128,28 +131,28 @@ private
|
|
128
131
|
|
129
132
|
def _write_data(socket, data)
|
130
133
|
case protocol
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
|
134
|
+
when :em_object
|
135
|
+
data = Marshal.dump(data)
|
136
|
+
socket.write([data.bytesize, data].pack('Na*'))
|
137
|
+
else
|
138
|
+
socket.write(data.to_s)
|
136
139
|
end
|
137
140
|
end
|
138
141
|
|
139
142
|
def _read_data(socket)
|
140
143
|
case protocol
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
|
147
|
-
|
148
|
-
|
149
|
-
|
150
|
-
|
151
|
-
|
152
|
-
|
144
|
+
when :em_object
|
145
|
+
content = ''
|
146
|
+
msg_size = socket.recv(4).unpack('N')[0] rescue 0
|
147
|
+
content << socket.recv(msg_size - content.length) while content.length < msg_size
|
148
|
+
if content.present?
|
149
|
+
Marshal.load(content) rescue 'corrupted_marshal'
|
150
|
+
end
|
151
|
+
when :raw
|
152
|
+
@buffer = ''
|
153
|
+
loop { @buffer << socket.recv(1) }
|
154
|
+
else
|
155
|
+
socket.readline.chop
|
153
156
|
end
|
154
157
|
end
|
155
158
|
|