symphony-metronome 0.1.0 → 0.2.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -24,8 +24,8 @@ class Symphony::Metronome::ScheduledEvent
24
24
  # Configure defaults.
25
25
  #
26
26
  CONFIG_DEFAULTS = {
27
- db: 'sqlite:///tmp/metronome.db',
28
- splay: 0
27
+ :db => 'sqlite:///tmp/metronome.db',
28
+ :splay => 0
29
29
  }
30
30
 
31
31
  class << self
@@ -52,6 +52,7 @@ class Symphony::Metronome::ScheduledEvent
52
52
  #
53
53
  migrations_dir = Symphony::Metronome::DATADIR + 'migrations'
54
54
  unless Sequel::Migrator.is_current?( self.db, migrations_dir.to_s )
55
+ Loggability[ Symphony ].info "Installing database schema..."
55
56
  Sequel::Migrator.apply( self.db, migrations_dir.to_s )
56
57
  end
57
58
  end
@@ -97,6 +98,8 @@ class Symphony::Metronome::ScheduledEvent
97
98
  @event = Symphony::Metronome::IntervalExpression.parse( row[:expression], row[:created] )
98
99
  @options = row.delete( :options )
99
100
  @id = row.delete( :id )
101
+ @ds = self.class.db[ :metronome ].filter( :id => self.id )
102
+
100
103
  self.reset_runtime
101
104
 
102
105
  unless self.class.splay.zero?
@@ -105,6 +108,9 @@ class Symphony::Metronome::ScheduledEvent
105
108
  end
106
109
  end
107
110
 
111
+ # The sequel dataset representing this event.
112
+ attr_reader :ds
113
+
108
114
  # The parsed interval expression.
109
115
  attr_reader :event
110
116
 
@@ -133,7 +139,21 @@ class Symphony::Metronome::ScheduledEvent
133
139
  # Otherwise, the event should already be running (start time has already
134
140
  # elapsed), so schedule it forward on it's next interval iteration.
135
141
  #
136
- @runtime = now + self.event.interval
142
+ # If it's a recurring event that has run before, consider the elapsed time
143
+ # as part of the next calculation.
144
+ #
145
+ row = self.ds.first
146
+ if self.event.recurring && row
147
+ last = row[ :lastrun ]
148
+ if last && now > last
149
+ @runtime = now + self.event.interval - ( now - last )
150
+ else
151
+ @runtime = now + self.event.interval
152
+ end
153
+
154
+ else
155
+ @runtime = now + self.event.interval
156
+ end
137
157
  end
138
158
 
139
159
 
@@ -141,13 +161,36 @@ class Symphony::Metronome::ScheduledEvent
141
161
  ### deserialized options, the action ID to the supplied block if
142
162
  ### this event is okay to execute.
143
163
  ###
164
+ ### If the event is recurring, perform additional checks against the
165
+ ### last run time.
166
+ ###
144
167
  ### Automatically remove the event if it has expired.
145
168
  ###
146
169
  def fire
147
170
  rv = self.event.fire?
148
171
 
172
+ # Just based on the expression parser, is this event ready to fire?
173
+ #
149
174
  if rv
150
175
  opts = Yajl.load( self.options )
176
+
177
+ # Don't fire recurring events unless their interval has elapsed.
178
+ # This prevents events from triggering when the daemon receives
179
+ # a HUP.
180
+ #
181
+ if self.event.recurring
182
+ now = Time.now
183
+ row = self.ds.first
184
+
185
+ if row
186
+ last = row[ :lastrun ]
187
+ return false if last && now - last < self.event.interval
188
+ end
189
+
190
+ # Mark the time this recurring event was fired.
191
+ self.ds.update( :lastrun => Time.now )
192
+ end
193
+
151
194
  yield opts, self.id
152
195
  end
153
196
 
@@ -160,7 +203,7 @@ class Symphony::Metronome::ScheduledEvent
160
203
  ###
161
204
  def delete
162
205
  self.log.debug "Removing action %p" % [ self.id ]
163
- self.class.db[ :metronome ].filter( :id => self.id ).delete
206
+ self.ds.delete
164
207
  end
165
208
 
166
209
 
@@ -18,7 +18,7 @@ class Symphony::Metronome::Scheduler
18
18
  SIGNALS = [ :HUP, :INT, :TERM ]
19
19
 
20
20
  CONFIG_DEFAULTS = {
21
- :listen => true
21
+ :listen => false
22
22
  }
23
23
 
24
24
  class << self
@@ -126,7 +126,7 @@ class Symphony::Metronome::Scheduler
126
126
  end
127
127
 
128
128
 
