eye 0.2.2 → 0.2.3

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: ec5135b6c531e9451f98ec8b9d36a54d2e57e3f9
4
- data.tar.gz: fd8011e705ee96d0d24dffbe03be598a18b285c4
3
+ metadata.gz: b27fc1f2b1ca918d1dec48f63af0f59446f6a166
4
+ data.tar.gz: b823fadfaea2111a8c57ec07e4b2ae84ad7899a2
5
5
  SHA512:
6
- metadata.gz: 59237be9adb524bdc90ddb9203d3246e7e6fc03f4b9c7398df2380fba2423e68592a996ac720ff04cd8a813b34ed8a27a1c259421907dd1103b18ad508c9decd
7
- data.tar.gz: b741a332f8888e3f5a2dd50af91e0dbafebed8f8dcc406f9f8cab270b565f3ce2624adef2e4b9c2b3be0a01ff18dcbaf28159d4ba55b6d532e37711b8c9fa5cd
6
+ metadata.gz: 6fd472f37e8123f426b45409e2067c1bf901cf265aa37a3480229eda6dcbc8fcdca4c51656580cc756c305da9f565f18a35dda277a48f188da36bb69a02effa0
7
+ data.tar.gz: ce0459d1f8d2d0d236a9ca2586ed44e2e173b6c82bfc6c426c473e9d0c20dce20bf28935af89efc23f2e33a48be9953a61fd0a2e0b5b536ef62e8fbd32a38997
data/README.md CHANGED
@@ -30,7 +30,7 @@ Eye.application "test" do
30
30
  working_dir File.expand_path(File.join(File.dirname(__FILE__), %w[ processes ]))
31
31
  stdall "trash.log" # stdout,err logs for processes by default
32
32
  env "APP_ENV" => "production" # global env for each processes
33
- triggers :flapping, :times => 10, :within => 1.minute #
33
+ triggers :flapping, :times => 10, :within => 1.minute, :retry_in => 10.minutes
34
34
  checks :cpu, :below => 100, :times => 3 # global check for all processes
35
35
 
36
36
  group "samples" do
@@ -14,7 +14,7 @@ Eye.application "test" do
14
14
  working_dir File.expand_path(File.join(File.dirname(__FILE__), %w[ processes ]))
15
15
  stdall "trash.log" # stdout,err logs for processes by default
16
16
  env "APP_ENV" => "production" # global env for each processes
17
- triggers :flapping, :times => 10, :within => 1.minute #
17
+ triggers :flapping, :times => 10, :within => 1.minute, :retry_in => 10.minutes
18
18
  checks :cpu, :below => 100, :times => 3 # global check for all processes
19
19
 
20
20
  group "samples" do
@@ -8,7 +8,7 @@ Gem::Specification.new do |gem|
8
8
  %q{Process monitoring tool. An alternative to God and Bluepill. With Bluepill like config syntax. Requires MRI Ruby >= 1.9.2. Uses Celluloid and Celluloid::IO.}
9
9
  gem.homepage = "http://github.com/kostya/eye"
10
10
 
11
- gem.files = `git ls-files`.split($\)
11
+ gem.files = `git ls-files`.split($\).reject{|n| n =~ %r[png|gif\z]}
12
12
  gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
13
13
  gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
14
14
  gem.name = "eye"
@@ -21,7 +21,7 @@ Gem::Specification.new do |gem|
21
21
 
22
22
  gem.add_dependency 'celluloid', '~> 0.12.0'
23
23
  gem.add_dependency 'celluloid-io', '~> 0.12.0'
24
- gem.add_dependency 'state_machine'
24
+ gem.add_dependency 'state_machine', '< 1.2'
25
25
  gem.add_dependency 'activesupport', '~> 3.2.0'
26
26
  gem.add_dependency 'thor'
27
27
 
data/lib/eye.rb CHANGED
@@ -1,5 +1,5 @@
1
1
  module Eye
2
- VERSION = "0.2.2"
2
+ VERSION = "0.2.3"
3
3
  ABOUT = "Eye v#{VERSION} (c) 2012-2013 @kostya"
4
4
 
5
5
  autoload :Process, 'eye/process'
@@ -95,7 +95,7 @@ private
95
95
  Net::HTTP.new(@uri.host, @uri.port).tap do |session|
