eye 0.8.pre2 → 0.8.rc
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 +4 -4
- data/.rubocop.yml +141 -0
- data/.travis.yml +5 -3
- data/README.md +1 -2
- data/Rakefile +5 -5
- data/bin/leye +9 -4
- data/bin/loader_eye +14 -15
- data/examples/custom_check.eye +24 -0
- data/examples/custom_trigger.eye +3 -1
- data/examples/delayed_job.eye +3 -3
- data/examples/dependency.eye +10 -11
- data/examples/leye_example/Eyefile +10 -0
- data/examples/notify.eye +3 -4
- data/examples/plugin/main.eye +5 -5
- data/examples/plugin/plugin.rb +10 -2
- data/examples/process_thin.rb +8 -8
- data/examples/processes/em.rb +18 -12
- data/examples/processes/forking.rb +5 -5
- data/examples/processes/sample.rb +46 -44
- data/examples/puma.eye +9 -8
- 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 +1 -2
- data/examples/thin-farm.eye +7 -8
- data/examples/triggers.eye +13 -15
- data/examples/unicorn.eye +12 -13
- data/eye.gemspec +14 -12
- data/lib/eye.rb +2 -3
- data/lib/eye/application.rb +5 -6
- data/lib/eye/checker.rb +36 -19
- data/lib/eye/checker/children_count.rb +1 -1
- data/lib/eye/checker/file_ctime.rb +1 -1
- data/lib/eye/checker/http.rb +13 -15
- data/lib/eye/checker/nop.rb +1 -0
- data/lib/eye/checker/socket.rb +60 -63
- data/lib/eye/checker/ssl_socket.rb +5 -5
- data/lib/eye/child_process.rb +6 -4
- data/lib/eye/cli.rb +50 -41
- data/lib/eye/cli/commands.rb +4 -5
- data/lib/eye/cli/render.rb +61 -41
- data/lib/eye/cli/server.rb +19 -16
- data/lib/eye/client.rb +1 -0
- data/lib/eye/config.rb +19 -19
- data/lib/eye/controller.rb +2 -3
- data/lib/eye/controller/commands.rb +1 -1
- data/lib/eye/controller/helpers.rb +2 -2
- data/lib/eye/controller/load.rb +18 -12
- data/lib/eye/controller/options.rb +1 -5
- data/lib/eye/controller/send_command.rb +21 -23
- data/lib/eye/controller/status.rb +17 -15
- data/lib/eye/dsl.rb +3 -0
- data/lib/eye/dsl/application_opts.rb +4 -3
- 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 +4 -3
- data/lib/eye/dsl/opts.rb +31 -28
- data/lib/eye/dsl/process_opts.rb +13 -7
- data/lib/eye/dsl/pure_opts.rb +13 -9
- data/lib/eye/dsl/validation.rb +48 -35
- data/lib/eye/group.rb +20 -6
- data/lib/eye/group/chain.rb +6 -6
- data/lib/eye/loader.rb +1 -1
- data/lib/eye/local.rb +9 -4
- data/lib/eye/logger.rb +11 -4
- data/lib/eye/notify.rb +10 -6
- data/lib/eye/notify/jabber.rb +1 -1
- data/lib/eye/notify/mail.rb +2 -2
- data/lib/eye/notify/slack.rb +4 -3
- data/lib/eye/process.rb +2 -0
- data/lib/eye/process/children.rb +4 -4
- data/lib/eye/process/commands.rb +28 -31
- data/lib/eye/process/config.rb +21 -19
- data/lib/eye/process/data.rb +11 -9
- data/lib/eye/process/monitor.rb +30 -29
- data/lib/eye/process/notify.rb +10 -10
- data/lib/eye/process/scheduler.rb +36 -31
- data/lib/eye/process/states.rb +5 -4
- data/lib/eye/process/states_history.rb +9 -3
- data/lib/eye/process/system.rb +5 -4
- data/lib/eye/process/trigger.rb +1 -5
- data/lib/eye/process/watchers.rb +6 -9
- data/lib/eye/reason.rb +4 -1
- data/lib/eye/server.rb +2 -1
- data/lib/eye/system.rb +16 -13
- data/lib/eye/system_resources.rb +13 -8
- data/lib/eye/trigger.rb +18 -16
- data/lib/eye/trigger/check_dependency.rb +7 -4
- data/lib/eye/trigger/flapping.rb +24 -7
- data/lib/eye/trigger/starting_guard.rb +7 -6
- data/lib/eye/trigger/stop_children.rb +2 -2
- data/lib/eye/trigger/transition.rb +1 -1
- data/lib/eye/trigger/wait_dependency.rb +3 -2
- data/lib/eye/utils.rb +4 -3
- data/lib/eye/utils/alive_array.rb +9 -4
- data/lib/eye/utils/celluloid_chain.rb +12 -10
- data/lib/eye/utils/mini_active_support.rb +16 -16
- data/lib/eye/utils/pmap.rb +2 -0
- data/lib/eye/utils/tail.rb +2 -2
- metadata +34 -4
- data/lib/eye/utils/leak_19.rb +0 -10
data/lib/eye/trigger.rb
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
class Eye::Trigger
|
|
2
|
+
|
|
2
3
|
include Eye::Dsl::Validation
|
|
3
4
|
|
|
4
5
|
autoload :Flapping, 'eye/trigger/flapping'
|
|
@@ -8,19 +9,18 @@ class Eye::Trigger
|
|
|
8
9
|
autoload :CheckDependency, 'eye/trigger/check_dependency'
|
|
9
10
|
autoload :StartingGuard, 'eye/trigger/starting_guard'
|
|
10
11
|
|
|
11
|
-
TYPES = {:
|
|
12
|
-
|
|
13
|
-
}
|
|
12
|
+
TYPES = { flapping: 'Flapping', transition: 'Transition', stop_children: 'StopChildren',
|
|
13
|
+
wait_dependency: 'WaitDependency', check_dependency: 'CheckDependency', starting_guard: 'StartingGuard' }
|
|
14
14
|
|
|
15
15
|
attr_reader :message, :options, :process
|
|
16
16
|
|
|
17
17
|
def self.name_and_class(type)
|
|
18
18
|
type = type.to_sym
|
|
19
|
-
return {:
|
|
19
|
+
return { name: type, type: type } if TYPES[type]
|
|
20
20
|
|
|
21
|
-
if type =~
|
|
22
|
-
ctype =
|
|
23
|
-
return {:
|
|
21
|
+
if type =~ %r[\A(.*?)_?[0-9]+\z]
|
|
22
|
+
ctype = Regexp.last_match(1).to_sym
|
|
23
|
+
return { name: type, type: ctype } if TYPES[ctype]
|
|
24
24
|
end
|
|
25
25
|
end
|
|
26
26
|
|
|
@@ -36,7 +36,7 @@ class Eye::Trigger
|
|
|
36
36
|
def self.create(process, options = {})
|
|
37
37
|
get_class(options[:type]).new(process, options)
|
|
38
38
|
|
|
39
|
-
rescue
|
|
39
|
+
rescue Object => ex
|
|
40
40
|
log_ex(ex)
|
|
41
41
|
nil
|
|
42
42
|
end
|
|
@@ -72,7 +72,7 @@ class Eye::Trigger
|
|
|
72
72
|
|
|
73
73
|
check(transition) if filter_transition(transition)
|
|
74
74
|
|
|
75
|
-
rescue
|
|
75
|
+
rescue Object => ex
|
|
76
76
|
if ex.class == Eye::Process::StateError
|
|
77
77
|
raise ex
|
|
78
78
|
else
|
|
@@ -92,7 +92,7 @@ class Eye::Trigger
|
|
|
92
92
|
compare_state(trans.event, event)
|
|
93
93
|
end
|
|
94
94
|
|
|
95
|
-
def check(
|
|
95
|
+
def check(_transition)
|
|
96
96
|
raise NotImplementedError
|
|
97
97
|
end
|
|
98
98
|
|
|
@@ -126,22 +126,24 @@ class Eye::Trigger
|
|
|
126
126
|
end
|
|
127
127
|
|
|
128
128
|
class Custom < Eye::Trigger
|
|
129
|
+
|
|
129
130
|
def self.inherited(base)
|
|
130
131
|
super
|
|
131
132
|
register(base)
|
|
132
133
|
end
|
|
134
|
+
|
|
133
135
|
end
|
|
134
136
|
|
|
135
137
|
private
|
|
136
138
|
|
|
137
139
|
def compare_state(state_name, condition)
|
|
138
140
|
case condition
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
141
|
+
when Symbol
|
|
142
|
+
state_name == condition
|
|
143
|
+
when Array
|
|
144
|
+
condition.include?(state_name)
|
|
145
|
+
else
|
|
146
|
+
true
|
|
145
147
|
end
|
|
146
148
|
end
|
|
147
149
|
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
class Eye::Trigger::CheckDependency < Eye::Trigger
|
|
2
|
+
|
|
2
3
|
param :names, [Array], true, 5
|
|
3
4
|
|
|
4
5
|
def check(transition)
|
|
@@ -10,14 +11,16 @@ private
|
|
|
10
11
|
def check_dependency(to)
|
|
11
12
|
processes = names.map do |name|
|
|
12
13
|
Eye::Control.find_nearest_process(name, process.group_name_pure, process.app_name)
|
|
13
|
-
end
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
processes = processes.compact.select { |p| p.state_name != :unmonitored }
|
|
14
17
|
return if processes.empty?
|
|
15
18
|
processes = Eye::Utils::AliveArray.new(processes)
|
|
16
19
|
|
|
17
20
|
act = case to
|
|
18
|
-
when :down, :restarting
|
|
19
|
-
when :stopping
|
|
20
|
-
when :unmonitored
|
|
21
|
+
when :down, :restarting then :restart
|
|
22
|
+
when :stopping then :stop
|
|
23
|
+
when :unmonitored then :unmonitor
|
|
21
24
|
end
|
|
22
25
|
|
|
23
26
|
if act
|
data/lib/eye/trigger/flapping.rb
CHANGED
|
@@ -7,10 +7,12 @@ class Eye::Trigger::Flapping < Eye::Trigger
|
|
|
7
7
|
param :within, [Float, Fixnum], true
|
|
8
8
|
param :retry_in, [Float, Fixnum]
|
|
9
9
|
param :retry_times, [Fixnum]
|
|
10
|
+
param :reretry_in, [Float, Fixnum]
|
|
11
|
+
param :reretry_times, [Fixnum]
|
|
10
12
|
|
|
11
13
|
def initialize(*args)
|
|
12
14
|
super
|
|
13
|
-
|
|
15
|
+
clear_counters
|
|
14
16
|
end
|
|
15
17
|
|
|
16
18
|
def check(transition)
|
|
@@ -19,9 +21,16 @@ class Eye::Trigger::Flapping < Eye::Trigger
|
|
|
19
21
|
|
|
20
22
|
private
|
|
21
23
|
|
|
24
|
+
def clear_counters
|
|
25
|
+
@retry_times = 0
|
|
26
|
+
@reretry_times = 0
|
|
27
|
+
end
|
|
28
|
+
|
|
22
29
|
def good?
|
|
23
|
-
|
|
24
|
-
|
|
30
|
+
down_count = 0
|
|
31
|
+
process.states_history.states_for_period(within, @last_at) do |s|
|
|
32
|
+
down_count += 1 if s[:state] == :down
|
|
33
|
+
end
|
|
25
34
|
|
|
26
35
|
if down_count >= times
|
|
27
36
|
@last_at = process.states_history.last_state_changed_at
|
|
@@ -38,10 +47,18 @@ private
|
|
|
38
47
|
process.schedule :unmonitor, Eye::Reason::Flapping.new(:flapping)
|
|
39
48
|
|
|
40
49
|
return unless retry_in
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
50
|
+
if !retry_times || (retry_times && @retry_times < retry_times)
|
|
51
|
+
@retry_times += 1
|
|
52
|
+
process.schedule_in(retry_in.to_f, :conditional_start, Eye::Reason::Flapping.new('retry start after flapping'))
|
|
53
|
+
else
|
|
54
|
+
if reretry_in
|
|
55
|
+
if !reretry_times || (reretry_times && @reretry_times < reretry_times)
|
|
56
|
+
@retry_times = 0
|
|
57
|
+
@reretry_times += 1
|
|
58
|
+
process.schedule_in(reretry_in.to_f, :conditional_start, Eye::Reason::Flapping.new('reretry start after flapping'))
|
|
59
|
+
end
|
|
60
|
+
end
|
|
61
|
+
end
|
|
45
62
|
end
|
|
46
63
|
|
|
47
64
|
end
|
|
@@ -33,32 +33,33 @@ class Eye::Trigger::StartingGuard < Eye::Trigger
|
|
|
33
33
|
@reretry_count = 0
|
|
34
34
|
return
|
|
35
35
|
else
|
|
36
|
-
info
|
|
36
|
+
info 'false executed condition'
|
|
37
37
|
end
|
|
38
38
|
|
|
39
39
|
new_time = nil
|
|
40
40
|
if every
|
|
41
41
|
if times
|
|
42
|
-
if
|
|
42
|
+
if @retry_count < times
|
|
43
43
|
new_time = Time.now + every
|
|
44
|
-
process.schedule_in every, :conditional_start, Eye::Reason::StartingGuard.new(
|
|
44
|
+
process.schedule_in every, :conditional_start, Eye::Reason::StartingGuard.new('starting_guard, retry start')
|
|
45
45
|
else
|
|
46
46
|
@retry_count = 0
|
|
47
47
|
@reretry_count += 1
|
|
48
48
|
if retry_in && (!retry_times || (@reretry_count < retry_times))
|
|
49
49
|
new_time = Time.now + retry_in
|
|
50
|
-
process.schedule_in retry_in, :conditional_start, Eye::Reason::StartingGuard.new(
|
|
50
|
+
process.schedule_in retry_in, :conditional_start, Eye::Reason::StartingGuard.new('starting_guard, reretry start')
|
|
51
51
|
end
|
|
52
52
|
end
|
|
53
53
|
else
|
|
54
54
|
new_time = Time.now + every
|
|
55
|
-
process.schedule_in every, :conditional_start, Eye::Reason::StartingGuard.new(
|
|
55
|
+
process.schedule_in every, :conditional_start, Eye::Reason::StartingGuard.new('starting_guard, retry start')
|
|
56
56
|
end
|
|
57
57
|
end
|
|
58
58
|
|
|
59
59
|
retry_msg = new_time ? ", retry at '#{Eye::Utils.human_time2(new_time.to_i)}'" : ''
|
|
60
60
|
process.switch :unmonitoring, Eye::Reason::StartingGuard.new("starting_guard, failed condition#{retry_msg}")
|
|
61
61
|
|
|
62
|
-
raise Eye::Process::StateError
|
|
62
|
+
raise Eye::Process::StateError, 'starting_guard, refused to start'
|
|
63
63
|
end
|
|
64
|
+
|
|
64
65
|
end
|
|
@@ -9,9 +9,9 @@ class Eye::Trigger::StopChildren < Eye::Trigger
|
|
|
9
9
|
# default on stopped, crashed
|
|
10
10
|
param_default :event, [:stopped, :crashed]
|
|
11
11
|
|
|
12
|
-
def check(
|
|
12
|
+
def check(_trans)
|
|
13
13
|
debug { 'stopping children' }
|
|
14
|
-
process.children.pmap { |
|
|
14
|
+
process.children.pmap { |_pid, c| c.stop }
|
|
15
15
|
end
|
|
16
16
|
|
|
17
17
|
end
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
class Eye::Trigger::WaitDependency < Eye::Trigger
|
|
2
|
+
|
|
2
3
|
param :names, [Array], true
|
|
3
4
|
param :wait_timeout, [Numeric], nil, 15.seconds
|
|
4
5
|
param :retry_after, [Numeric], nil, 1.minute
|
|
@@ -18,7 +19,7 @@ private
|
|
|
18
19
|
processes = Eye::Utils::AliveArray.new(processes)
|
|
19
20
|
|
|
20
21
|
processes.each do |p|
|
|
21
|
-
if p.state_name != :up && (should_start
|
|
22
|
+
if p.state_name != :up && (should_start != false)
|
|
22
23
|
p.schedule :start, Eye::Reason.new(:start_dependency)
|
|
23
24
|
end
|
|
24
25
|
end
|
|
@@ -42,7 +43,7 @@ private
|
|
|
42
43
|
process.schedule_in retry_after, :start, Eye::Reason.new(:wait_dependency)
|
|
43
44
|
end
|
|
44
45
|
|
|
45
|
-
raise Eye::Process::StateError
|
|
46
|
+
raise Eye::Process::StateError, 'stop transition because dependency is not up'
|
|
46
47
|
end
|
|
47
48
|
end
|
|
48
49
|
|
data/lib/eye/utils.rb
CHANGED
|
@@ -1,14 +1,15 @@
|
|
|
1
1
|
require 'date'
|
|
2
2
|
|
|
3
3
|
module Eye::Utils
|
|
4
|
+
|
|
4
5
|
autoload :Tail, 'eye/utils/tail'
|
|
5
6
|
autoload :AliveArray, 'eye/utils/alive_array'
|
|
6
7
|
autoload :CelluloidChain, 'eye/utils/celluloid_chain'
|
|
7
8
|
|
|
8
9
|
def self.deep_clone(value)
|
|
9
10
|
case
|
|
10
|
-
when value.is_a?(Array) then value.map{|v| deep_clone(v) }
|
|
11
|
-
when value.is_a?(Hash) then value.
|
|
11
|
+
when value.is_a?(Array) then value.map { |v| deep_clone(v) }
|
|
12
|
+
when value.is_a?(Hash) then value.each_with_object({}) { |(k, v), r| r[deep_clone(k)] = deep_clone(v) }
|
|
12
13
|
else value
|
|
13
14
|
end
|
|
14
15
|
end
|
|
@@ -47,7 +48,7 @@ module Eye::Utils
|
|
|
47
48
|
env_vars = content.split("\n")
|
|
48
49
|
h = {}
|
|
49
50
|
env_vars.each do |e|
|
|
50
|
-
e = e.gsub(
|
|
51
|
+
e = e.gsub(%r[#.+$], '').strip
|
|
51
52
|
next unless e.include?('=')
|
|
52
53
|
k, v = e.split('=', 2)
|
|
53
54
|
h[k] = v
|
|
@@ -1,20 +1,21 @@
|
|
|
1
1
|
class Eye::Utils::AliveArray
|
|
2
|
+
|
|
2
3
|
extend Forwardable
|
|
3
4
|
include Enumerable
|
|
4
5
|
|
|
5
6
|
def_delegators :@arr, :[], :<<, :clear, :delete, :size, :empty?, :push,
|
|
6
|
-
|
|
7
|
+
:flatten, :present?, :uniq!, :select!
|
|
7
8
|
|
|
8
9
|
def initialize(arr = [])
|
|
9
10
|
@arr = arr
|
|
10
11
|
end
|
|
11
12
|
|
|
12
13
|
def each(&block)
|
|
13
|
-
@arr.each{|elem| elem && elem.alive? && block[elem] }
|
|
14
|
+
@arr.each { |elem| elem && elem.alive? && block[elem] }
|
|
14
15
|
end
|
|
15
16
|
|
|
16
17
|
def to_a
|
|
17
|
-
map{|x| x }
|
|
18
|
+
map { |x| x }
|
|
18
19
|
end
|
|
19
20
|
|
|
20
21
|
def full_size
|
|
@@ -33,6 +34,10 @@ class Eye::Utils::AliveArray
|
|
|
33
34
|
self.class.new super
|
|
34
35
|
end
|
|
35
36
|
|
|
37
|
+
def sort!
|
|
38
|
+
@arr.sort!
|
|
39
|
+
end
|
|
40
|
+
|
|
36
41
|
def +(other)
|
|
37
42
|
if other.is_a?(Eye::Utils::AliveArray)
|
|
38
43
|
@arr += other.pure
|
|
@@ -54,4 +59,4 @@ class Eye::Utils::AliveArray
|
|
|
54
59
|
end
|
|
55
60
|
end
|
|
56
61
|
|
|
57
|
-
end
|
|
62
|
+
end
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
require 'celluloid'
|
|
2
2
|
|
|
3
3
|
class Eye::Utils::CelluloidChain
|
|
4
|
+
|
|
4
5
|
include Celluloid
|
|
5
6
|
|
|
6
7
|
def initialize(target)
|
|
@@ -10,21 +11,21 @@ class Eye::Utils::CelluloidChain
|
|
|
10
11
|
@target_class = @target.class
|
|
11
12
|
end
|
|
12
13
|
|
|
13
|
-
def add(method_name, *args
|
|
14
|
-
@calls << {:
|
|
14
|
+
def add(method_name, *args)
|
|
15
|
+
@calls << { method_name: method_name, args: args }
|
|
15
16
|
ensure_process
|
|
16
17
|
end
|
|
17
18
|
|
|
18
|
-
def add_wo_dups(method_name, *args
|
|
19
|
-
h = {:
|
|
19
|
+
def add_wo_dups(method_name, *args)
|
|
20
|
+
h = { method_name: method_name, args: args }
|
|
20
21
|
if @calls[-1] != h
|
|
21
22
|
@calls << h
|
|
22
23
|
ensure_process
|
|
23
24
|
end
|
|
24
25
|
end
|
|
25
26
|
|
|
26
|
-
def add_wo_dups_current(method_name, *args
|
|
27
|
-
h = {:
|
|
27
|
+
def add_wo_dups_current(method_name, *args)
|
|
28
|
+
h = { method_name: method_name, args: args }
|
|
28
29
|
if !@calls.include?(h) && @call != h
|
|
29
30
|
@calls << h
|
|
30
31
|
ensure_process
|
|
@@ -36,14 +37,14 @@ class Eye::Utils::CelluloidChain
|
|
|
36
37
|
end
|
|
37
38
|
|
|
38
39
|
def names_list
|
|
39
|
-
list.map{|el| el[:method_name].to_sym }
|
|
40
|
+
list.map { |el| el[:method_name].to_sym }
|
|
40
41
|
end
|
|
41
42
|
|
|
42
43
|
def clear
|
|
43
44
|
@calls = []
|
|
44
45
|
end
|
|
45
46
|
|
|
46
|
-
|
|
47
|
+
alias_method :clear_pending_list, :clear
|
|
47
48
|
|
|
48
49
|
# need, because of https://github.com/celluloid/celluloid/issues/22
|
|
49
50
|
def inspect
|
|
@@ -64,8 +65,9 @@ private
|
|
|
64
65
|
def process
|
|
65
66
|
while @call = @calls.shift
|
|
66
67
|
@running = true
|
|
67
|
-
@target.send(@call[:method_name], *@call[:args]
|
|
68
|
+
@target.send(@call[:method_name], *@call[:args]) if @target.alive?
|
|
68
69
|
end
|
|
69
70
|
@running = false
|
|
70
71
|
end
|
|
71
|
-
|
|
72
|
+
|
|
73
|
+
end
|
|
@@ -31,9 +31,9 @@ class String
|
|
|
31
31
|
word = self.dup
|
|
32
32
|
word.gsub!('::', '/')
|
|
33
33
|
word.gsub!(/(?:([A-Za-z\d])|^)((?=a)b)(?=\b|[^a-z])/) { "#{$1}#{$1 && '_'}#{$2.downcase}" }
|
|
34
|
-
word.gsub!(/([A-Z\d]+)([A-Z][a-z])/,'\1_\2')
|
|
35
|
-
word.gsub!(/([a-z\d])([A-Z])/,'\1_\2')
|
|
36
|
-
word.tr!(
|
|
34
|
+
word.gsub!(/([A-Z\d]+)([A-Z][a-z])/, '\1_\2')
|
|
35
|
+
word.gsub!(/([a-z\d])([A-Z])/, '\1_\2')
|
|
36
|
+
word.tr!('-', '_')
|
|
37
37
|
word.downcase!
|
|
38
38
|
word
|
|
39
39
|
end
|
|
@@ -53,32 +53,32 @@ class Numeric
|
|
|
53
53
|
def percents
|
|
54
54
|
self
|
|
55
55
|
end
|
|
56
|
-
|
|
56
|
+
alias_method :percent, :percents
|
|
57
57
|
|
|
58
58
|
def seconds
|
|
59
59
|
self
|
|
60
60
|
end
|
|
61
|
-
|
|
61
|
+
alias_method :second, :seconds
|
|
62
62
|
|
|
63
63
|
def minutes
|
|
64
64
|
self * 60
|
|
65
65
|
end
|
|
66
|
-
|
|
66
|
+
alias_method :minute, :minutes
|
|
67
67
|
|
|
68
68
|
def hours
|
|
69
69
|
self * 3600
|
|
70
70
|
end
|
|
71
|
-
|
|
71
|
+
alias_method :hour, :hours
|
|
72
72
|
|
|
73
73
|
def days
|
|
74
|
-
self *
|
|
74
|
+
self * 86_400
|
|
75
75
|
end
|
|
76
|
-
|
|
76
|
+
alias_method :day, :days
|
|
77
77
|
|
|
78
78
|
def weeks
|
|
79
|
-
self *
|
|
79
|
+
self * 86_400 * 7
|
|
80
80
|
end
|
|
81
|
-
|
|
81
|
+
alias_method :week, :weeks
|
|
82
82
|
|
|
83
83
|
def ago
|
|
84
84
|
::Time.now - self
|
|
@@ -87,25 +87,25 @@ class Numeric
|
|
|
87
87
|
def bytes
|
|
88
88
|
self
|
|
89
89
|
end
|
|
90
|
-
|
|
90
|
+
alias_method :byte, :bytes
|
|
91
91
|
|
|
92
92
|
def kilobytes
|
|
93
93
|
self * 1024
|
|
94
94
|
end
|
|
95
|
-
|
|
95
|
+
alias_method :kilobyte, :kilobytes
|
|
96
96
|
|
|
97
97
|
def megabytes
|
|
98
98
|
self * 1024 * 1024
|
|
99
99
|
end
|
|
100
|
-
|
|
100
|
+
alias_method :megabyte, :megabytes
|
|
101
101
|
|
|
102
102
|
def gigabytes
|
|
103
103
|
self * 1024 * 1024 * 1024
|
|
104
104
|
end
|
|
105
|
-
|
|
105
|
+
alias_method :gigabyte, :gigabytes
|
|
106
106
|
|
|
107
107
|
def terabytes
|
|
108
108
|
self * 1024 * 1024 * 1024 * 1024
|
|
109
109
|
end
|
|
110
|
-
|
|
110
|
+
alias_method :terabyte, :terabytes
|
|
111
111
|
end
|