schked 1.1.2 → 1.3.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: fe971fe49c1279ffd4cbc39948faea2fb82fa58434aa90814e1c1cbe2ebd99e2
4
- data.tar.gz: 2b8800aa8128347a42e1f7fe2d73930293baae1ff258d6f1ddd24f21dff297c4
3
+ metadata.gz: 3cb8172851d135726e8cf5ae569e378c4855de6b78466fc19786a81fcd08045a
4
+ data.tar.gz: 0d448a52410312f3b0c6132059bc43a6f4f147b242ad4f7bfb1a47742df07990
5
5
  SHA512:
6
- metadata.gz: a8dcdca1dad927793b3c0f6356a1f6222a9e4081b20baca7df9391c93ea044f8f2f9bf7fa2db05c330616a0692597abbf8e2807a07d5c6f80bff0687bfd90911
7
- data.tar.gz: 370cab83d6e000cbc0cb2c19be884738315434d3dd42d0bf718c1b094194231b77f8356d2782f6a7c773b98aa64f3eedc6de39f3a34206f8a3aa381645f5012e
6
+ metadata.gz: 89be3ba061cc48c06024ca0f1697dc74d2dd383e5e1c73dbe14ffeb3d781862004341d45643db09081a7997c753912e3fb7e3af1d8fb778a9a768582302af3ab
7
+ data.tar.gz: 430bdb484f6962a1e41efeef2b47112614f98356cfe6d4e68eabb0f871c566bbca368e0f19e438383c680184740c32087f50757bdf31f0a7440506ae97c71287
data/README.md CHANGED
@@ -79,7 +79,7 @@ When you deploy your schedule to production, you want to start new instance befo
79
79
  You can configure Redis client as the following:
80
80
 
81
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"]
82
+ Schked.config.redis = {url: ENV.fetch("REDIS_URL") }
83
83
  ```
84
84
 
85
85
  ### Callbacks
@@ -94,7 +94,19 @@ Schked.config.register_callback(:on_error) do |job, error|
94
94
  end
95
95
  ```
96
96
 
97
- There are `:before_start` and `:after_finish` callbacks as well.
97
+ There are `:before_start`, `:after_finish` and `:around_job` callbacks as well.
98
+
99
+ Warning: `:before_start` and `:after_finish` callbacks are executed in the scheduler thread, not in the work threads (the threads where the job execution really happens).
100
+
101
+ `:around_job` callback is executed in the job's thread.
102
+
103
+ ```ruby
104
+ Schked.config.register_callback(:around_job) do |job, &block|
105
+ ...
106
+ block.call
107
+ ...
108
+ end
109
+ ```
98
110
 
99
111
  ### Logging
100
112
 
data/lib/schked/config.rb CHANGED
@@ -6,7 +6,7 @@ module Schked
6
6
  class Config
7
7
  attr_writer :logger,
8
8
  :do_not_load_root_schedule,
9
- :redis_servers,
9
+ :redis,
10
10
  :standalone
11
11
 
12
12
  def paths
@@ -35,8 +35,36 @@ module Schked
35
35
  end
36
36
  end
37
37
 
38
- def redis_servers
39
- @redis_servers ||= [ENV.fetch("REDIS_URL", "redis://127.0.0.1:6379")]
38
+ def fire_around_callback(name, job, calls = callbacks[name], &block)
39
+ return yield if calls.none?
40
+
41
+ calls.first.call(job) do
42
+ calls = calls.drop(1)
43
+ if calls.any?
44
+ fire_around_callback(name, job, calls, &block)
45
+ else
46
+ yield
47
+ end
48
+ end
49
+ end
50
+
51
+ def redis
52
+ @redis ||= {url: ENV.fetch("REDIS_URL", "redis://127.0.0.1:6379")}
53
+ end
54
+
55
+ def redis_servers=(val)
56
+ val = val.first
57
+
58
+ if val.is_a?(String)
59
+ self.redis = {url: val}
60
+ elsif val.respond_to?(:_client)
61
+ conf = val._client.config
62
+ self.redis = {url: conf.server_url, username: conf.username, password: conf.password}
63
+ else
64
+ raise ArgumentError, "Schked `redis_servers=` config option is deprecated. Please use `redis=` with a Hash"
65
+ end
66
+
67
+ warn "🔥 Schked `redis_servers=` config option is deprecated. Please use `redis=` with a Hash. Called from #{caller(1..1).first}"
40
68
  end