96
96
  if @uri.scheme == 'https'
97
97
  require 'net/https'
98
- session.use_ssl=true
98
+ session.use_ssl = true
99
99
  session.verify_mode = OpenSSL::SSL::VERIFY_NONE
100
100
  end
101
101
  session.open_timeout = @open_timeout
@@ -39,7 +39,7 @@ class Eye::Controller
39
39
 
40
40
  Eye::SystemResources.setup
41
41
 
42
- info "starting #{Eye::ABOUT}"
42
+ info "starting #{Eye::ABOUT} (#{$$})"
43
43
  end
44
44
 
45
45
  end
@@ -90,7 +90,7 @@ private
90
90
 
91
91
  res = []
92
92
  str = Regexp.escape(mask).gsub('\*', '.*?')
93
- r = %r{\A#{str}\z}
93
+ r = %r{\A#{str}}
94
94
 
95
95
  # find app
96
96
  res = @applications.select{|a| a.name =~ r || a.full_name =~ r }
@@ -6,7 +6,7 @@ gem 'nio4r'
6
6
  gem 'facter'
7
7
  gem 'timers'
8
8
 
9
- gem 'state_machine'
9
+ gem 'state_machine', '< 1.2'
10
10
  gem 'activesupport', '~> 3.2.0'
11
11
 
12
12
  gem 'i18n' # for as
@@ -18,7 +18,7 @@ class Eye::Process
18
18
  autoload :Validate, 'eye/process/validate'
19
19
 
20
20
  attr_accessor :pid, :watchers, :config, :states_history,
21
- :childs, :triggers, :flapping, :name
21
+ :childs, :triggers, :name, :state_reason
22
22
 
23
23
  def initialize(config)
24
24
  raise 'pid file should be' unless config[:pid_file]
@@ -29,7 +29,6 @@ class Eye::Process
29
29
  @watchers = {}
30
30
  @childs = {}
31
31
  @triggers = []
32
- @flapping = false
33
32
  @name = @config[:name]
34
33
 
35
34
  @states_history = Eye::Process::StatesHistory.new(100)
@@ -39,7 +39,8 @@ module Eye::Process::Data
39
39
  end
40
40
 
41
41
  def sub_object?(obj)
42
- # we not recognize childs
42
+ return false if self.class == Eye::ChildProcess
43
+ self.childs.each { |_, child| return true if child == obj }
43
44
  false
44
45
  end
45
46
 
@@ -76,13 +76,15 @@ private
76
76
 
77
77
  def check_crash
78
78
  if down?
79
- if self[:keep_alive] && !@flapping
79
+ if self[:keep_alive]
80
80
  warn 'check crashed: process is down'
81
81
  schedule :start, 'crashed'
82
82
  else
83
- warn 'check crashed: process is down, and flapping happens (or not keep_alive option)'
84
- schedule :unmonitor, 'flapping'
83
+ warn 'check crashed: process without keep_alive'
84
+ schedule :unmonitor, 'crashed'
85
85
  end
86
+ else
87
+ debug 'check crashed: skipped, process is not in down'
86
88
  end
87
89
  end
88
90
 
@@ -3,7 +3,7 @@ module Eye::Process::Scheduler
3
3
  # ex: schedule :update_config, config, "reason: update_config"
4
4
  def schedule(command, *args, &block)
5
5
  if scheduler.alive?
6
- unless self.respond_to?(command)
6
+ unless self.respond_to?(command, true)
7
7
  warn "object not support :#{command} to schedule"
8
8
  return
9
9
  end
@@ -17,6 +17,14 @@ module Eye::Process::Scheduler
17
17
  end
18
18
  end
19
19
 
20
+ def schedule_in(interval, command, *args, &block)
21
+ debug "schedule_in #{interval} :#{command} #{args}"
22
+ after(interval.to_f) do
23
+ debug "scheduled_in #{interval} :#{command} #{args}"
24
+ schedule(command, *args, &block)
25
+ end
26
+ end
27
+
20
28
  def scheduled_action(command, h = {}, &block)
21
29
  reason = h.delete(:reason)
22
30
  info "=> #{command} #{h[:args].present? ? "#{h[:args]*',' }" : nil} #{reason ? "(reason: #{reason})" : nil}"
@@ -52,12 +52,12 @@ class Eye::Process
52
52
  transition any => :unmonitored
53
53
  end
54
54
 
55
- after_transition :on => :crashed, :do => :on_crashed
56
55
  after_transition any => :unmonitored, :do => :on_unmonitored
57
56
  after_transition any-:up => :up, :do => :on_up
58
57
  after_transition :up => any-:up, :do => :from_up
59
58
  after_transition any => any, :do => :log_transition
60
- after_transition any => any, :do => :upd_for_triggers
59
+ after_transition any => any, :do => :check_triggers
60
+ after_transition :on => :crashed, :do => :on_crashed
61
61
  end
62
62
 
63
63
  def on_crashed
@@ -65,7 +65,6 @@ class Eye::Process
65
65
  end
66
66
 
67
67
  def on_unmonitored
68
- self.flapping = false
69
68
  self.pid = nil
70
69
  end
71
70
 
@@ -84,8 +83,4 @@ class Eye::Process
84
83
  info "switch :#{transition.event} [:#{transition.from_name} => :#{transition.to_name}] #{@state_reason ? "(reason: #{@state_reason})" : nil}"
85
84
  end
86
85
 
87
- def upd_for_triggers(transition)
88
- check_triggers
89
- end
90
-
91
86
  end
@@ -8,11 +8,11 @@ class Eye::Process::StatesHistory < Eye::Utils::Tail
8
8
  self.map{|c| c[:state] }
9
9
  end
10
10
 
11
- def states_for_period(period)
11
+ def states_for_period(period, from_time = nil)
12
12
  tm = Time.now - period
13
- self.select do |s|
14
- s[:at] >= tm
15
- end.map{|c| c[:state] }
13
+ tm = [tm, from_time].max if from_time
14
+
15
+ self.select{|s| s[:at] >= tm }.map{|c| c[:state] }
16
16
  end
17
17
 
18
18
  def last_state
@@ -16,9 +16,8 @@ module Eye::Process::Trigger
16
16
  return if unmonitored?
17
17
 
18
18
  self.triggers.each do |trigger|
19
- if !trigger.check(self.states_history)
20
- notify :crit, 'flapping!'
21
- @flapping = true
19
+ unless trigger.check(self.states_history)
20
+ on_flapping(trigger) if trigger.class == Eye::Trigger::Flapping
22
21
  end
23
22
  end
24
23
  end
@@ -26,7 +25,30 @@ module Eye::Process::Trigger
26
25
  private
27
26
 
28
27
  def add_trigger(cfg = {})
29
- self.triggers << Eye::Trigger.create(cfg, logger.prefix)
28
+ trigger = Eye::Trigger.create(cfg, logger.prefix)
29
+ self.triggers << trigger
30
30
  end
31
31
 
32
- end
32
+ def on_flapping(trigger)
33
+ notify :crit, 'flapping!'
34
+ schedule :unmonitor, "flapping"
35
+
36
+ @retry_times ||= 0
37
+ retry_in = trigger.retry_in
38
+
39
+ return unless retry_in
40
+ return if trigger.retry_times && @retry_times >= trigger.retry_times
41
+
42
+ schedule_in(retry_in.to_f, :retry_action)
43
+ end
44
+
45
+ def retry_action
46
+ debug "trigger retry timer"
47
+ return unless unmonitored?
48
+ return unless state_reason.to_s.include?('flapping') # TODO: remove hackety
49
+
50
+ schedule :start, "retry start after flapping"
51
+ @retry_times += 1
52
+ end
53
+
54
+ end
@@ -74,7 +74,7 @@ class Eye::SystemResources
74
74
  private
75
75
 
76
76
  def set
77
- @ps_aux = Eye::System.ps_aux
77
+ @ps_aux = defer{ Eye::System.ps_aux }
78
78
  @at = Time.now
79
79
  end
80
80
 
@@ -27,7 +27,7 @@ class Eye::Trigger
27
27
  @options = options
28
28
  @logger = Eye::Logger.new(logger_prefix, "trigger")
29
29
 
30
- debug "add trigger #{options}"
30
+ debug "add #{options}"
31
31
  end
32
32
 
33
33
  def check(states_history)
@@ -1,20 +1,24 @@
1
1
  class Eye::Trigger::Flapping < Eye::Trigger
2
2
 
3
- # triggers :flapping, :times => 10, :within => 1.minute
3
+ # triggers :flapping, :times => 10, :within => 1.minute,
4
+ # :retry_in => 10.minutes, :retry_times => 15
4
5
 
5
- param :times, [Fixnum], true
6
+ param :times, [Fixnum], true, 5
6
7
  param :within, [Float, Fixnum], true
8
+ param :retry_in, [Float, Fixnum]
9
+ param :retry_times, [Fixnum]
7
10
 
8
- def good?
9
- return true unless within
10
-
11
- states = @states_history.states_for_period( within )
11
+ def initialize(*args)
12
+ super
13
+ @last_at = nil
14
+ end
12
15
 
13
- starting_count = states.count{|st| st == :starting}
14
- down_count = states.count{|st| st == :down}
15
- times_count = times || 5
16
+ def good?
17
+ states = @states_history.states_for_period( within, @last_at )
18
+ down_count = states.count{|st| st == :down }
16
19
 
17
- if (starting_count >= times_count) && (down_count >= times_count)
20
+ if down_count >= times
21
+ @last_at = @states_history.last_state_changed_at
18
22
  false
19
23
  else
20
24
  true
@@ -77,6 +77,26 @@ describe "find_objects" do
77
77
  subject.find_objects("asdfasdf").should == []
78
78
  end
79
79
 
80
+ describe "submatching without * " do
81
+ it "match by start symbols, apps" do
82
+ objs = subject.find_objects("app")
83
+ objs.map{|c| c.class}.should == [Eye::Application, Eye::Application]
84
+ objs.map{|c| c.name}.sort.should == %w{app1 app2}
85
+ end
86
+
87
+ it "match by start symbols, groups" do
88
+ objs = subject.find_objects("gr")
89
+ objs.map{|c| c.class}.should == [Eye::Group, Eye::Group]
90
+ objs.map{|c| c.name}.sort.should == %w{gr1 gr2}
91
+ end
92
+
93
+ it "match by start symbols, process" do
94
+ objs = subject.find_objects("z")
95
+ objs.map{|c| c.class}.should == [Eye::Process]
96
+ objs.map{|c| c.name}.sort.should == %w{z1}
97
+ end
98
+ end
99
+
80
100
  describe "find by routes" do
81
101
  it "group" do
82
102
  objs = subject.find_objects("app1:gr2")
@@ -102,7 +122,7 @@ describe "find_objects" do
102
122
  subject{ c = Eye::Controller.new; c.load(fixture("dsl/load_dubls.eye")); c }
103
123
 
104
124
  it "not found" do
105
- subject.find_objects("z").should == []
125
+ subject.find_objects("zu").should == []
106
126
  end
107
127
 
108
128
  it "found 2 processed" do
@@ -139,11 +159,11 @@ describe "find_objects" do
139
159
 
140
160
  describe "missing" do
141
161
  it "should not found" do
142
- subject.find_objects("app1:gr2:q").should == []
143
- subject.find_objects("gr1:p1").should == []
162
+ subject.find_objects("app1:gr4").should == []
163
+ subject.find_objects("gr:p").should == []
144
164
  subject.find_objects("pp1").should == []
145
165
  subject.find_objects("app1::").should == []
146
- subject.find_objects("app1:").should == []
166
+ subject.find_objects("app1:=").should == []
147
167
  end
148
168
  end
149
169
 
@@ -155,4 +155,14 @@ describe "Scheduler" do
155
155
  @process.test3.should == [1, :bla, 3]
156
156
  end
157
157
  end
158
+
159
+ describe "schedule_in" do
160
+ it "should schedule to future" do
161
+ @process.schedule_in(1.second, :scheduler_test3, 1, 2, 3)
162
+ sleep 0.5
163
+ @process.test3.should == nil
164
+ sleep 0.6
165
+ @process.test3.should == [1,2,3]
166
+ end
167
+ end
158
168
  end
@@ -26,6 +26,12 @@ describe "Eye::Process::StatesHistory" do
26
26
  @h.states_for_period(1.5.minutes).should == [:up, :down]
27
27
  @h.states_for_period(2.5.minutes).should == [:stop, :up, :down]
28
28
  @h.states_for_period(6.minutes).should == [:up, :down, :start, :stop, :up, :down]
29
+
30
+ # with start_point
31
+ @h.states_for_period(2.5.minutes, 5.minutes.ago).should == [:stop, :up, :down]
32
+ @h.states_for_period(2.5.minutes, nil).should == [:stop, :up, :down]
33
+ @h.states_for_period(2.5.minutes, 1.5.minutes.ago).should == [:up, :down]
34
+ @h.states_for_period(2.5.minutes, Time.now).should == []
29
35
  end
30
36
 
31
37
  it "seq?" do
@@ -42,6 +42,7 @@ describe "Flapping" do
42
42
 
43
43
  @process.state_name.should == :unmonitored
44
44
  @process.watchers.keys.should == []
45
+ @process.states_history.states.last(2).should == [:down, :unmonitored]
45
46
  end
46
47
 
47
48
  it "process flapping emulate with kill" do
@@ -49,14 +50,37 @@ describe "Flapping" do
49
50
 
50
51
  @process.start
51
52
 
52
- # 4 times because, flapping flag, check on next switch
53
- 4.times do
53
+ 3.times do
54
54
  die_process!(@process.pid)
55
55
  sleep 3
56
56
  end
57
57
 
58
58
  @process.state_name.should == :unmonitored
59
59
  @process.watchers.keys.should == []
60
+
61
+ # ! should switched to unmonitored from down status
62
+ @process.states_history.states.last(2).should == [:down, :unmonitored]
63
+ end
64
+
65
+ it "process flapping, and then send to start and fast kill, should ok started" do
66
+ @process = process(@c.merge(:triggers => C.flapping(:times => 3, :within => 15)))
67
+
68
+ @process.start
69
+
70
+ 3.times do
71
+ die_process!(@process.pid)
72
+ sleep 3
73
+ end
74
+
75
+ @process.state_name.should == :unmonitored
76
+ @process.watchers.keys.should == []
77
+
78
+ @process.start
79
+ @process.state_name.should == :up
80
+
81
+ die_process!(@process.pid)
82
+ sleep 4
83
+ @process.state_name.should == :up
60
84
  end
61
85
 
62
86
  it "flapping not happens" do
@@ -67,15 +91,152 @@ describe "Flapping" do
67
91
  proxy(@process).schedule(:check_crash, anything)
68
92
  dont_allow(@process).schedule(:unmonitor)
69
93
 
94
+ sleep 2
70
95
 
71
- sleep 5
72
-
73
- # even if process die in middle
74
- die_process!(@process.pid)
96
+ 2.times do
97
+ die_process!(@process.pid)
98
+ sleep 3
99
+ end
75
100
 
76
- sleep 5
101
+ sleep 2
77
102
 
78
103
  @process.state_name.should == :up
79
104
  end
80
105
 
106
+ describe "retry_in, retry_times" do
107
+ before :each do
108
+ @c = C.p1.merge(
109
+ :triggers => C.flapping(:times => 2, :within => 3),
110
+ :start_grace => 0.1, # for fast flapping
111
+ :stop_grace => 0,
112
+ :start_command => @c[:start_command] + " -r"
113
+ )
114
+ end
115
+
116
+ it "flapping than wait for interval and try again" do
117
+ @process = process(@c.merge(:triggers => C.flapping(:times => 2, :within => 3,
118
+ :retry_in => 5.seconds)))
119
+ @process.start!
120
+
121
+ sleep 18
122
+
123
+ h = @process.states_history
124
+
125
+ # был в unmonitored
126
+ h.shift[:state].should == :unmonitored
127
+
128
+ # должен попытаться подняться два раза,
129
+ h.shift(6)
130
+
131
+ # затем перейти в unmonitored с причиной flapping
132
+ flapp1 = h.shift
133
+ flapp1[:state].should == :unmonitored
134
+ flapp1[:reason].should == 'flapping'
135
+
136
+ # затем снова попыться подняться два раза
137
+ h.shift(6)
138
+
139
+ # и снова перейти в unmonitored с причиной flapping
140
+ flapp2 = h.shift
141
+ flapp2[:state].should == :unmonitored
142
+ flapp2[:reason].should == 'flapping'
143
+
144
+ # интервал между переходами во flapping должен быть больше 8 сек
145
+ (flapp2[:at] - flapp1[:at]).should > 5.seconds
146
+
147
+ # тут снова должен пытаться подниматься так как нет лимитов
148
+ h.should_not be_blank
149
+ end
150
+
151
+ it "flapping retry 1 times with retry_times = 1" do
152
+ @process = process(@c.merge(:triggers => C.flapping(:times => 2, :within => 3,
153
+ :retry_in => 5.seconds, :retry_times => 1)))
154
+ @process.start!
155
+
156
+ sleep 18
157
+
158
+ h = @process.states_history
159
+
160
+ # был в unmonitored
161
+ h.shift[:state].should == :unmonitored
162
+
163
+ # должен попытаться подняться два раза,
164
+ h.shift(6)
165
+
166
+ # затем перейти в unmonitored с причиной flapping
167
+ flapp1 = h.shift
168
+ flapp1[:state].should == :unmonitored
169
+ flapp1[:reason].should == 'flapping'
170
+
171
+ # затем снова попыться подняться два раза
172
+ h.shift(6)
173
+
174
+ # и снова перейти в unmonitored с причиной flapping
175
+ flapp2 = h.shift
176
+ flapp2[:state].should == :unmonitored
177
+ flapp2[:reason].should == 'flapping'
178
+
179
+ # интервал между переходами во flapping должен быть больше 8 сек
180
+ (flapp2[:at] - flapp1[:at]).should > 5.seconds
181
+
182
+ # все финал
183
+ h.should be_blank
184
+ end
185
+
186
+ it "flapping than manually doing something, should not retry" do
187
+ @process = process(@c.merge(:triggers => C.flapping(:times => 2, :within => 3,
188
+ :retry_in => 5.seconds)))
189
+ @process.start!
190
+
191
+ sleep 6
192
+ @process.send_command :unmonitor
193
+ sleep 9
194
+
195
+ h = @process.states_history
196
+
197
+ # был в unmonitored
198
+ h.shift[:state].should == :unmonitored
199
+
200
+ # должен попытаться подняться два раза,
201
+ h.shift(6)
202
+
203
+ # затем перейти в unmonitored с причиной flapping
204
+ flapp1 = h.shift
205
+ flapp1[:state].should == :unmonitored
206
+ flapp1[:reason].should == 'flapping'
207
+
208
+ # затем его руками переводят в unmonitored
209
+ unm = h.shift
210
+ unm[:state].should == :unmonitored
211
+ unm[:reason].should == 'unmonitor by user'
212
+
213
+ # все финал
214
+ h.should be_blank
215
+ end
216
+
217
+ it "without retry_in" do
218
+ @process = process(@c.merge(:triggers => C.flapping(:times => 2, :within => 3)))
219
+ @process.start!
220
+
221
+ sleep 10
222
+
223
+ h = @process.states_history
224
+
225
+ # был в unmonitored
226
+ h.shift[:state].should == :unmonitored
227
+
228
+ # должен попытаться подняться два раза,
229
+ h.shift(6)
230
+
231
+ # затем перейти в unmonitored с причиной flapping
232
+ flapp1 = h.shift
233
+ flapp1[:state].should == :unmonitored
234
+ flapp1[:reason].should == 'flapping'
235
+
236
+ # все финал
237
+ h.should be_blank
238
+ end
239
+
240
+ end
241
+
81
242
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: eye
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.2
4
+ version: 0.2.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - Konstantin Makarchev
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2013-03-30 00:00:00.000000000 Z
11
+ date: 2013-04-14 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: celluloid
@@ -42,16 +42,16 @@ dependencies:
42
42
  name: state_machine
43
43
  requirement: !ruby/object:Gem::Requirement
44
44
  requirements:
45
- - - '>='
45
+ - - <
46
46
  - !ruby/object:Gem::Version
47
- version: '0'
47
+ version: '1.2'
48
48
  type: :runtime
49
49
  prerelease: false
50
50
  version_requirements: !ruby/object:Gem::Requirement
51
51
  requirements:
52
- - - '>='
52
+ - - <
53
53
  - !ruby/object:Gem::Version
54
- version: '0'
54
+ version: '1.2'
55
55
  - !ruby/object:Gem::Dependency
56
56
  name: activesupport
57
57
  requirement: !ruby/object:Gem::Requirement