129
- ### Process all event that have reached their runtime.
129
+ ### Process all events that have reached their runtime.
130
130
  ###
131
131
  def process_events
132
132
  now = Time.now
metadata CHANGED
@@ -1,97 +1,119 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: symphony-metronome
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.2.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Mahlon E. Smith <mahlon@martini.nu>
8
8
  autorequire:
9
9
  bindir: bin
10
- cert_chain: []
11
- date: 2014-04-22 00:00:00.000000000 Z
10
+ cert_chain:
11
+ - |
12
+ -----BEGIN CERTIFICATE-----
13
+ MIIDbDCCAlSgAwIBAgIBATANBgkqhkiG9w0BAQUFADA+MQ8wDQYDVQQDDAZtYWhs
14
+ b24xFzAVBgoJkiaJk/IsZAEZFgdtYXJ0aW5pMRIwEAYKCZImiZPyLGQBGRYCbnUw
15
+ HhcNMTUwMzI3MjIwNzQ0WhcNMTYwMzI2MjIwNzQ0WjA+MQ8wDQYDVQQDDAZtYWhs
16
+ b24xFzAVBgoJkiaJk/IsZAEZFgdtYXJ0aW5pMRIwEAYKCZImiZPyLGQBGRYCbnUw
17
+ ggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDpXGN0YbMVpYv4EoiCxpQw
18
+ sxKdyhlkvpvENUkpEhbpnEuMKXgUfRHO4T/vBZf0h8eYgwnrHCRhAeIqesFKfoj9
19
+ mpEJk5JUuADOAz18aT+v24UqAtJdiwBJLuqhslSNB6CFXZv3OOMny9bjoJegz0hI
20
+ Fht9ppCuNmxJNd+L3zAX8lD01RUWNRC+8L5QLCjViJtjFDDCFfh9NCirs+XnTCzo
21
+ AJgFbsZIzFJtSiXUtFgscKr4Ik8ruhRbPbYbmx9rf6W74aTMPxggq/d3gj0Eh32y
22
+ WsXsQ5giVnmkbsRkBNu3QyZ8Xr5+7mvy5AWyqXKOrcW7lnYaob6Z9x/MGXGNeD6j
23
+ AgMBAAGjdTBzMAkGA1UdEwQCMAAwCwYDVR0PBAQDAgSwMB0GA1UdDgQWBBRY8ea6
24
+ +6kAaW7ukKph2/4MTAD8/TAcBgNVHREEFTATgRFtYWhsb25AbWFydGluaS5udTAc
25
+ BgNVHRIEFTATgRFtYWhsb25AbWFydGluaS5udTANBgkqhkiG9w0BAQUFAAOCAQEA
26
+ DP5Nkbz/Cn9CWZo19MCUJCl7UXTjhiYrCler/JsbZJq0+BFIV+bDWuVxyaNyv3Tn
27
+ lqV+TmIUwv1MAklenb0wLRzCV2Z7AV3DbSIRfN40G9xc87MOG+8zx4SaMbw9EloP
28
+ 3rubBnAGvTBaNy1+0byAwhF8sx8chhJDDayusdg2auErvAWgQk4t3c6IH6wU2rt2
29
+ NlO8QBa0U0D1hzwuiDPsuNQoLQnn8+E/Osz7RyMN4FmhGdaFg4hdlbo6bWRofZL7
30
+ R1mvNMxDDunWP1mKW80U5LUAU5SpqoLczW5QBLQUZUResTbNGSWW8EbngbTrseOz
31
+ 6uw87VFLpcRJxE/HNXJMSg==
32
+ -----END CERTIFICATE-----
33
+ date: 2015-07-08 00:00:00.000000000 Z
12
34
  dependencies:
13
35
  - !ruby/object:Gem::Dependency
14
36
  name: symphony
15
37
  requirement: !ruby/object:Gem::Requirement
16
38
  requirements:
17
- - - ~>
39
+ - - "~>"
18
40
  - !ruby/object:Gem::Version
19
- version: '0.6'
41
+ version: '0.9'
20
42
  type: :runtime
21
43
  prerelease: false
22
44
  version_requirements: !ruby/object:Gem::Requirement
23
45
  requirements:
24
- - - ~>
46
+ - - "~>"
25
47
  - !ruby/object:Gem::Version
26
- version: '0.6'
48
+ version: '0.9'
27
49
  - !ruby/object:Gem::Dependency
28
50
  name: sequel
29
51
  requirement: !ruby/object:Gem::Requirement
30
52
  requirements:
31
- - - ~>
53
+ - - "~>"
32
54
  - !ruby/object:Gem::Version
