sidetiq 0.3.5 → 0.3.6

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
2
  SHA1:
3
- metadata.gz: 79f2b65ef53704beb2a8b0176b5a72a840b5df07
4
- data.tar.gz: 99004a1cb008a81248c80217603b041f6c44fcb8
3
+ metadata.gz: 1df64df09fdf5d7e87b13410a3a8b39c325fd70a
4
+ data.tar.gz: 43e79f2eb7c71065ba27f54cf8e36924c8575250
5
5
  SHA512:
6
- metadata.gz: 8e15758167ae4177fa2dcf367fb40b5a1070b4815f78105d0437df53a9f478b81a7ac6e9c3b01d6420fd08be1f230bb3464a808a72d6c42469e4c64ca9b1db3a
7
- data.tar.gz: 534269b3b8e92d1fd4ff9f3f15e82145fc180f9f976a697fa8a2ad4ba9220cae2e7a26b480eba5dea001dfdd43f1efd06d3c52aa9a50f3c804e47c8ae844a176
6
+ metadata.gz: 3b11cd2d90c41504bd9914ca3058cc242c9d4819d4d8550348e2326d85aaacbcf9293f02f5ac01b058be6b222f94eedbca5bafeba76c3cc231e168c1d63a964c
7
+ data.tar.gz: c5b583be6d96c52e8494bc790c406f5d06cd84e0e0b643e0ca14ef9eae1dc36b5e858cfde858a2e8891d3c11bb18d2982f4018370beba0451cccd54f1171930d
data/.travis.yml CHANGED
@@ -1,6 +1,39 @@
1
1
  language: ruby
2
+ branches:
3
+ only:
4
+ - master
5
+ services:
6
+ - redis-server
2
7
  rvm:
3
8
  - 1.9.3
4
9
  - 2.0.0
5
10
  - jruby-19mode
6
11
  - rbx-19mode
12
+ - ruby-head
13
+ - jruby-head
14
+ jdk:
15
+ - openjdk6
16
+ - openjdk7
17
+ - oraclejdk7
18
+ matrix:
19
+ exclude:
20
+ - rvm: 2.0.0
21
+ jdk: openjdk7
22
+ - rvm: 2.0.0
23
+ jdk: openjdk6
24
+ - rvm: 1.9.3
25
+ jdk: openjdk7
26
+ - rvm: 1.9.3
27
+ jdk: openjdk6
28
+ - rvm: rbx-19mode
29
+ jdk: openjdk7
30
+ - rvm: rbx-19mode
31
+ jdk: openjdk6
32
+ - rvm: ruby-head
33
+ jdk: openjdk7
34
+ - rvm: ruby-head
35
+ jdk: openjdk6
36
+ allow_failures:
37
+ - rvm: rbx-19mode
38
+ - rvm: ruby-head
39
+ - rvm: jruby-head
data/CHANGELOG.md CHANGED
@@ -1,3 +1,14 @@
1
+ 0.3.6
2
+ -----
3
+
4
+ - Better protection against stale locks and race-conditions.
5
+
6
+ Locking is now done using WATCH/MULTI/EXEC/UNWATCH and additionally
7
+ includes a host and process specific identifier to prevent accidental
8
+ unlocks from other Sidekiq processes.
9
+
10
+ - Fix Sidetiq::Schedulable documentation.
11
+
1
12
  0.3.5
2
13
  -----
3
14
 
data/lib/sidetiq.rb CHANGED
@@ -2,6 +2,7 @@
2
2
  require 'monitor'
3
3
  require 'ostruct'
4
4
  require 'singleton'
5
+ require 'socket'
5
6
 
6
7
  # gems
7
8
  require 'ice_cube'
@@ -10,6 +11,7 @@ require 'sidekiq'
10
11
  # internal
11
12
  require 'sidetiq/config'
12
13
  require 'sidetiq/clock'
14
+ require 'sidetiq/lock'
13
15
  require 'sidetiq/middleware'
14
16
  require 'sidetiq/schedule'
15
17
  require 'sidetiq/schedulable'
data/lib/sidetiq/clock.rb CHANGED
@@ -52,7 +52,7 @@ module Sidetiq
52
52
  tick = gettime
53
53
  mon_synchronize do
54
54
  schedules.each do |worker, sched|
55
- synchronize_clockworks(worker) do |redis|
55
+ Lock.new(worker).synchronize do |redis|
56
56
  if sched.backfill? && (last = worker.last_scheduled_occurrence) > 0
57
57
  last = Sidetiq.config.utc ? Time.at(last).utc : Time.at(last)
58
58
  sched.occurrences_between(last + 1, tick).each do |past_t|
@@ -150,24 +150,6 @@ module Sidetiq
150
150
  end
151
151
  end
152
152
 
153
- def synchronize_clockworks(klass)
154
- lock = "sidetiq:#{klass.name}:lock"
155
-
156
- Sidekiq.redis do |redis|
157
- if redis.setnx(lock, 1)
158
- Sidetiq.logger.debug "Sidetiq::Clock lock #{lock}"
159
-
160
- begin
161
- redis.pexpire(lock, Sidetiq.config.lock_expire)
162
- yield redis
163
- ensure
164
- redis.del(lock)
165
- Sidetiq.logger.debug "Sidetiq::Clock unlock #{lock}"
166
- end
167
- end
168
- end
169
- end
170
-
171
153
  def clock