41
69
 
42
70
  def standalone?
@@ -0,0 +1,34 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "redis-client"
4
+
5
+ module Schked
6
+ module RedisClientFactory
7
+ def self.build(options)
8
+ unless options.key?(:reconnect_attempts)
9
+ options[:reconnect_attempts] = 3
10
+ end
11
+
12
+ if options.key?(:sentinels)
13
+ if (url = options.delete(:url))
14
+ uri = URI.parse(url)
15
+ if !options.key?(:name) && uri.host
16
+ options[:name] = uri.host
17
+ end
18
+
19
+ if !options.key?(:password) && uri.password && !uri.password.empty?
20
+ options[:password] = uri.password
21
+ end
22
+
23
+ if !options.key?(:username) && uri.user && !uri.user.empty?
24
+ options[:username] = uri.user
25
+ end
26
+ end
27
+
28
+ RedisClient.sentinel(**options).new_client
29
+ else
30
+ RedisClient.config(**options).new_client
31
+ end
32
+ end
33
+ end
34
+ end
@@ -10,8 +10,8 @@ module Schked
10
10
  LOCK_KEY = "schked:redis_locker"
11
11
  LOCK_TTL = 60_000 # ms
12
12
 
13
- def initialize(redis_servers, lock_ttl: LOCK_TTL, logger: Logger.new($stdout))
14
- @lock_manager = Redlock::Client.new(redis_servers, retry_count: 0)
13
+ def initialize(redis_conf, lock_ttl: LOCK_TTL, logger: Logger.new($stdout))
14
+ @lock_manager = Redlock::Client.new([redis_client(redis_conf)], retry_count: 0)
15
15
  @lock_ttl = lock_ttl
16
16
  @logger = logger
17
17
  end
@@ -49,6 +49,14 @@ module Schked
49
49
 
50
50
  private
51
51
 
52
+ def redis_client(redis_conf)
53
+ if Gem::Version.new(Redlock::VERSION) >= Gem::Version.new("2.0.0")
54
+ ConnectionPool::Wrapper.new { RedisClientFactory.build(redis_conf) }
55
+ else
56
+ ConnectionPool::Wrapper.new { Redis.new(**redis_conf) }
57
+ end
58
+ end
59
+
52
60
  def try_lock
53
61
  @lock_id = lock_manager.lock(LOCK_KEY, lock_ttl)
54
62
  end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Schked
4
- VERSION = "1.1.2"
4
+ VERSION = "1.3.0"
5
5
  end
data/lib/schked/worker.rb CHANGED
@@ -7,7 +7,8 @@ module Schked
7
7
  def initialize(config:)
8
8
  @config = config
9
9
 
10
- @locker = RedisLocker.new(config.redis_servers, lock_ttl: 40_000, logger: config.logger) unless config.standalone?
10
+ @locker = RedisLocker.new(config.redis, lock_ttl: 40_000, logger: config.logger) unless config.standalone?
11
+
11
12
  @scheduler = Rufus::Scheduler.new(trigger_lock: locker)
12
13
 
13
14
  watch_signals
@@ -67,6 +68,10 @@ module Schked
67
68
  cfg.fire_callback(:before_start, job, time)
68
69
  end
69
70
 
71
+ scheduler.define_singleton_method(:around_trigger) do |job, &block|
72
+ cfg.fire_around_callback(:around_job, job, &block)
73
+ end
74
+
70
75
  scheduler.define_singleton_method(:on_post_trigger) do |job, time|
71
76
  cfg.logger.info("Finished task: #{extract_job_name(job)}")
72
77
 