33
55
  version: '4'
34
56
  type: :runtime
35
57
  prerelease: false
36
58
  version_requirements: !ruby/object:Gem::Requirement
37
59
  requirements:
38
- - - ~>
60
+ - - "~>"
39
61
  - !ruby/object:Gem::Version
40
62
  version: '4'
41
63
  - !ruby/object:Gem::Dependency
42
64
  name: sqlite3
43
65
  requirement: !ruby/object:Gem::Requirement
44
66
  requirements:
45
- - - ~>
67
+ - - "~>"
46
68
  - !ruby/object:Gem::Version
47
69
  version: '1.3'
48
70
  type: :runtime
49
71
  prerelease: false
50
72
  version_requirements: !ruby/object:Gem::Requirement
51
73
  requirements:
52
- - - ~>
74
+ - - "~>"
53
75
  - !ruby/object:Gem::Version
54
76
  version: '1.3'
55
77
  - !ruby/object:Gem::Dependency
56
78
  name: rspec
57
79
  requirement: !ruby/object:Gem::Requirement
58
80
  requirements:
59
- - - ~>
81
+ - - "~>"
60
82
  - !ruby/object:Gem::Version
61
- version: '3.0'
83
+ version: '3.3'
62
84
  type: :development
63
85
  prerelease: false
64
86
  version_requirements: !ruby/object:Gem::Requirement
65
87
  requirements:
66
- - - ~>
88
+ - - "~>"
67
89
  - !ruby/object:Gem::Version
68
- version: '3.0'
90
+ version: '3.3'
69
91
  - !ruby/object:Gem::Dependency
70
92
  name: simplecov
71
93
  requirement: !ruby/object:Gem::Requirement
72
94
  requirements:
73
- - - ~>
95
+ - - "~>"
74
96
  - !ruby/object:Gem::Version
75
- version: '0.8'
97
+ version: '0.9'
76
98
  type: :development
77
99
  prerelease: false
78
100
  version_requirements: !ruby/object:Gem::Requirement
79
101
  requirements:
80
- - - ~>
102
+ - - "~>"
81
103
  - !ruby/object:Gem::Version
82
- version: '0.8'
104
+ version: '0.9'
83
105
  - !ruby/object:Gem::Dependency
84
106
  name: timecop
85
107
  requirement: !ruby/object:Gem::Requirement
86
108
  requirements:
87
- - - ~>
109
+ - - "~>"
88
110
  - !ruby/object:Gem::Version
89
111
  version: '0.7'
90
112
  type: :development
91
113
  prerelease: false
92
114
  version_requirements: !ruby/object:Gem::Requirement
93
115
  requirements:
94
- - - ~>
116
+ - - "~>"
95
117
  - !ruby/object:Gem::Version
96
118
  version: '0.7'
97
119
  description: "\t\tMetronome is a scheduler and task runner. It can be used locally
@@ -108,8 +130,10 @@ files:
108
130
  - README.rdoc
109
131
  - bin/metronome-exp
110
132
  - data/symphony-metronome/migrations/20140419_initial.rb
133
+ - data/symphony-metronome/migrations/20141028_lastrun.rb
111
134
  - lib/symphony/metronome.rb
112
135
  - lib/symphony/metronome/intervalexpression.rb
136
+ - lib/symphony/metronome/intervalexpression.rl
113
137
  - lib/symphony/metronome/mixins.rb
114
138
  - lib/symphony/metronome/scheduledevent.rb
115
139
  - lib/symphony/metronome/scheduler.rb
@@ -124,12 +148,12 @@ require_paths:
124
148
  - lib
125
149
  required_ruby_version: !ruby/object:Gem::Requirement
126
150
  requirements:
127
- - - '>='
151
+ - - ">="
128
152
  - !ruby/object:Gem::Version
129
153
  version: 2.0.0
130
154
  required_rubygems_version: !ruby/object:Gem::Requirement
131
155
  requirements:
132
- - - '>='
156
+ - - ">="
133
157
  - !ruby/object:Gem::Version
134
158
  version: 2.0.3
135
159
  requirements: []
@@ -0,0 +1,4 @@
1
+ M5P/s�r��-�u���Qv��.����Fk)���V������q��Eu�����f=�2�
2
+ ��0U����PS�
3
+ ��33�� oe�Mƣ^�G�׳�u���|�����؊RN��]����n=��F�́%#���>�5<�'C$�
4
+ ;�c�ݳy����{�8��W�Ƚ*�t�05���P���![�� '����B�U��)�)�'�z��9rl�oD��b2�[��U�W����_k0Y���d"pE�4� ז�q��ո