zhong 0.2.0 → 0.3.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
- SHA1:
3
- metadata.gz: 902b025d6f1afe4edfa0f2cb6f6639bc0ff558ff
4
- data.tar.gz: 939fedf9667d0dc26f7fb1adcddedd5cbe76deba
2
+ SHA256:
3
+ metadata.gz: 577d8f17b30c591def82d4f69b184e233ba9a3b66d690616880c6e311dd85e4c
4
+ data.tar.gz: a838490cfa7cf4b3dbd451009cd0278d9a7ab391934e6e39a8d897af4a81926a
5
5
  SHA512:
6
- metadata.gz: 16ce76fbea779cffa736f3c48f99bca3fa0ac0ba27e46261f20c41c037143317cb406715e8e866da4495dcf33a20a11830a37b6bd1b41ac9d64c39568c7e1896
7
- data.tar.gz: 85abd697abfe5fa1ffd7513ae8e146f34c3360234f2685f9f89aec5224b259d086e25097614836ba90ebe8bc2347b8ea324051d87ea5e6813acc845267de96bf
6
+ metadata.gz: 30259b64b127a57c3ae44cfe5ad5a8339c7009512eeb26d08e69b417bf0c6d682de87d73f20ac23efc9fd2e2863aa9a62f2ca6c6b07eee89e77228c017f49007
7
+ data.tar.gz: 36e88630340b371f38c511d9b716456b7a2112c5c4555c197ec18d3c176cad22f52be34c43262c06cf670d2bddafcbfe9c2c60124780075987228c548df11d3e
@@ -0,0 +1,34 @@
1
+ name: CI
2
+
3
+ on:
4
+ push:
5
+ branches:
6
+ - master
7
+ pull_request:
8
+
9
+ jobs:
10
+ build:
11
+ runs-on: ubuntu-latest
12
+ strategy:
13
+ fail-fast: false
14
+ matrix:
15
+ ruby:
16
+ - '2.5'
17
+ - '2.6'
18
+ - '2.7'
19
+ - '3.0'
20
+ - ruby-head
21
+ continue-on-error: ${{ matrix.ruby == 'ruby-head' }}
22
+ services:
23
+ redis:
24
+ image: redis
25
+ ports:
26
+ - 6379:6379
27
+ steps:
28
+ - uses: actions/checkout@v2
29
+ - uses: ruby/setup-ruby@v1
30
+ with:
31
+ ruby-version: ${{ matrix.ruby }}
32
+ bundler-cache: true
33
+ - run: |
34
+ bundle exec rake
@@ -1,3 +1,24 @@
1
+ ## 0.3.0
2
+
3
+ - Update version requirements, and switch to Github actions (thank you @mlarraz!)
4
+
5
+ ## 0.2.4
6
+
7
+ - Compatibility with Sinatra/Tilt (thank you Brian Storti!)
8
+
9
+ ## 0.2.3
10
+
11
+ - Much improved documentation, and executable file naming (thank you Antoine Augusti!)
12
+ - Fixes to the time parsing & to_s (thank you Antoine Augusti!)
13
+
14
+ ## 0.2.2
15
+
16
+ - Re-licensed as LGPL, as I lifted Sidekiq-web code to power Zhong web (thanks Mike Perham for the great gem and the code!)
17
+
18
+ ## 0.2.1
19
+
20
+ - Fix manually specifying a Redis connection (thanks, Richard Adams!)
21
+
1
22
  ## 0.2.0
2
23
 
3
24
  - Configuring Redis and the heartbeat key now correctly updates even after Zhong is configured initially.
@@ -1,22 +1,5 @@
1
- Copyright (c) 2015 Nick Elser
1
+ Copyright (c) Nick Elser
2
2
 
