Moderizing dev environment.
- Use rake-deveiate. - Fixes for README - Add History, break out Manifest - Remove keyword expansion constant REVISION - Use current Configurability APIs instead of the (now ancient) methods - Whitespace changes FossilOrigin-Name: a778fb275af99a238d9d2311cc601c58adf80e28bd68a37e06acdfb6efeb018d
This commit is contained in:
parent
07c927e13a
commit
2682000224
18 changed files with 210 additions and 227 deletions
9
.fossil-settings/ignore-glob
Normal file
9
.fossil-settings/ignore-glob
Normal file
|
|
@ -0,0 +1,9 @@
|
||||||
|
Session.vim
|
||||||
|
certs/*
|
||||||
|
coverage/*
|
||||||
|
docs/*
|
||||||
|
gem.deps.rb.lock
|
||||||
|
*.so
|
||||||
|
tmp/*
|
||||||
|
lib/symphony/metronome/intervalexpression.rb
|
||||||
|
|
||||||
8
.gems
8
.gems
|
|
@ -1,8 +0,0 @@
|
||||||
autotest -v4.4.6
|
|
||||||
configurability -v2.1.1
|
|
||||||
sequel -v5.4.0
|
|
||||||
sqlite3 -v1.3.9
|
|
||||||
symphony -v0.9.2
|
|
||||||
rspec -v3.3.1
|
|
||||||
timecop -v0.7.1
|
|
||||||
simplecov -v0.9.1
|
|
||||||
11
.hgignore
11
.hgignore
|
|
@ -1,11 +0,0 @@
|
||||||
\.orig$
|
|
||||||
\.rej$
|
|
||||||
etc/.*\.(conf|yml)$
|
|
||||||
\.DS_Store
|
|
||||||
~$
|
|
||||||
pkg/
|
|
||||||
^ChangeLog$
|
|
||||||
^docs/
|
|
||||||
^coverage/
|
|
||||||
lib/symphony/metronome/intervalexpression.rb
|
|
||||||
|
|
||||||
1
.hgtags
1
.hgtags
|
|
@ -1 +0,0 @@
|
||||||
bc6d5e12d577e1a982dfd4cd8ae63e90ce94f876 v0.2.1
|
|
||||||
1
.ruby-gemset
Normal file
1
.ruby-gemset
Normal file
|
|
@ -0,0 +1 @@
|
||||||
|
metronome
|
||||||
1
.ruby-version
Normal file
1
.ruby-version
Normal file
|
|
@ -0,0 +1 @@
|
||||||
|
3.2
|
||||||
32
.rvmrc
32
.rvmrc
|
|
@ -1,32 +0,0 @@
|
||||||
#!/usr/bin/env bash
|
|
||||||
|
|
||||||
# This is an RVM Project .rvmrc file, used to automatically load the ruby
|
|
||||||
# development environment upon cd'ing into the directory
|
|
||||||
|
|
||||||
environment_id="2.1.1@metronome"
|
|
||||||
|
|
||||||
if [[ -d "${rvm_path:-$HOME/.rvm}/environments" \
|
|
||||||
&& -s "${rvm_path:-$HOME/.rvm}/environments/$environment_id" ]]; then
|
|
||||||
echo "Using ${environment_id}"
|
|
||||||
. "${rvm_path:-$HOME/.rvm}/environments/$environment_id"
|
|
||||||
|
|
||||||
if [[ -s "${rvm_path:-$HOME/.rvm}/hooks/after_use" ]]; then
|
|
||||||
. "${rvm_path:-$HOME/.rvm}/hooks/after_use"
|
|
||||||
fi
|
|
||||||
else
|
|
||||||
# If the environment file has not yet been created, use the RVM CLI to select.
|
|
||||||
if ! rvm --create use "$environment_id"
|
|
||||||
then
|
|
||||||
echo "Failed to create RVM environment '${environment_id}'."
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
|
|
||||||
filename=".gems"
|
|
||||||
if [[ -s "$filename" ]]; then
|
|
||||||
rvm gemset import "$filename"
|
|
||||||
fi
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
27
History.md
Normal file
27
History.md
Normal file
|
|
@ -0,0 +1,27 @@
|
||||||
|
# Release History for Symphony-Metronome
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## v0.3.0 [2023-03-20] Mahlon E. Smith <mahlon@martini.nu>
|
||||||
|
|
||||||
|
- Updates for Ruby 3.
|
||||||
|
- Dependency updates.
|
||||||
|
- Conversion to more modern ruby development tooling.
|
||||||
|
|
||||||
|
|
||||||
|
## v0.2.1 [2015-07-08] Mahlon E. Smith <mahlon@martini.nu>
|
||||||
|
|
||||||
|
Enhancements:
|
||||||
|
|
||||||
|
- Add "last run" timestamps for recurring events.
|
||||||
|
|
||||||
|
Fixes:
|
||||||
|
|
||||||
|
- Repair exact start times for recurring events, ie
|
||||||
|
'starting at 2015-01-01 09:00:00 run every other minute for 2 days'
|
||||||
|
|
||||||
|
|
||||||
|
## v0.1.0 [2014-04-22] Mahlon E. Smith <mahlon@martini.nu>
|
||||||
|
|
||||||
|
Initial release.
|
||||||
|
|
||||||
10
Manifest.txt
Normal file
10
Manifest.txt
Normal file
|
|
@ -0,0 +1,10 @@
|
||||||
|
data/symphony-metronome/migrations/20140419_initial.rb
|
||||||
|
data/symphony-metronome/migrations/20141028_lastrun.rb
|
||||||
|
lib/symphony/metronome/intervalexpression.rb
|
||||||
|
lib/symphony/metronome/mixins.rb
|
||||||
|
lib/symphony/metronome/scheduledevent.rb
|
||||||
|
lib/symphony/metronome/scheduler.rb
|
||||||
|
lib/symphony/metronome.rb
|
||||||
|
lib/symphony/tasks/scheduletask.rb
|
||||||
|
History.md
|
||||||
|
README.md
|
||||||
88
README.md
88
README.md
|
|
@ -1,15 +1,26 @@
|
||||||
# Metronome
|
# Metronome
|
||||||
|
|
||||||
|
home
|
||||||
|
: https://code.martini.nu/fossil/symphony-metronome
|
||||||
|
|
||||||
|
docs
|
||||||
|
: https://martini.nu/docs/symphony-metronome
|
||||||
|
|
||||||
|
github_mirror
|
||||||
|
: https://github.com/mahlonsmith/symphony-metronome
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
## Description
|
## Description
|
||||||
|
|
||||||
Metronome is an interval scheduler and task runner. It can be used
|
Metronome is an interval scheduler and task runner. It can be used locally as a
|
||||||
locally as a cron replacement, or as a network-wide job executor.
|
cron replacement, or as a network-wide job executor. It is intended to be run
|
||||||
|
alongside Symphony, a Ruby AMQP event consumer.
|
||||||
|
|
||||||
Events are stored via simple database rows, and optionally managed
|
Events are stored via simple database rows, and optionally themselves managed
|
||||||
via AMQP events. Interval/time values are expressed with intuitive
|
via AMQP events. Interval/time values are expressed with intuitive English
|
||||||
English phrases, ie.: 'at 2pm', or 'Starting in 20 minutes, run every 10
|
phrases, ie.: 'at 2pm', or 'Starting in 20 minutes, run every 10 seconds and
|
||||||
seconds and then finish in 2 days', or 'execute 12 times during the next
|
then finish in 2 days', or 'execute 12 times during the next minute'.
|
||||||
minute'.
|
|
||||||
|
|
||||||
## Synopsis
|
## Synopsis
|
||||||
|
|
||||||
|
|
@ -31,8 +42,8 @@ end
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
And here's a simplistic AMQP message broadcaster, using existing
|
And here's a simplistic timed AMQP message broadcaster, using existing Symphony
|
||||||
Symphony connection information:
|
connection information:
|
||||||
|
|
||||||
```
|
```
|
||||||
#!ruby
|
#!ruby
|
||||||
|
|
@ -156,19 +167,58 @@ gem install symphony-metronome
|
||||||
|
|
||||||
## Contributing
|
## Contributing
|
||||||
|
|
||||||
You can check out the current development source with Mercurial
|
You can check out the source via Fossil from the following uri:
|
||||||
[here](http://code.martini.nu/symphony-metronome), or via a mirror:
|
|
||||||
|
|
||||||
* github: https://github.com/mahlonsmith/Symphony-Metronome
|
% fossil clone https://code.martini.nu/fossil/symphony-metronome
|
||||||
* SourceHut: https://hg.sr.ht/~mahlon/Symphony-Metronome
|
|
||||||
|
or via its GitHub mirror at:
|
||||||
|
|
||||||
|
% git clone https://github.com/mahlonsmith/Symphony-Metronome
|
||||||
|
|
||||||
After checking out the source, run:
|
After checking out the source, run:
|
||||||
|
|
||||||
```
|
$ gem install -Ng
|
||||||
$ rake
|
$ rake setup
|
||||||
```
|
|
||||||
|
|
||||||
This task will run the tests/specs and generate API documentation.
|
This will install dependencies, and do any other necessary setup for
|
||||||
|
development.
|
||||||
|
|
||||||
|
Please report any issues
|
||||||
|
[here](https://code.martini.nu/fossil/symphony-metronome/tktnew).
|
||||||
|
|
||||||
|
|
||||||
|
## Authors
|
||||||
|
|
||||||
|
- Mahlon E. Smith <mahlon@martini.nu>
|
||||||
|
|
||||||
|
|
||||||
|
## License
|
||||||
|
|
||||||
|
Copyright (c) 2014-2023 Mahlon E. Smith
|
||||||
|
All rights reserved.
|
||||||
|
|
||||||
|
Redistribution and use in source and binary forms, with or without
|
||||||
|
modification, are permitted provided that the following conditions are met:
|
||||||
|
|
||||||
|
* Redistributions of source code must retain the above copyright notice,
|
||||||
|
this list of conditions and the following disclaimer.
|
||||||
|
|
||||||
|
* Redistributions in binary form must reproduce the above copyright notice,
|
||||||
|
this list of conditions and the following disclaimer in the documentation
|
||||||
|
and/or other materials provided with the distribution.
|
||||||
|
|
||||||
|
* Neither the name of the author/s, nor the names of the project's
|
||||||
|
contributors may be used to endorse or promote products derived from this
|
||||||
|
software without specific prior written permission.
|
||||||
|
|
||||||
|
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||||
|
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
|
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||||
|
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
|
||||||
|
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||||
|
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||||
|
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||||
|
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||||
|
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
|
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
If you use [rvm](http://rvm.io/), entering the project directory will
|
|
||||||
install any required development dependencies.
|
|
||||||
|
|
|
||||||
152
Rakefile
152
Rakefile
|
|
@ -1,28 +1,35 @@
|
||||||
#!/usr/bin/env rake
|
# vim: set noet sta sw=4 ts=4 :
|
||||||
# vim: set nosta noet ts=4 sw=4:
|
# -*- ruby -*-
|
||||||
|
|
||||||
require 'rake/clean'
|
require 'rake/deveiate'
|
||||||
require 'pathname'
|
require 'pathname'
|
||||||
|
|
||||||
PROJECT = 'metronome'
|
Rake::DevEiate.setup( 'symphony-metronome' ) do |project|
|
||||||
BASEDIR = Pathname( __FILE__ ).dirname.relative_path_from( Pathname.pwd )
|
project.publish_to = 'martini.nu:martini/www/docs/symphony-metronome'
|
||||||
LIBDIR = BASEDIR + 'lib' + 'symphony'
|
project.summary = <<~END_SUM
|
||||||
|
A natural language scheduling and task runner for Symphony.
|
||||||
|
END_SUM
|
||||||
|
project.description = <<~END_DESC
|
||||||
|
Metronome is a scheduler and task runner. It can be used locally as a
|
||||||
|
cron replacement, or as a network-wide job executor. Events are stored
|
||||||
|
via simple database rows, and optionally managed via AMQP events.
|
||||||
|
Interval/time values are expressed with reasonably intuitive English
|
||||||
|
phrases, ie.: 'at 2pm', or 'Starting in 20 minutes, run every 10 seconds
|
||||||
|
and then finish in 2 days'.
|
||||||
|
END_DESC
|
||||||
|
project.authors = [ 'Mahlon E. Smith <mahlon@martini.nu>' ]
|
||||||
|
project.rdoc_generator = :sixfish
|
||||||
|
end
|
||||||
|
|
||||||
CLOBBER.include( 'coverage' )
|
CLOBBER.include( 'coverage' )
|
||||||
|
|
||||||
$LOAD_PATH.unshift( LIBDIR.to_s )
|
BASEDIR = Pathname( __FILE__ ).dirname.relative_path_from( Pathname.pwd )
|
||||||
|
LIBDIR = BASEDIR + 'lib' + 'symphony'
|
||||||
|
|
||||||
EXPRESSION_RL = LIBDIR + 'metronome' + 'intervalexpression.rl'
|
EXPRESSION_RL = LIBDIR + 'metronome' + 'intervalexpression.rl'
|
||||||
EXPRESSION_RB = LIBDIR + 'metronome' + 'intervalexpression.rb'
|
EXPRESSION_RB = LIBDIR + 'metronome' + 'intervalexpression.rb'
|
||||||
|
|
||||||
|
CLOBBER.include( EXPRESSION_RB.to_s )
|
||||||
if Rake.application.options.trace
|
|
||||||
$trace = true
|
|
||||||
$stderr.puts '$trace is enabled'
|
|
||||||
end
|
|
||||||
|
|
||||||
# get the current library version
|
|
||||||
$version = ( LIBDIR + "#{PROJECT}.rb" ).read.split(/\n/).
|
|
||||||
select{|line| line =~ /VERSION =/}.first.match(/([\d|.]+)/)[1]
|
|
||||||
|
|
||||||
task :default => [ :spec, :docs, :package ]
|
task :default => [ :spec, :docs, :package ]
|
||||||
|
|
||||||
|
|
@ -32,116 +39,7 @@ file EXPRESSION_RB
|
||||||
task EXPRESSION_RB => EXPRESSION_RL do |task|
|
task EXPRESSION_RB => EXPRESSION_RL do |task|
|
||||||
sh 'ragel', '-R', '-T1', '-Ls', task.prerequisites.first
|
sh 'ragel', '-R', '-T1', '-Ls', task.prerequisites.first
|
||||||
end
|
end
|
||||||
|
|
||||||
task :spec => EXPRESSION_RB
|
task :spec => EXPRESSION_RB
|
||||||
|
task :package => EXPRESSION_RB
|
||||||
|
|
||||||
########################################################################
|
|
||||||
### P A C K A G I N G
|
|
||||||
########################################################################
|
|
||||||
|
|
||||||
require 'rubygems'
|
|
||||||
require 'rubygems/package_task'
|
|
||||||
spec = Gem::Specification.new do |s|
|
|
||||||
s.email = 'mahlon@martini.nu'
|
|
||||||
s.homepage = 'http://projects.martini.nu/ruby-modules'
|
|
||||||
s.authors = [ 'Mahlon E. Smith <mahlon@martini.nu>' ]
|
|
||||||
s.platform = Gem::Platform::RUBY
|
|
||||||
s.summary = "A natural language scheduling and task runner."
|
|
||||||
s.name = 'symphony-' + PROJECT
|
|
||||||
s.version = $version
|
|
||||||
s.license = 'BSD'
|
|
||||||
s.has_rdoc = true
|
|
||||||
s.require_path = 'lib'
|
|
||||||
s.bindir = 'bin'
|
|
||||||
s.files = File.read( __FILE__ ).split( /^__END__/, 2 ).last.split
|
|
||||||
s.executables = %w[ metronome-exp ]
|
|
||||||
s.description = <<-EOF
|
|
||||||
Metronome is a scheduler and task runner. It can be used locally as a
|
|
||||||
cron replacement, or as a network-wide job executor. Events are stored
|
|
||||||
via simple database rows, and optionally managed via AMQP events.
|
|
||||||
Interval/time values are expressed with reasonably intuitive English
|
|
||||||
phrases, ie.: 'at 2pm', or 'Starting in 20 minutes, run every 10 seconds
|
|
||||||
and then finish in 2 days'.
|
|
||||||
EOF
|
|
||||||
s.required_rubygems_version = '>= 2.0.3'
|
|
||||||
s.required_ruby_version = '>= 2.0.0'
|
|
||||||
|
|
||||||
s.add_dependency 'symphony', '~> 0.11'
|
|
||||||
s.add_dependency 'sequel', '~> 5'
|
|
||||||
s.add_dependency 'sqlite3', '~> 1.3'
|
|
||||||
|
|
||||||
s.add_development_dependency 'rspec', '~> 3.3'
|
|
||||||
s.add_development_dependency 'simplecov', '~> 0.9'
|
|
||||||
s.add_development_dependency 'timecop', '~> 0.7'
|
|
||||||
end
|
|
||||||
|
|
||||||
Gem::PackageTask.new( spec ) do |pkg|
|
|
||||||
pkg.need_zip = true
|
|
||||||
pkg.need_tar = true
|
|
||||||
end
|
|
||||||
|
|
||||||
########################################################################
|
|
||||||
### D O C U M E N T A T I O N
|
|
||||||
########################################################################
|
|
||||||
|
|
||||||
begin
|
|
||||||
require 'rdoc/task'
|
|
||||||
|
|
||||||
desc 'Generate rdoc documentation'
|
|
||||||
RDoc::Task.new do |rdoc|
|
|
||||||
rdoc.name = :docs
|
|
||||||
rdoc.rdoc_dir = 'docs'
|
|
||||||
rdoc.main = "README.rdoc"
|
|
||||||
rdoc.rdoc_files = [ 'lib', *FileList['*.rdoc'] ]
|
|
||||||
end
|
|
||||||
|
|
||||||
RDoc::Task.new do |rdoc|
|
|
||||||
rdoc.name = :doc_coverage
|
|
||||||
rdoc.options = [ '-C1' ]
|
|
||||||
end
|
|
||||||
|
|
||||||
rescue LoadError
|
|
||||||
$stderr.puts "Omitting 'docs' tasks, rdoc doesn't seem to be installed."
|
|
||||||
end
|
|
||||||
|
|
||||||
|
|
||||||
########################################################################
|
|
||||||
### T E S T I N G
|
|
||||||
########################################################################
|
|
||||||
|
|
||||||
begin
|
|
||||||
require 'rspec/core/rake_task'
|
|
||||||
task :test => :spec
|
|
||||||
|
|
||||||
desc "Run specs"
|
|
||||||
RSpec::Core::RakeTask.new do |t|
|
|
||||||
t.pattern = "spec/**/*_spec.rb"
|
|
||||||
end
|
|
||||||
|
|
||||||
desc "Build a coverage report"
|
|
||||||
task :coverage do
|
|
||||||
ENV[ 'COVERAGE' ] = "yep"
|
|
||||||
Rake::Task[ :spec ].invoke
|
|
||||||
end
|
|
||||||
|
|
||||||
rescue LoadError
|
|
||||||
$stderr.puts "Omitting testing tasks, rspec doesn't seem to be installed."
|
|
||||||
end
|
|
||||||
|
|
||||||
|
|
||||||
########################################################################
|
|
||||||
### M A N I F E S T
|
|
||||||
########################################################################
|
|
||||||
__END__
|
|
||||||
bin/metronome-exp
|
|
||||||
data/symphony-metronome/migrations/20140419_initial.rb
|
|
||||||
data/symphony-metronome/migrations/20141028_lastrun.rb
|
|
||||||
lib/symphony/metronome/intervalexpression.rb
|
|
||||||
lib/symphony/metronome/intervalexpression.rl
|
|
||||||
lib/symphony/metronome/mixins.rb
|
|
||||||
lib/symphony/metronome/scheduledevent.rb
|
|
||||||
lib/symphony/metronome/scheduler.rb
|
|
||||||
lib/symphony/metronome.rb
|
|
||||||
lib/symphony/tasks/scheduletask.rb
|
|
||||||
README.rdoc
|
|
||||||
|
|
||||||
|
|
|
||||||
25
certs/mahlon.pem
Normal file
25
certs/mahlon.pem
Normal file
|
|
@ -0,0 +1,25 @@
|
||||||
|
-----BEGIN CERTIFICATE-----
|
||||||
|
MIIENDCCApygAwIBAgIBATANBgkqhkiG9w0BAQsFADAiMSAwHgYDVQQDDBdtYWhs
|
||||||
|
b24vREM9bWFydGluaS9EQz1udTAeFw0yMTAxMTcwMDQzMDZaFw0zMTAxMTUwMDQz
|
||||||
|
MDZaMCIxIDAeBgNVBAMMF21haGxvbi9EQz1tYXJ0aW5pL0RDPW51MIIBojANBgkq
|
||||||
|
hkiG9w0BAQEFAAOCAY8AMIIBigKCAYEAsRZyNGaL3I8T2AkQsHKyixW10CY6T715
|
||||||
|
uOztbmZImekhmgE9Uj5xZCnUP4xG5ToJffgkxcbepyJwIHCjEQg7viL9EsA+rMNb
|
||||||
|
UX8dsa9jpvVD6nHAdoW8G0ee7SRBXhCfyNma8FtkDJfw2bwdKhxUKiHsULCSQ0Pd
|
||||||
|
p+4d5NnldgfB8cf4Hz9Ai/8FHacWnZVEiHa4Ngb5Fe42OUs+4XDQdpcgA7wCY633
|
||||||
|
q9rRVGK7MW9BzMv+hhQfElQMn1eDMgQVpO543viDT8JatwhhcYmKdzwTIIPAIybf
|
||||||
|
8MfJaimsh20OAqs3FAXNKjDVFbcXFfKUXXgVgMjUoEK5+Lp+pKPZXU4bIi5oYZqB
|
||||||
|
OttGPMD5rOWlAooWNQ7xbdHByUVqJmALSWHqPHdvVmAVsW8tNoB1qGbM+C6o80Ie
|
||||||
|
9H0389ja3TW4JK/0w/gFUmrVvYKRll44HaxS9nXNpiYBipbJmlR/R9qoe54ImQje
|
||||||
|
Z4vsWrWiDrK/oVYlUXOy7SE/jUAQF9UzAgMBAAGjdTBzMAkGA1UdEwQCMAAwCwYD
|
||||||
|
VR0PBAQDAgSwMB0GA1UdDgQWBBSx8TRqCmTPOARICKiZ3c66sIG3pTAcBgNVHREE
|
||||||
|
FTATgRFtYWhsb25AbWFydGluaS5udTAcBgNVHRIEFTATgRFtYWhsb25AbWFydGlu
|
||||||
|
aS5udTANBgkqhkiG9w0BAQsFAAOCAYEAHbiAZTe46/kp1Tkm4s6D30VBaYaAdaYG
|
||||||
|
bZIaAaHtJO9MbUNS0FA01fxQpptjpOQT3cNNf8CX8UHPTaSuPFMfgVWj1xiX7Byb
|
||||||
|
hqhUcUTENOuUxxWGDCa4orCFctc3yihojTKGtbhODHVSHf9DRDyalRcvmyWzxMFT
|
||||||
|
XtBS05OUXc9O1bKqzNaRc9nMGw6Y+V79hIex4mZlMBkhTeVKxeeweCXfELXOQRmB
|
||||||
|
FgPgUyQn0AaSpplx0YoWdy/99fEkXSMvgeEoiR1ApR6aUuTlvIr1yUgzVBpWU4mE
|
||||||
|
XC+Ig+3jhqufGyE/Do+1M7n5QLpgGfpy3QmoOiKeYt3XzR5Z7XoxCAaKHNRxVEga
|
||||||
|
ojmVnDNlLQkkZZkbFNGPHjCIBs7h+6eoIYvy/eQ82c4vd6w9rR4v9bKUL8NNkcSz
|
||||||
|
49pOzX5KHZLTS9DKeaP/xcGPz6C8MiwQdYrZarr2SHRASX1zFa79rkItO8kE6RDr
|
||||||
|
b6WDF79UvZ55ajtE00TiwqjQL/ZPEtbd
|
||||||
|
-----END CERTIFICATE-----
|
||||||
17
gem.deps.rb
Normal file
17
gem.deps.rb
Normal file
|
|
@ -0,0 +1,17 @@
|
||||||
|
source 'https://rubygems.org/'
|
||||||
|
|
||||||
|
gem 'sequel', '~> 5.66'
|
||||||
|
gem 'sorted_set', '~> 1.0'
|
||||||
|
gem 'sqlite3', '~> 1.6'
|
||||||
|
gem 'symphony', '~> 0.14'
|
||||||
|
gem 'yajl-ruby', '~> 1.4'
|
||||||
|
|
||||||
|
group :development do
|
||||||
|
gem 'rake-deveiate', '~> 0.22'
|
||||||
|
gem 'rspec', '~> 3.12'
|
||||||
|
gem 'rdoc-generator-sixfish', '~> 0.3'
|
||||||
|
gem 'simplecov', '~> 0.22'
|
||||||
|
gem 'timecop', '~> 0.9'
|
||||||
|
gem 'pry', '~> 0.14'
|
||||||
|
end
|
||||||
|
|
||||||
|
|
@ -9,10 +9,7 @@ module Symphony::Metronome
|
||||||
Configurability
|
Configurability
|
||||||
|
|
||||||
# Library version constant
|
# Library version constant
|
||||||
VERSION = '0.2.3'
|
VERSION = '0.3.0'
|
||||||
|
|
||||||
# Version-control revision constant
|
|
||||||
REVISION = %q$Revision: e3d11b2c9e48 $
|
|
||||||
|
|
||||||
# The name of the environment variable to check for config file overrides
|
# The name of the environment variable to check for config file overrides
|
||||||
CONFIG_ENV = 'METRONOME_CONFIG'
|
CONFIG_ENV = 'METRONOME_CONFIG'
|
||||||
|
|
|
||||||
|
|
@ -239,7 +239,7 @@ class Symphony::Metronome::IntervalExpression
|
||||||
### an expression was generated, you can 'reconstitute' an interval
|
### an expression was generated, you can 'reconstitute' an interval
|
||||||
### object this way.
|
### object this way.
|
||||||
###
|
###
|
||||||
def self::parse( exp, time=nil )
|
def self::parse( exp, time=Time.now )
|
||||||
|
|
||||||
# Normalize the expression before parsing
|
# Normalize the expression before parsing
|
||||||
#
|
#
|
||||||
|
|
@ -250,7 +250,7 @@ class Symphony::Metronome::IntervalExpression
|
||||||
gsub( /([:\-])+/, '\1' ). # collapse multiple - or : chars
|
gsub( /([:\-])+/, '\1' ). # collapse multiple - or : chars
|
||||||
gsub( /\.+$/, '' ) # trailing periods
|
gsub( /\.+$/, '' ) # trailing periods
|
||||||
|
|
||||||
event = new( exp, time || Time.now )
|
event = new( exp, time )
|
||||||
data = event.instance_variable_get( :@data )
|
data = event.instance_variable_get( :@data )
|
||||||
|
|
||||||
# Ragel interface variables
|
# Ragel interface variables
|
||||||
|
|
|
||||||
|
|
@ -21,19 +21,17 @@ class Symphony::Metronome::ScheduledEvent
|
||||||
config_key :metronome
|
config_key :metronome
|
||||||
|
|
||||||
|
|
||||||
# Configure defaults.
|
### Configurability API.
|
||||||
#
|
###
|
||||||
CONFIG_DEFAULTS = {
|
configurability do
|
||||||
:db => 'sqlite:///tmp/metronome.db',
|
|
||||||
:splay => 0
|
|
||||||
}
|
|
||||||
|
|
||||||
class << self
|
##
|
||||||
# A Sequel-style DB connection URI.
|
# A Sequel-style DB connection URI.
|
||||||
attr_reader :db
|
setting :db, default: 'sqlite:///tmp/metronome.db'
|
||||||
|
|
||||||
|
##
|
||||||
# Adjust recurring intervals by a random window.
|
# Adjust recurring intervals by a random window.
|
||||||
attr_reader :splay
|
setting :splay, default: 0
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -62,7 +60,6 @@ class Symphony::Metronome::ScheduledEvent
|
||||||
### Delete any rows that are invalid expressions.
|
### Delete any rows that are invalid expressions.
|
||||||
###
|
###
|
||||||
def self::load
|
def self::load
|
||||||
now = Time.now
|
|
||||||
events = SortedSet.new
|
events = SortedSet.new
|
||||||
|
|
||||||
# Force reset the DB handle.
|
# Force reset the DB handle.
|
||||||
|
|
|
||||||
|
|
@ -17,22 +17,15 @@ class Symphony::Metronome::Scheduler
|
||||||
# Signals the daemon responds to.
|
# Signals the daemon responds to.
|
||||||
SIGNALS = [ :HUP, :INT, :TERM ]
|
SIGNALS = [ :HUP, :INT, :TERM ]
|
||||||
|
|
||||||
CONFIG_DEFAULTS = {
|
|
||||||
:listen => false
|
|
||||||
}
|
|
||||||
|
|
||||||
class << self
|
### Configurability API.
|
||||||
|
###
|
||||||
|
configurability do
|
||||||
|
|
||||||
# Should Metronome register and schedule events via AMQP?
|
# Should Metronome register and schedule events via AMQP?
|
||||||
# If +false+, you'll need a separate way to add event actions
|
# If +false+, you'll need a separate way to add event actions
|
||||||
# to the database, and manually HUP the daemon.
|
# to the database, and manually HUP the daemon.
|
||||||
attr_reader :listen
|
setting :listen, default: false
|
||||||
end
|
|
||||||
|
|
||||||
### Configurability API
|
|
||||||
###
|
|
||||||
def self::configure( config=nil )
|
|
||||||
config = self.defaults.merge( config || {} )
|
|
||||||
@listen = config.delete( :listen )
|
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -33,11 +33,13 @@ describe Symphony::Metronome::ScheduledEvent do
|
||||||
Timecop.travel( time )
|
Timecop.travel( time )
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
it 'applies migrations upon initial config' do
|
it 'applies migrations upon initial config' do
|
||||||
migrations = described_class.db[ :schema_migrations ].all
|
migrations = described_class.db[ :schema_migrations ].all
|
||||||
expect( migrations.first[:filename] ).to eq( '20140419_initial.rb' )
|
expect( migrations.first[:filename] ).to eq( '20140419_initial.rb' )
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
it 'can load all stored events sorted by next execution time' do
|
it 'can load all stored events sorted by next execution time' do
|
||||||
ds.insert(
|
ds.insert(
|
||||||
:created => Time.now,
|
:created => Time.now,
|
||||||
|
|
@ -61,6 +63,7 @@ describe Symphony::Metronome::ScheduledEvent do
|
||||||
expect( events.last.event.instance_variable_get(:@exp) ).to eq( 'at 3pm' )
|
expect( events.last.event.instance_variable_get(:@exp) ).to eq( 'at 3pm' )
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
it 'removes invalid expressions from storage when loading' do
|
it 'removes invalid expressions from storage when loading' do
|
||||||
ds.insert(
|
ds.insert(
|
||||||
:created => Time.now,
|
:created => Time.now,
|
||||||
|
|
@ -77,6 +80,7 @@ describe Symphony::Metronome::ScheduledEvent do
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
context 'an instance' do
|
context 'an instance' do
|
||||||
|
|
||||||
let( :time ) { Time.at(1262376000) }
|
let( :time ) { Time.at(1262376000) }
|
||||||
|
|
@ -94,6 +98,7 @@ describe Symphony::Metronome::ScheduledEvent do
|
||||||
expect( ev.runtime ).to eq( time )
|
expect( ev.runtime ).to eq( time )
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
it 'can reschedule itself into the future when recurring (past start)' do
|
it 'can reschedule itself into the future when recurring (past start)' do
|
||||||
ev = described_class.new(
|
ev = described_class.new(
|
||||||
:created => time,
|
:created => time,
|
||||||
|
|
@ -107,6 +112,7 @@ describe Symphony::Metronome::ScheduledEvent do
|
||||||
expect( ev.runtime ).to be >= time + 3600 + 30
|
expect( ev.runtime ).to be >= time + 3600 + 30
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
it 'can reschedule itself into the future when recurring (recently run)' do
|
it 'can reschedule itself into the future when recurring (recently run)' do
|
||||||
ds.insert(
|
ds.insert(
|
||||||
:created => time,
|
:created => time,
|
||||||
|
|
@ -120,9 +126,10 @@ describe Symphony::Metronome::ScheduledEvent do
|
||||||
ev.reset_runtime
|
ev.reset_runtime
|
||||||
end
|
end
|
||||||
|
|
||||||
expect( ev.runtime ).to be >= time + 18
|
expect( ev.runtime ).to be >= time + 17
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
it 'removes itself when firing if expired' do
|
it 'removes itself when firing if expired' do
|
||||||
ds.insert(
|
ds.insert(
|
||||||
:created => time,
|
:created => time,
|
||||||
|
|
@ -135,6 +142,7 @@ describe Symphony::Metronome::ScheduledEvent do
|
||||||
expect( ds.count ).to eq( 0 )
|
expect( ds.count ).to eq( 0 )
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
it 'yields a deserialized options hash if okay to fire' do
|
it 'yields a deserialized options hash if okay to fire' do
|
||||||
ev = described_class.new(
|
ev = described_class.new(
|
||||||
:created => time,
|
:created => time,
|
||||||
|
|
@ -150,6 +158,7 @@ describe Symphony::Metronome::ScheduledEvent do
|
||||||
expect( res ).to be( 12 )
|
expect( res ).to be( 12 )
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
it "won't re-fire recurring events if they already fired within their interval window" do
|
it "won't re-fire recurring events if they already fired within their interval window" do
|
||||||
ds.insert(
|
ds.insert(
|
||||||
:created => time,
|
:created => time,
|
||||||
|
|
@ -170,6 +179,7 @@ describe Symphony::Metronome::ScheduledEvent do
|
||||||
expect( res ).to be( 0 )
|
expect( res ).to be( 0 )
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
it 'randomizes start times if a splay is configured' do
|
it 'randomizes start times if a splay is configured' do
|
||||||
described_class.instance_variable_set( :@splay, 5 )
|
described_class.instance_variable_set( :@splay, 5 )
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue