schked 0.4.0 → 1.1.0
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/README.md +11 -1
- data/lib/schked/cli.rb +1 -3
- data/lib/schked/config.rb +13 -1
- data/lib/schked/redis_locker.rb +45 -0
- data/lib/schked/version.rb +1 -1
- data/lib/schked/worker.rb +30 -2
- data/lib/schked.rb +3 -0
- metadata +17 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 660370465a4ff279d9bc26184108c07637d0fcd69f071e22e8dea9b5b79b29ae
|
4
|
+
data.tar.gz: 9e54efb1455b8e48af9d67011008cb821aefe6bb691ec0325f1f0a9c8425ed10
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: f0ee5ac189460a35c87da4c6a889482f824985abd5561f5541e01157b6574e7d28957b9082cab272fc2cce04e779850ced784858e91da02554b3816a37483fee
|
7
|
+
data.tar.gz: 68754d88a2fcc870c6e161d951b2ff2a00749d0c345401e9608c69cfde4055554f1275157b1e7af7c3a2f07efff037eb690619834daa3d289293ef33c27be6ac
|
data/README.md
CHANGED
@@ -41,7 +41,7 @@ gem install schked
|
|
41
41
|
config/schedule.rb
|
42
42
|
|
43
43
|
```ruby
|
44
|
-
cron "*/30 * * * *", as: "CleanOrphanAttachmentsJob" do
|
44
|
+
cron "*/30 * * * *", as: "CleanOrphanAttachmentsJob", timeout: "60s", overlap: false do
|
45
45
|
CleanOrphanAttachmentsJob.perform_later
|
46
46
|
end
|
47
47
|
```
|
@@ -72,6 +72,16 @@ To show schedule:
|
|
72
72
|
bundle exec schked show
|
73
73
|
```
|
74
74
|
|
75
|
+
### Duplicate scheduling
|
76
|
+
|
77
|
+
When you deploy your schedule to production, you want to start new instance before you shut down the current. And you don't want simultaneous working of both. To achieve a seamless transition, Schked is using Redis for locks.
|
78
|
+
|
79
|
+
You can configure Redis client as the following:
|
80
|
+
|
81
|
+
```ruby
|
82
|
+
Schked.config.redis_servers = ["redis://127.0.0.1:7777", "redis://127.0.0.1:7778", "redis://127.0.0.1:7779"]
|
83
|
+
```
|
84
|
+
|
75
85
|
### Callbacks
|
76
86
|
|
77
87
|
Also, you can define callbacks for errors handling:
|
data/lib/schked/cli.rb
CHANGED
@@ -45,9 +45,7 @@ module Schked
|
|
45
45
|
private
|
46
46
|
|
47
47
|
def load_requires
|
48
|
-
if options[:require]&.any?
|
49
|
-
options[:require].each { |file| load(File.join(Dir.pwd, file)) }
|
50
|
-
end
|
48
|
+
options[:require].each { |file| load(File.join(Dir.pwd, file)) } if options[:require]&.any?
|
51
49
|
|
52
50
|
# We have to load Schked at here, because of Rails and our railtie.
|
53
51
|
require "schked"
|
data/lib/schked/config.rb
CHANGED
@@ -5,7 +5,9 @@ require "logger"
|
|
5
5
|
module Schked
|
6
6
|
class Config
|
7
7
|
attr_writer :logger,
|
8
|
-
:do_not_load_root_schedule
|
8
|
+
:do_not_load_root_schedule,
|
9
|
+
:redis_servers,
|
10
|
+
:standalone
|
9
11
|
|
10
12
|
def paths
|
11
13
|
@paths ||= []
|
@@ -33,6 +35,16 @@ module Schked
|
|
33
35
|
end
|
34
36
|
end
|
35
37
|
|
38
|
+
def redis_servers
|
39
|
+
@redis_servers ||= [ENV.fetch("REDIS_URL", "redis://127.0.0.1:6379")]
|
40
|
+
end
|
41
|
+
|
42
|
+
def standalone?
|
43
|
+
@standalone = ENV["RAILS_ENV"] == "test" || ENV["RACK_ENV"] == "test" if @standalone.nil?
|
44
|
+
|
45
|
+
!!@standalone
|
46
|
+
end
|
47
|
+
|
36
48
|
private
|
37
49
|
|
38
50
|
def callbacks
|
@@ -0,0 +1,45 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Schked
|
4
|
+
class RedisLocker
|
5
|
+
attr_reader :lock_manager,
|
6
|
+
:lock_id,
|
7
|
+
:lock_ttl
|
8
|
+
|
9
|
+
LOCK_KEY = "schked:redis_locker"
|
10
|
+
LOCK_TTL = 60_000 # ms
|
11
|
+
|
12
|
+
def initialize(redis_servers, lock_ttl: LOCK_TTL)
|
13
|
+
@lock_manager = Redlock::Client.new(redis_servers, retry_count: 0)
|
14
|
+
@lock_ttl = lock_ttl
|
15
|
+
end
|
16
|
+
|
17
|
+
def lock
|
18
|
+
valid_lock? || !!try_lock
|
19
|
+
end
|
20
|
+
|
21
|
+
def unlock
|
22
|
+
lock_manager.unlock(lock_id) if valid_lock?
|
23
|
+
end
|
24
|
+
|
25
|
+
def extend_lock
|
26
|
+
return false unless valid_lock?
|
27
|
+
|
28
|
+
@lock_id = lock_manager.lock(LOCK_KEY, lock_ttl, extend: lock_id, extend_only_if_locked: true)
|
29
|
+
|
30
|
+
!!@lock_id
|
31
|
+
end
|
32
|
+
|
33
|
+
def valid_lock?
|
34
|
+
return false unless lock_id
|
35
|
+
|
36
|
+
lock_manager.valid_lock?(lock_id)
|
37
|
+
end
|
38
|
+
|
39
|
+
private
|
40
|
+
|
41
|
+
def try_lock
|
42
|
+
@lock_id = lock_manager.lock(LOCK_KEY, lock_ttl)
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
data/lib/schked/version.rb
CHANGED
data/lib/schked/worker.rb
CHANGED
@@ -7,9 +7,12 @@ module Schked
|
|
7
7
|
def initialize(config:)
|
8
8
|
@config = config
|
9
9
|
|
10
|
-
@
|
10
|
+
@locker = RedisLocker.new(config.redis_servers, lock_ttl: 40_000) unless config.standalone?
|
11
|
+
@scheduler = Rufus::Scheduler.new(trigger_lock: locker)
|
11
12
|
|
13
|
+
watch_signals
|
12
14
|
define_callbacks
|
15
|
+
define_extend_lock unless config.standalone?
|
13
16
|
load_schedule
|
14
17
|
end
|
15
18
|
|
@@ -38,7 +41,7 @@ module Schked
|
|
38
41
|
|
39
42
|
private
|
40
43
|
|
41
|
-
attr_reader :config, :scheduler
|
44
|
+
attr_reader :config, :scheduler, :locker
|
42
45
|
|
43
46
|
def define_callbacks
|
44
47
|
cfg = config
|
@@ -63,6 +66,31 @@ module Schked
|
|
63
66
|
end
|
64
67
|
end
|
65
68
|
|
69
|
+
def watch_signals
|
70
|
+
Signal.trap("TERM") do
|
71
|
+
config.logger.info("Going to shut down...")
|
72
|
+
@shutdown = true
|
73
|
+
end
|
74
|
+
|
75
|
+
Signal.trap("INT") do
|
76
|
+
config.logger.info("Going to shut down...")
|
77
|
+
@shutdown = true
|
78
|
+
end
|
79
|
+
|
80
|
+
Thread.new do
|
81
|
+
loop do
|
82
|
+
scheduler.shutdown(wait: 5) if @shutdown
|
83
|
+
sleep 0.2
|
84
|
+
end
|
85
|
+
end
|
86
|
+
end
|
87
|
+
|
88
|
+
def define_extend_lock
|
89
|
+
scheduler.every("10s", as: "Schked::Worker#extend_lock", timeout: "5s", overlap: false) do
|
90
|
+
locker.extend_lock
|
91
|
+
end
|
92
|
+
end
|
93
|
+
|
66
94
|
def load_schedule
|
67
95
|
scheduler.instance_eval(schedule)
|
68
96
|
end
|
data/lib/schked.rb
CHANGED
metadata
CHANGED
@@ -1,15 +1,29 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: schked
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version:
|
4
|
+
version: 1.1.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Misha Merkushin
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2022-
|
11
|
+
date: 2022-10-19 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: redlock
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - ">="
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '0'
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - ">="
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '0'
|
13
27
|
- !ruby/object:Gem::Dependency
|
14
28
|
name: rufus-scheduler
|
15
29
|
requirement: !ruby/object:Gem::Requirement
|
@@ -151,6 +165,7 @@ files:
|
|
151
165
|
- lib/schked/cli.rb
|
152
166
|
- lib/schked/config.rb
|
153
167
|
- lib/schked/railtie.rb
|
168
|
+
- lib/schked/redis_locker.rb
|
154
169
|
- lib/schked/version.rb
|
155
170
|
- lib/schked/worker.rb
|
156
171
|
homepage: https://github.com/bibendi/schked
|