3
- MIT License
4
-
5
- Permission is hereby granted, free of charge, to any person obtaining
6
- a copy of this software and associated documentation files (the
7
- "Software"), to deal in the Software without restriction, including
8
- without limitation the rights to use, copy, modify, merge, publish,
9
- distribute, sublicense, and/or sell copies of the Software, and to
10
- permit persons to whom the Software is furnished to do so, subject to
11
- the following conditions:
12
-
13
- The above copyright notice and this permission notice shall be
14
- included in all copies or substantial portions of the Software.
15
-
16
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
- EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
- MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
- NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
- LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
- OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
- WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
3
+ Zhong is an Open Source project licensed under the terms of
4
+ the LGPLv3 license. Please see <http://www.gnu.org/licenses/lgpl-3.0.html>
5
+ for license text.
data/README.md CHANGED
@@ -1,9 +1,10 @@
1
- # Zhong [![Build Status](https://travis-ci.org/nickelser/zhong.svg?branch=master)](https://travis-ci.org/nickelser/zhong) [![Code Climate](https://codeclimate.com/github/nickelser/zhong/badges/gpa.svg)](https://codeclimate.com/github/nickelser/zhong) [![Test Coverage](https://codeclimate.com/github/nickelser/zhong/badges/coverage.svg)](https://codeclimate.com/github/nickelser/zhong) [![Gem Version](https://badge.fury.io/rb/zhong.svg)](http://badge.fury.io/rb/zhong)
1
+ # Zhong [![Build Status](https://github.com/nickelser/zhong/workflows/CI/badge.svg)](https://github.com/nickelser/zhong/actions?query=workflow%3ACI) [![Code Climate](https://codeclimate.com/github/nickelser/zhong/badges/gpa.svg)](https://codeclimate.com/github/nickelser/zhong) [![Gem Version](https://badge.fury.io/rb/zhong.svg)](http://badge.fury.io/rb/zhong)
2
2
 
3
3
  Useful, reliable distributed cron. Tired of your cron-like scheduler running key jobs twice? Would you like to be able to run your cron server on multiple machines and have it "just work"? Have we got the gem for you.
4
4
 
5
5
  Zhong uses Redis to acquire exclusive locks on jobs, as well as recording when they last ran. This means that you can rest easy at night, knowing that your customers are getting their monthly Goat Fancy magazine subscriptions and you are rolling around in your piles of money without a care in the world.
6
6
 