172
154
  loop do
173
155
  sleep_time = time { yield }
@@ -0,0 +1,63 @@
1
+ module Sidetiq
2
+ class Lock # :nodoc: all
3
+ attr_reader :key, :timeout
4
+
5
+ OWNER = "#{Socket.gethostname}:#{Process.pid}"
6
+
7
+ def initialize(key, timeout = Sidetiq.config.lock_expire)
8
+ @key = key.kind_of?(Class) ? "sidetiq:#{key.name}:lock" : "sidetiq:#{key}:lock"
9
+ @timeout = timeout
10
+ end
11
+
12
+ def synchronize
13
+ Sidekiq.redis do |redis|
14
+ if lock(redis)
15
+ Sidetiq.logger.debug "Sidetiq::Clock lock #{key}"
16
+
17
+ begin
18
+ yield redis
19
+ ensure
20
+ unlock(redis)
21
+ Sidetiq.logger.debug "Sidetiq::Clock unlock #{key}"
22
+ end
23
+ end
24
+ end
25
+ end
26
+
27
+ private
28
+
29
+ def lock(redis)
30
+ acquired = false
31
+
32
+ watch(redis, key) do
33
+ if !redis.exists(key)
34
+ acquired = !!redis.multi do |multi|
35
+ multi.psetex(key, timeout, OWNER)
36
+ end
37
+ end
38
+ end
39
+
40
+ acquired
41
+ end
42
+
43
+ def unlock(redis)
44
+ watch(redis, key) do
45
+ if redis.get(key) == OWNER
46
+ redis.multi do |multi|
47
+ multi.del(key)
48
+ end
49
+ end
50
+ end
51
+ end
52
+
53
+ def watch(redis, *args)
54
+ redis.watch(*args)
55
+
56
+ begin
57
+ yield
58
+ ensure
59
+ redis.unwatch
60
+ end
61
+ end
62
+ end
63
+ end
@@ -8,7 +8,7 @@ module Sidetiq
8
8
  # include Sidetiq::Schedulable
9
9
  #
10
10
  # # Daily at midnight
11
- # tiq { daily }
11
+ # recurrence { daily }
12
12
  # end
13
13
  module Schedulable
14
14
  module ClassMethods
@@ -47,7 +47,7 @@ module Sidetiq
47
47
  # include Sidekiq::Worker
48
48
  # include Sidetiq::Schedulable
49
49
  #
50
- # tiq { daily }
50
+ # recurrence { daily }
51
51
  #
52
52
  # def perform
53
53
  # end
@@ -8,7 +8,7 @@ module Sidetiq
8
8
  MINOR = 3
9
9
 
10
10
  # Public: Sidetiq patch level.
11
- PATCH = 5
11
+ PATCH = 6
12
12
 
13
13
  # Public: String representation of the current Sidetiq version.
14
14
  STRING = [MAJOR, MINOR, PATCH].compact.join('.')
data/test/test_lock.rb ADDED
@@ -0,0 +1,30 @@
1
+ require_relative 'helper'
2
+
3
+ class TestLock < Sidetiq::TestCase
4
+ def test_locking
5
+ lock_name = SecureRandom.hex(8)
6
+ key = SecureRandom.hex(8)
7
+
8
+ Sidekiq.redis do |redis|
9
+ redis.set(key, 0)
10
+
11
+ 5.times.map do
12
+ Thread.start do
13
+ locked(lock_name) do |r|
14
+ sleep 0.1
15
+ r.incr(key)
16
+ end
17
+ end
18
+ end.each(&:join)
19
+
20
+ assert_equal "1", redis.get(key)
21
+ end
22
+ end
23
+
24
+ def locked(lock_name)
25
+ Sidetiq::Lock.new(lock_name).synchronize do |redis|
26
+ yield redis
27
+ end
28
+ end
29
+ end
30
+
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: sidetiq
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.5
4
+ version: 0.3.6
5
5
  platform: ruby
6
6
  authors:
7
7
  - Tobias Svensson
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2013-07-29 00:00:00.000000000 Z
11
+ date: 2013-08-13 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: sidekiq
@@ -56,6 +56,7 @@ files:
56
56
  - lib/sidetiq.rb
57
57
  - lib/sidetiq/clock.rb
58
58
  - lib/sidetiq/config.rb
59
+ - lib/sidetiq/lock.rb
59
60
  - lib/sidetiq/middleware.rb
60
61
  - lib/sidetiq/schedulable.rb
61
62
  - lib/sidetiq/schedule.rb
@@ -73,6 +74,7 @@ files:
73
74
  - test/helper.rb
74
75
  - test/test_clock.rb
75
76
  - test/test_config.rb
77
+ - test/test_lock.rb
76
78
  - test/test_middleware.rb
77
79
  - test/test_schedule.rb
78
80
  - test/test_sidetiq.rb
@@ -113,6 +115,7 @@ test_files:
113
115
  - test/helper.rb
114
116
  - test/test_clock.rb
115
117
  - test/test_config.rb
118
+ - test/test_lock.rb
116
119
  - test/test_middleware.rb
117
120
  - test/test_schedule.rb
118
121
  - test/test_sidetiq.rb