data/lib/schked.rb CHANGED
@@ -1,11 +1,13 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require "connection_pool"
3
4
  require "redlock"
4
5
 
5
6
  require "schked/version"
6
7
  require "schked/config"
7
8
  require "schked/worker"
8
9
  require "schked/redis_locker"
10
+ require "schked/redis_client_factory"
9
11
  require "schked/railtie" if defined?(Rails)
10
12
 
11
13
  module Schked
metadata CHANGED
@@ -1,29 +1,49 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: schked
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.1.2
4
+ version: 1.3.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-12-16 00:00:00.000000000 Z
11
+ date: 2023-09-06 00:00:00.000000000 Z
12
12
  dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: connection_pool
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '2.0'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '2.0'
13
27
  - !ruby/object:Gem::Dependency
14
28
  name: redlock
15
29
  requirement: !ruby/object:Gem::Requirement
16
30
  requirements:
17
- - - ">="
31
+ - - ">"
18
32
  - !ruby/object:Gem::Version
19
- version: '0'
33
+ version: '1.0'
34
+ - - "<"
35
+ - !ruby/object:Gem::Version
36
+ version: '3.0'
20
37
  type: :runtime
21
38
  prerelease: false
22
39
  version_requirements: !ruby/object:Gem::Requirement
23
40
  requirements:
24
- - - ">="
41
+ - - ">"
25
42
  - !ruby/object:Gem::Version
26
- version: '0'
43
+ version: '1.0'
44
+ - - "<"
45
+ - !ruby/object:Gem::Version
46
+ version: '3.0'
27
47
  - !ruby/object:Gem::Dependency
28
48
  name: rufus-scheduler
29
49
  requirement: !ruby/object:Gem::Requirement
@@ -95,33 +115,33 @@ dependencies:
95
115
  - !ruby/object:Gem::Version
96
116
  version: '1.3'
97
117
  - !ruby/object:Gem::Dependency
98
- name: pry-byebug
118
+ name: rake
99
119
  requirement: !ruby/object:Gem::Requirement
100
120
  requirements:
101
121
  - - "~>"
102
122
  - !ruby/object:Gem::Version
103
- version: '3.9'
123
+ version: '13.0'
104
124
  type: :development
105
125
  prerelease: false
106
126
  version_requirements: !ruby/object:Gem::Requirement
107
127
  requirements:
108
128
  - - "~>"
109
129
  - !ruby/object:Gem::Version
110
- version: '3.9'
130
+ version: '13.0'
111
131
  - !ruby/object:Gem::Dependency
112
- name: rake
132
+ name: redis-client
113
133
  requirement: !ruby/object:Gem::Requirement
114
134
  requirements:
115
135
  - - "~>"
116
136
  - !ruby/object:Gem::Version
117
- version: '13.0'
137
+ version: '0.10'
118
138
  type: :development
119
139
  prerelease: false
120
140
  version_requirements: !ruby/object:Gem::Requirement
121
141
  requirements:
122
142
  - - "~>"
123
143
  - !ruby/object:Gem::Version
124
- version: '13.0'
144
+ version: '0.10'
125
145
  - !ruby/object:Gem::Dependency
126
146
  name: rspec
127
147
  requirement: !ruby/object:Gem::Requirement
@@ -165,6 +185,7 @@ files:
165
185
  - lib/schked/cli.rb
166
186
  - lib/schked/config.rb
167
187
  - lib/schked/railtie.rb
188
+ - lib/schked/redis_client_factory.rb
168
189
  - lib/schked/redis_locker.rb
169
190
  - lib/schked/version.rb
170
191
  - lib/schked/worker.rb
@@ -179,9 +200,9 @@ require_paths:
179
200
  - lib
180
201
  required_ruby_version: !ruby/object:Gem::Requirement
181
202
  requirements:
182
- - - ">"
203
+ - - ">="
183
204
  - !ruby/object:Gem::Version
184
- version: '2.5'
205
+ version: '2.7'
185
206
  required_rubygems_version: !ruby/object:Gem::Requirement
186
207
  requirements:
187
208
  - - ">="