7
+ :tangerine: Battle-tested at [Instacart](https://www.instacart.com/opensource)
7
8
  # Installation
8
9
 
9
10
  Add this line to your application’s Gemfile:
@@ -14,6 +15,9 @@ gem 'zhong'
14
15
 
15
16
  ## Usage
16
17
 
18
+ ### Zhong schedule
19
+ Create a definition file, let's call it `zhong.rb`:
20
+
17
21
  ```ruby
18
22
  Zhong.redis = Redis.new(url: ENV["ZHONG_REDIS_URL"])
19
23
 
@@ -23,9 +27,9 @@ Zhong.schedule do
23
27
  puts "foo"
24
28
  end
25
29
 
26
- every(1.minute, "biz", at: ["**:26", "**:27"]) { puts "biz" }
27
- every(1.week, "baz", at: ["mon 22:45", "wed 23:13"]) { puts "baz" }
28
- every(10.seconds, "boom") { raise "fail" }
30
+ every(1.minute, "running biz at 26th and 27th minute", at: ["**:26", "**:27"]) { puts "biz" }
31
+ every(1.week, "running baz on mon and wed", at: ["mon 22:45", "wed 23:13"]) { puts "baz" }
32
+ every(10.seconds, "boom every 10 seconds") { raise "fail" }
29
33
  end
30
34
 
31
35
  category "clutter" do
@@ -75,18 +79,55 @@ Zhong.schedule do
75
79
  end
76
80
  ```
77
81
 
82
+ This file only describes what should be the schedule. Nothing will be executed
83
+ until we actually run
84
+ ```ruby
85
+ Zhong.start
86
+ ```
87
+ after describing the Zhong schedule.
88
+
89
+ ### Zhong cron process
90
+
91
+ You can run the cron process that will execute your code from the definitions
92
+ in the `zhong.rb` file by running:
93
+ ```sh
94
+ zhong zhong.rb
95
+ ```
96
+
78
97
  ## Web UI
79
98
 
80
99
  Zhong comes with a web application that can display jobs, their last run and
81
100
  enable/disable them.
82
101
 
83
- ### Rails
102
+ This is a Sinatra application that requires at least `v2.0.0`. You can add to your Gemfile
103
+ ```ruby
104
+ gem 'sinatra', "~>2.0"
105
+ ```
106
+
107
+ It can be protected by HTTP basic authentication by
108
+ setting the following environment variables:
109
+ - `ZHONG_WEB_USERNAME`: the username
110
+ - `ZHONG_WEB_PASSWORD`: the password
84
111
 
85
- Add the following to your config/routes.rb:
112
+ You'll need to load the Zhong schedule to be able to see jobs in the web UI, typically
113
+ by requiring your `zhong.rb` definition file.
86
114
 
115
+ ### Rails
116
+ Load the Zhong schedule by creating an initializer at `config/initializers/zhong.rb`,
117
+ with the following content:
118
+ ```ruby
119
+ require "#{Rails.root}/zhong.rb"
120
+ ```
121
+
122
+ Add the following to your `config/routes.rb`:
87
123
  ```ruby
88
124
  require 'zhong/web'
89
- mount Zhong::Web, at: "zhong"
125
+
126
+ Rails.application.routes.draw do
127
+ # Other routes here...
128
+
129
+ mount Zhong::Web, at: "/zhong"
130
+ end
90
131
  ```
91
132
 
92
133
  ## History
@@ -20,7 +20,7 @@ module Zhong
20
20
 
21
21
  def to_s
22
22
  EVERY_KEYWORDS.to_a.reverse.each do |friendly, period|
23
- next unless @period % period == 0
23
+ next unless @period.to_i % period.to_i == 0
24
24
 
25
25
  rem = @period / period
26
26
 
@@ -23,6 +23,7 @@ module Zhong
23
23
  @long_running_timeout = config[:long_running_timeout]
24
24
  @running = false
25
25
  @first_run = true
26
+ @last_ran = nil
26
27
  @id = Digest::SHA256.hexdigest(@name)
27
28
  end
28
29
 
@@ -183,7 +184,7 @@ module Zhong
183
184
  end
184
185
 
185
186
  def redis_lock
186
- @lock ||= Suo::Client::Redis.new(lock_key, client: @redis, stale_lock_expiration: @long_running_timeout)
187
+ @lock ||= Suo::Client::Redis.new(lock_key, client: redis, stale_lock_expiration: @long_running_timeout)
187
188
  end
188
189
  end
189
190
  end
@@ -1,3 +1,3 @@
1
1
  module Zhong
2
- VERSION = "0.2.0".freeze
2
+ VERSION = "0.3.0".freeze
3
3
  end
@@ -6,6 +6,8 @@ require "zhong"
6
6
  require "zhong/web_helpers"
7
7
 
8
8
  module Zhong
9
+ # Most of the following helpers are copied from a previous version of the Sidekiq project
10
+ # available here: https://github.com/mperham/sidekiq/blob/2c9f7662fcdcb52d59b72ba0fe7dc5f963de4904/lib/sidekiq/web.rb
9
11
  class Web < Sinatra::Base
10
12
  enable :sessions
11
13
  use ::Rack::Protection, use: :authenticity_token unless ENV["RACK_ENV"] == "test"
@@ -2,6 +2,8 @@
2
2
  require "uri"
3
3
 
4
4
  module Zhong
5
+ # Most of the following helpers are copied from a previous version of the Sidekiq project
6
+ # available here: https://github.com/mperham/sidekiq/blob/2c9f7662fcdcb52d59b72ba0fe7dc5f963de4904/lib/sidekiq/web_helpers.rb
5
7
  module WebHelpers
6
8
  # Simple capture method for erb templates. The origin was
7
9
  # capture method from sinatra-contrib library.
@@ -77,6 +77,18 @@ class TestEvery < Minitest::Test
77
77
  assert_equal time_in_day(0, 0, 7, 10), every.next_at(time_in_day(0, 0, 0, 10))
78
78
  end
79
79
 
80
+ def test_to_s
81
+ assert_equal "3 minutes", Zhong::Every.parse(3.minute).to_s
82
+ assert_equal "3 hours", Zhong::Every.parse(3.hour).to_s
83
+ assert_equal "1 hour", Zhong::Every.parse(1.hour).to_s
84
+ assert_equal "3 days", Zhong::Every.parse(3.day).to_s
85
+ assert_equal "3 weeks", Zhong::Every.parse(3.week).to_s
86
+ assert_equal "3 months", Zhong::Every.parse(3.month).to_s
87
+ assert_equal "1 month", Zhong::Every.parse(1.month).to_s
88
+ assert_equal "3 years", Zhong::Every.parse(3.year).to_s
89
+ assert_equal "3 decades", Zhong::Every.parse(30.years).to_s
90
+ end
91
+
80
92
  def test_invalid_string_foo
81
93
  assert_raises Zhong::Every::FailedToParse do
82
94
  Zhong::Every.parse("foo")
@@ -1,4 +1,5 @@
1
1
  <!DOCTYPE html>
2
+ <!-- This view based on ankane/clockwork_web's interface https://github.com/ankane/clockwork_web/blob/master/app/views/clockwork_web/home/index.html.erb -->
2
3
  <html>
3
4
  <head>
4
5
  <title><%= environment_title_prefix %>Zhong</title>
@@ -69,7 +70,7 @@
69
70
  <tbody>
70
71
  <% @jobs.each do |job| %>
71
72
  <% enabled = !@disabled[job.to_s] %>
72
- <% enabled_str = enabled ? 'disable' : 'enable' -%>
73
+ <% enabled_str = enabled ? 'disable' : 'enable' %>
73
74
  <% last_run = @last_runs[job.to_s] %>
74
75
  <tr class="<%= enabled ? "" : "disabled" %>">
75
76
  <td><%= h(job) %></td>
@@ -87,7 +88,7 @@
87
88
  <form method="POST" style="margin-top: 20px; margin-bottom: 10px;">
88
89
  <%= csrf_tag %>
89
90
  <div>
90
- <button type="submit" name="<%= enabled_str -%>" value="<%= job.id -%>" data-confirm="Are you sure you want to <%= enabled_str -%> this job?"><%= enabled_str.capitalize -%></button>
91
+ <button type="submit" name="<%= enabled_str %>" value="<%= job.id %>" data-confirm="Are you sure you want to <%= enabled_str %> this job?"><%= enabled_str.capitalize %></button>
91
92
  </div>
92
93
  </form>
93
94
  </td>
@@ -99,15 +100,15 @@
99
100
  <div>
100
101
  <h3>Hosts</h3>
101
102
  <ul>
102
- <% @hosts.each do |host| -%>
103
+ <% @hosts.each do |host| %>
103
104
  <li>
104
- <strong><%= h(host[:host]) -%></strong> <em>(PID <%= host[:pid] -%>)</em>: last seen <%= relative_time(host[:last_seen]) -%>.
105
+ <strong><%= h(host[:host]) %></strong> <em>(PID <%= host[:pid] %>)</em>: last seen <%= relative_time(host[:last_seen]) %>.
105
106
  </li>
106
- <% end -%>
107
+ <% end %>
107
108
  </ul>
108
109
  </div>
109
110
  <div>
110
- <small><%= product_version -%></small>
111
+ <small><%= product_version %></small>
111
112
  </div>
112
113
  </body>
113
114
  </html>
@@ -16,20 +16,20 @@ Gem::Specification.new do |spec|
16
16
 
17
17
  spec.files = `git ls-files -z`.split("\x0")
18
18
  spec.bindir = "bin"
19
- spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
19
+ spec.executables = ["zhong"]
20
20
  spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
21
21
  spec.require_paths = ["lib"]
22
22
 
23
- spec.required_ruby_version = "~> 2.1"
23
+ spec.required_ruby_version = ">= 2.5.0"
24
24
 
25
25
  spec.add_dependency "suo"
26
26
  spec.add_dependency "redis"
27
27
  spec.add_dependency "tzinfo"
28
28
  spec.add_dependency "activesupport"
29
29
 
30
- spec.add_development_dependency "bundler", "~> 1.5"
31
- spec.add_development_dependency "rake", "~> 10.0"
32
- spec.add_development_dependency "rubocop", "~> 0.30.0"
30
+ spec.add_development_dependency "bundler", "~> 2.2"
31
+ spec.add_development_dependency "rake", "~> 13.0"
32
+ spec.add_development_dependency "rubocop", "~> 0.49.0"
33
33
  spec.add_development_dependency "minitest", "~> 5.5.0"
34
34
  spec.add_development_dependency "codeclimate-test-reporter", "~> 0.4.7"
35
35
  spec.add_development_dependency "sinatra", "~> 1.4", ">= 1.4.6"
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: zhong
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.0
4
+ version: 0.3.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Nick Elser
8
- autorequire:
8
+ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2016-10-19 00:00:00.000000000 Z
11
+ date: 2021-01-21 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: suo
@@ -72,42 +72,42 @@ dependencies:
72
72
  requirements:
73
73
  - - "~>"
74
74
  - !ruby/object:Gem::Version
75
- version: '1.5'
75
+ version: '2.2'
76
76
  type: :development
77
77
  prerelease: false
78
78
  version_requirements: !ruby/object:Gem::Requirement
79
79
  requirements:
80
80
  - - "~>"
81
81
  - !ruby/object:Gem::Version
82
- version: '1.5'
82
+ version: '2.2'
83
83
  - !ruby/object:Gem::Dependency
84
84
  name: rake
85
85
  requirement: !ruby/object:Gem::Requirement
86
86
  requirements:
87
87
  - - "~>"
88
88
  - !ruby/object:Gem::Version
89
- version: '10.0'
89
+ version: '13.0'
90
90
  type: :development
91
91
  prerelease: false
92
92
  version_requirements: !ruby/object:Gem::Requirement
93
93
  requirements:
94
94
  - - "~>"
95
95
  - !ruby/object:Gem::Version
96
- version: '10.0'
96
+ version: '13.0'
97
97
  - !ruby/object:Gem::Dependency
98
98
  name: rubocop
99
99
  requirement: !ruby/object:Gem::Requirement
100
100
  requirements:
101
101
  - - "~>"
102
102
  - !ruby/object:Gem::Version
103
- version: 0.30.0
103
+ version: 0.49.0
104
104
  type: :development
105
105
  prerelease: false
106
106
  version_requirements: !ruby/object:Gem::Requirement
107
107
  requirements:
108
108
  - - "~>"
109
109
  - !ruby/object:Gem::Version
110
- version: 0.30.0
110
+ version: 0.49.0
111
111
  - !ruby/object:Gem::Dependency
112
112
  name: minitest
113
113
  requirement: !ruby/object:Gem::Requirement
@@ -216,8 +216,6 @@ description: Reliable, distributed cron.
216
216
  email:
217
217
  - nick.elser@gmail.com
218
218
  executables:
219
- - console
220
- - setup
221
219
  - zhong
222
220
  extensions: []
223
221
  extra_rdoc_files: []
@@ -225,9 +223,9 @@ files:
225
223
  - ".codeclimate.yml"
226
224
  - ".eslintignore"
227
225
  - ".eslintrc"
226
+ - ".github/workflows/CI.yml"
228
227
  - ".gitignore"
229
228
  - ".rubocop.yml"
230
- - ".travis.yml"
231
229
  - CHANGELOG.md
232
230
  - Gemfile
233
231
  - LICENSE.txt
@@ -260,24 +258,23 @@ homepage: https://www.github.com/nickelser/zhong
260
258
  licenses:
261
259
  - MIT
262
260
  metadata: {}
263
- post_install_message:
261
+ post_install_message:
264
262
  rdoc_options: []
265
263
  require_paths:
266
264
  - lib
267
265
  required_ruby_version: !ruby/object:Gem::Requirement
268
266
  requirements:
269
- - - "~>"
267
+ - - ">="
270
268
  - !ruby/object:Gem::Version
271
- version: '2.1'
269
+ version: 2.5.0
272
270
  required_rubygems_version: !ruby/object:Gem::Requirement
273
271
  requirements:
274
272
  - - ">="
275
273
  - !ruby/object:Gem::Version
276
274
  version: '0'
277
275
  requirements: []
278
- rubyforge_project:
279
- rubygems_version: 2.5.1
280
- signing_key:
276
+ rubygems_version: 3.1.2
277
+ signing_key:
281
278
  specification_version: 4
282
279
  summary: Reliable, distributed cron.
283
280
  test_files:
@@ -1,5 +0,0 @@
1
- language: ruby
2
- rvm:
3
- - 2.3.0
4
- services:
5
- - redis-server