expirable_locking 0.2.0 → 0.3.0

Sign up to get free protection for your applications and to get access to all the features.
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.2.0
1
+ 0.3.0
@@ -0,0 +1,50 @@
1
+ # Generated by jeweler
2
+ # DO NOT EDIT THIS FILE DIRECTLY
3
+ # Instead, edit Jeweler::Tasks in Rakefile, and run the gemspec command
4
+ # -*- encoding: utf-8 -*-
5
+
6
+ Gem::Specification.new do |s|
7
+ s.name = %q{expirable_locking}
8
+ s.version = "0.3.0"
9
+
10
+ s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
+ s.authors = ["Eric Chapweske"]
12
+ s.date = %q{2011-03-21}
13
+ s.description = %q{A tiny ActiveRecord extension for expirable locking.}
14
+ s.email = %q{eac@zendesk.com}
15
+ s.extra_rdoc_files = [
16
+ "LICENSE",
17
+ "README.rdoc"
18
+ ]
19
+ s.files = [
20
+ ".document",
21
+ ".gitignore",
22
+ "LICENSE",
23
+ "README.rdoc",
24
+ "Rakefile",
25
+ "VERSION",
26
+ "expirable_locking.gemspec",
27
+ "lib/expirable_locking.rb",
28
+ "test/expirable_locking_test.rb",
29
+ "test/helper.rb"
30
+ ]
31
+ s.homepage = %q{http://github.com/eac/expirable_locking}
32
+ s.rdoc_options = ["--charset=UTF-8"]
33
+ s.require_paths = ["lib"]
34
+ s.rubygems_version = %q{1.5.2}
35
+ s.summary = %q{A tiny ActiveRecord extension for expirable locking.}
36
+ s.test_files = [
37
+ "test/expirable_locking_test.rb",
38
+ "test/helper.rb"
39
+ ]
40
+
41
+ if s.respond_to? :specification_version then
42
+ s.specification_version = 3
43
+
44
+ if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
45
+ else
46
+ end
47
+ else
48
+ end
49
+ end
50
+
@@ -1,10 +1,13 @@
1
1
  module ExpirableLocking
2
2
 
3
3
  def self.extended(base)
4
- base.named_scope :unlocked, lambda {
5
- { :conditions => [ "locked_at IS NULL OR locked_at < ?", base.lock_duration.ago ] }
6
- }
7
- base.send(:include, InstanceMethods)
4
+ base.class_eval do
5
+ named_scope :unlocked, lambda {
6
+ { :conditions => [ "locked_at IS NULL OR locked_at < ?", base.lock_duration.ago ] }
7
+ }
8
+
9
+ include InstanceMethods
10
+ end
8
11
  end
9
12
 
10
13
  module InstanceMethods
@@ -30,20 +33,50 @@ module ExpirableLocking
30
33
  def unlock(record)
31
34
  return true if record.destroyed?
32
35
 
33
- 1 == update_all({ :locked_at => nil }, { :id => record, :locked_at => record.locked_at })
36
+ new_attributes = unlock_attributes
37
+ if result = (1 == update_all(new_attributes, { :id => record, :locked_at => record.locked_at }))
38
+
39
+ new_attributes.each do |key, value|
40
+ record.write_attribute_without_dirty(key, value)
41
+ end
42
+
43
+ end
44
+
45
+ result
34
46
  end
35
47
 
36
48
  # Updates lock timestamp without triggering validations/callbacks.
37
49
  def touch_lock(record)
38
- locked_at = default_timezone == :utc ? Time.now.utc : Time.now
39
- result = update_all({ :locked_at => locked_at }, { :id => record })
50
+ new_attributes = lock_attributes
51
+ result = update_all(new_attributes, { :id => record })
40
52
 
41
53
  if result == 1
42
- record.write_attribute_without_dirty(:locked_at, locked_at)
54
+ new_attributes.each do |key, value|
55
+ record.write_attribute_without_dirty(key, value)
56
+ end
43
57
  end
44
58
 
45
59
  result
46
60
  end
47
61
 
62
+ def unlock_attributes
63
+ lock_attributes.tap do |attributes|
64
+ attributes.keys.each { |key| attributes[key] = nil }
65
+ end
66
+ end
67
+
68
+ def lock_attributes
69
+ locked_at = default_timezone == :utc ? Time.now.utc : Time.now
70
+
71
+ Hash.new.tap do |attributes|
72
+ attributes[:locked_at] = locked_at
73
+ attributes[:locked_by] = lock_name if method_defined?(:locked_by)
74
+ end
75
+ end
76
+
77
+ def lock_name
78
+ "#{`hostname`.chomp}:#{Process.pid}"
79
+ end
80
+
48
81
  end
49
82
 
@@ -1,4 +1,5 @@
1
1
  require 'helper'
2
+ require 'socket'
2
3
 
3
4
  class ExpirableLockingTest < ActiveRecord::TestCase
4
5
 
@@ -51,6 +52,27 @@ class ExpirableLockingTest < ActiveRecord::TestCase
51
52
  assert_equal true, @record.lock_with_expiry
52
53
  end
53
54
 
55
+ should "add the name of the locking process" do
56
+ assert_equal nil, @record.locked_by
57
+ @model.stubs(:lock_name).returns('host.example:1234')
58
+ assert @record.lock_with_expiry
59
+ @record.reload
60
+
61
+ assert_equal 'host.example:1234', @record.locked_by
62
+ end
63
+
64
+ end
65
+
66
+ context "lock_name" do
67
+
68
+ should "include the host name" do
69
+ assert_match Socket.gethostname, @model.lock_name
70
+ end
71
+
72
+ should "include the pid" do
73
+ assert_match Process.pid.to_s, @model.lock_name
74
+ end
75
+
54
76
  end
55
77
 
56
78
  context "unlocking" do
@@ -82,6 +104,8 @@ class ExpirableLockingTest < ActiveRecord::TestCase
82
104
  @record.unlock
83
105
 
84
106
  assert @model.unlocked.include?(@record)
107
+ assert_equal nil, @record.locked_at
108
+ assert_equal nil, @record.locked_by
85
109
  end
86
110
 
87
111
  end
@@ -102,4 +126,3 @@ class ExpirableLockingTest < ActiveRecord::TestCase
102
126
  end
103
127
 
104
128
  end
105
-
@@ -24,6 +24,7 @@ ActiveRecord::Schema.define do
24
24
  table.timestamps
25
25
 
26
26
  table.datetime :locked_at
27
+ table.string :locked_by
27
28
  end
28
29
 
29
30
  end
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: expirable_locking
3
3
  version: !ruby/object:Gem::Version
4
- hash: 23
5
- prerelease: false
4
+ hash: 19
5
+ prerelease:
6
6
  segments:
7
7
  - 0
8
- - 2
8
+ - 3
9
9
  - 0
10
- version: 0.2.0
10
+ version: 0.3.0
11
11
  platform: ruby
12
12
  authors:
13
13
  - Eric Chapweske
@@ -15,7 +15,7 @@ autorequire:
15
15
  bindir: bin
16
16
  cert_chain: []
17
17
 
18
- date: 2010-08-24 00:00:00 -07:00
18
+ date: 2011-03-21 00:00:00 -07:00
19
19
  default_executable:
20
20
  dependencies: []
21
21
 
@@ -35,6 +35,7 @@ files:
35
35
  - README.rdoc
36
36
  - Rakefile
37
37
  - VERSION
38
+ - expirable_locking.gemspec
38
39
  - lib/expirable_locking.rb
39
40
  - test/expirable_locking_test.rb
40
41
  - test/helper.rb
@@ -68,7 +69,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
68
69
  requirements: []
69
70
 
70
71
  rubyforge_project:
71
- rubygems_version: 1.3.7
72
+ rubygems_version: 1.5.2
72
73
  signing_key:
73
74
  specification_version: 3
74
75
  summary: A tiny ActiveRecord extension for expirable locking.