with_lock 0.0.4.alpha

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 ADDED
@@ -0,0 +1,15 @@
1
+ ---
2
+ !binary "U0hBMQ==":
3
+ metadata.gz: !binary |-
4
+ OTIxODdiOTM5NjRiZGEwMWRmYTE3NDJiMDEyMmQ5N2NiZWNhNTRiOQ==
5
+ data.tar.gz: !binary |-
6
+ NDNkNjI2MDUxMmZhYmE3OWNmZThiOTI5NzMzNjgzOTFlOTU0NTNlMQ==
7
+ SHA512:
8
+ metadata.gz: !binary |-
9
+ MDNhYTE5YTI3ZTE3ZWJhMTY4ODNlNWExNjI4YTQ2Y2ExNjM3NjVkM2M4OTk1
10
+ ODlhMmM4MTNlNzEyOGZkZjVjMzIyODcwZWNjMDc5NGRjM2MxOTlmYTFmZGE0
11
+ ZTBjNmFlOGRjZDgwZGU0MjA2NDNhZTJjZTc2MThjN2FkM2FjZWY=
12
+ data.tar.gz: !binary |-
13
+ NzQzMWRhZTE5YjFlZDkyODFhY2FmNzRlODdkYzcxMmQyZWFhMWI3YjgzYWI3
14
+ NThiMjNlNDExYjkzYjZmM2FiMzAyZTc0Y2M1ZjE2ZWNjMWU5NDQ5NzFmNjU3
15
+ OTFmMWY3NTZiYmRmOTgwYmFkNGFmMmU3N2Y4MzFhYzRmYmExYzY=
data/.gitignore ADDED
@@ -0,0 +1,8 @@
1
+ # no tmp files
2
+ /tmp
3
+
4
+ # no log files
5
+ /log
6
+
7
+ # no OS files
8
+ *.DS_Store
data/.rspec ADDED
@@ -0,0 +1 @@
1
+ --color
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source "http://rubygems.org"
2
+
3
+ # Specify your gem's dependencies in with_lock.gemspec
4
+ gemspec
data/Gemfile.lock ADDED
@@ -0,0 +1,26 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ with_lock (0.0.4.alpha)
5
+ daemons
6
+
7
+ GEM
8
+ remote: http://rubygems.org/
9
+ specs:
10
+ daemons (1.1.9)
11
+ diff-lcs (1.1.3)
12
+ rspec (2.8.0)
13
+ rspec-core (~> 2.8.0)
14
+ rspec-expectations (~> 2.8.0)
15
+ rspec-mocks (~> 2.8.0)
16
+ rspec-core (2.8.0)
17
+ rspec-expectations (2.8.0)
18
+ diff-lcs (~> 1.1.2)
19
+ rspec-mocks (2.8.0)
20
+
21
+ PLATFORMS
22
+ ruby
23
+
24
+ DEPENDENCIES
25
+ rspec
26
+ with_lock!
data/README.md ADDED
@@ -0,0 +1,45 @@
1
+ # WithLock
2
+
3
+ Provides a DRb service to provide locking across a distributed ruby application.
4
+
5
+ ## Installation
6
+
7
+ Add to your Gemfile and run the `bundle` command to install it.
8
+
9
+ ```ruby
10
+ gem "with_lock", git: 'https://github.com/chrisboy333/with_lock.git'
11
+ ```
12
+
13
+ **Tested under Ruby 1.9.3.**
14
+
15
+ Add script and config files to your project(from console):
16
+ ```ruby
17
+ WithLock.setup
18
+ ```
19
+ In the configuration file you can change some settings if you like ... it defaults to using the following... where 'scope' is the application directory name with rails environment appended(if present):
20
+ url: druby://loclahost:9999
21
+ scope: <%= File.basename(File.expand_path('.')) %><%= ":#{Rails.env}" if defined?(Rails) %>
22
+ directory: tmp
23
+
24
+ The scope is used to let different applications use the same drb server ... or different parts of an app acquire the same named locks(not that I think this latter is a great idea) ...
25
+
26
+ Start/Stop the service from ruby
27
+ ```ruby
28
+ WithLock::Server.start_service
29
+ WithLock::Server.stop_service
30
+ ```
31
+ Start/Stop service from
32
+
33
+ ## Usage
34
+ A "with_lock()" function is provided globally to wrap with_lock sections of code.
35
+
36
+ ```ruby
37
+ with_lock('lock_name') do
38
+ puts "This is something only I can do right now, provided others are using the locks!"
39
+ end
40
+ ```
41
+ ## Development
42
+
43
+ Questions or problems? Please post them on the [issue tracker](https://github.com/chrisboy333/with_lock/issues). You can contribute changes by forking the project and submitting a pull request. You can ensure the tests passing by running `bundle` and `rake`.
44
+
45
+ This gem is created by Christopher Hauboldt and is under the MIT License.
data/Rakefile ADDED
@@ -0,0 +1,9 @@
1
+ require "bundler/gem_tasks"
2
+
3
+ require 'rspec/core/rake_task'
4
+ desc 'Run the specs'
5
+ RSpec::Core::RakeTask.new do |r|
6
+ r.verbose = false
7
+ end
8
+
9
+ task :default => :spec
@@ -0,0 +1,3 @@
1
+ url: druby://localhost:9999
2
+ scope: <%= File.basename(File.expand_path('.')) %><%= ":#{Rails.env}" if defined?(Rails) %>
3
+ directory: 'tmp'
@@ -0,0 +1,3 @@
1
+ url: druby://localhost:9999
2
+ scope: <%= File.basename(File.expand_path('.')) %><%= ":#{Rails.env}" if defined?(Rails) %>
3
+ directory: 'tmp'
data/lib/with_lock.rb ADDED
@@ -0,0 +1,89 @@
1
+ require "with_lock/version"
2
+ require 'erb'
3
+ require 'yaml'
4
+ require 'fileutils'
5
+ require 'logger'
6
+
7
+ module WithLock
8
+ class LockException < Exception
9
+ end
10
+
11
+ def self.setup
12
+ gem_dir = File.expand_path(File.join('..','..'),__FILE__)
13
+ app_dir = File.expand_path('.')
14
+ FileUtils.cp(File.join(gem_dir,'config','with_lock.yml'),File.join(app_dir,'config','with_lock.yml'))
15
+ FileUtils.cp(File.join(gem_dir,'script','with_lock'),File.join(app_dir,'script','with_lock'))
16
+ FileUtils.chmod(0755, File.join(app_dir,'script','with_lock'))
17
+ true
18
+ end
19
+
20
+ module Public
21
+ def with_lock(name,timeout=5,&block)
22
+ WithLock::Client.with_lock(name,timeout) do
23
+ yield
24
+ end
25
+ end
26
+ end
27
+
28
+ module Common
29
+ def logger
30
+ return @@logger if defined?(@@logger) && !@@logger.nil?
31
+ @@logger = nil
32
+ @@logger = Rails.logger if defined?(Rails)
33
+ FileUtils.mkdir_p('log') if @@logger.nil?
34
+ @@logger ||= Logger.new(File.join('log','with_lock.log'))
35
+ end
36
+
37
+ def url
38
+ settings['url']
39
+ end
40
+
41
+ def pidfile
42
+ File.join('tmp','pids','with_lock.pid')
43
+ end
44
+
45
+ def pid
46
+ File.read(pidfile).strip
47
+ rescue => e
48
+ nil
49
+ end
50
+
51
+ def running?(pid)
52
+ `ps -p#{pid} | wc -l`.to_i == 2
53
+ end
54
+
55
+ def settings_filename
56
+ File.join('config','with_lock.yml')
57
+ end
58
+
59
+ def local_settings_filename
60
+ File.join('config','with_lock.local.yml')
61
+ end
62
+
63
+ def settings
64
+ return @@settings if defined? @@settings
65
+ @@settings = default_settings
66
+ @@settings = @@settings.merge!(load_settings(settings_filename)||{}) if File.exists?(settings_filename)
67
+ @@settings.merge!(load_settings(local_settings_filename)||{}) if File.exists?(local_settings_filename)
68
+ @@settings
69
+ end
70
+
71
+ def default_settings
72
+ {
73
+ 'directory' => File.join('tmp'),
74
+ 'url' => "druby://localhost:9999",
75
+ 'scope' => "#{File.basename(File.expand_path('.'))}#{":#{Rails.env}" if defined?(Rails)}"
76
+ }
77
+ end
78
+
79
+ def load_settings(filename)
80
+ YAML.load(ERB.new(File.read(filename)).result)
81
+ end
82
+ end
83
+ end
84
+
85
+ WithLock::Public.respond_to?(:with_lock)
86
+
87
+ require 'with_lock/server'
88
+ require 'with_lock/client'
89
+ Object.send :include, WithLock::Public
@@ -0,0 +1,76 @@
1
+ class WithLock::Client
2
+ extend WithLock::Common
3
+ @@locker = nil
4
+
5
+ def self.scoped_name(name)
6
+ "#{scope}-#{name}"
7
+ end
8
+
9
+ def self.identity
10
+ "#{`hostname`.strip}|#{$$}"
11
+ end
12
+
13
+ def self.get(name,timeout=5)
14
+ locker.get(identity,scoped_name(name),timeout)
15
+ end
16
+
17
+ def self.release(name)
18
+ locker.release(identity,scoped_name(name))
19
+ end
20
+
21
+ def self.mine?(name)
22
+ locker.mine?(identity,scoped_name(name))
23
+ end
24
+
25
+ def self.with_lock(name, timeout=5, &block)
26
+ begin
27
+ locked = mine?(name) && increment(name)
28
+ locked ||= get(name,timeout) || raise(WithLock::LockException.new("Failed to obtain lock #{name} in #{timeout} seconds."))
29
+ yield
30
+ ensure
31
+ if locker_available?
32
+ decrement(name).to_i > 0 || release(name) || logger.debug("Warning: lock #{name} not released!")
33
+ end
34
+ end
35
+ end
36
+
37
+ def self.locker_available?
38
+ locker.url
39
+ true
40
+ rescue DRb::DRbConnError => e
41
+ false
42
+ end
43
+
44
+ def self.increment(name)
45
+ locker.increment(identity,scoped_name(name))
46
+ end
47
+
48
+ def self.decrement(name)
49
+ locker.decrement(identity,scoped_name(name))
50
+ end
51
+
52
+ def self.scope
53
+ @@scope ||= Rails.env if defined? Rails
54
+ @@scope ||= File.expand_path('.').split(File::SEPARATOR).last
55
+ end
56
+
57
+ def self.reconnect!
58
+ DRb.stop_service
59
+ @@uri = DRb.start_service
60
+ @@locker = DRbObject.new_with_uri(url)
61
+ end
62
+
63
+ def self.locker
64
+ return @@locker if (@@locker.url rescue false)
65
+ @@locker = nil
66
+ tries = 3
67
+ while @@locker.nil? && tries > 0 do
68
+ sleep 0.2 if tries < 3
69
+ tries -= 1
70
+ reconnect!
71
+ @@locker = nil unless (@@locker.url rescue false)
72
+ end
73
+ raise WithLock::LockException.new("Couldn't connect to locker.") if @@locker.nil?
74
+ @@locker
75
+ end
76
+ end
@@ -0,0 +1,119 @@
1
+ require 'drb'
2
+ require 'daemons'
3
+
4
+ class WithLock::Server
5
+ extend WithLock::Common
6
+
7
+ def self.mutex
8
+ @@mutex ||= Mutex.new
9
+ end
10
+
11
+ def self.owner_uri?(name)
12
+ locks[name][:owner]
13
+ rescue => e
14
+ ''
15
+ end
16
+
17
+ def self.owner_pid(name)
18
+ locks[name][:pid]
19
+ rescue => e
20
+ ''
21
+ end
22
+
23
+ def self.count(name)
24
+ locks[name][:count]
25
+ rescue => e
26
+ 0
27
+ end
28
+
29
+ def self.locked?(name)
30
+ !locks[name].nil?# && owner_active?(name)
31
+ end
32
+
33
+ def self.mine?(owner,name)
34
+ locked?(name) && locks[name][:owner].eql?(owner)
35
+ end
36
+
37
+ def self.get(owner,name,timeout=5)
38
+ endtime = Time.now.to_f + timeout.to_f
39
+ owner_uri, owner_pid = owner.split('|')
40
+ while !mine?(owner,name) && (Time.now.to_f < endtime)
41
+ mutex.synchronize do
42
+ if !locked?(name)
43
+ locks[name] = {owner: owner, count: 1}
44
+ end
45
+ end
46
+ sleep 0.01 unless mine?(owner,name)
47
+ end
48
+ mine?(owner,name)
49
+ end
50
+
51
+ def self.release(owner,name)
52
+ if mine?(owner,name)
53
+ locks.delete(name)
54
+ true
55
+ else
56
+ false
57
+ end
58
+ end
59
+
60
+ def self.increment(owner,name)
61
+ if mine?(owner,name)
62
+ locks[name][:count] += 1
63
+ end
64
+ count(name)
65
+ end
66
+
67
+ def self.decrement(owner,name)
68
+ if mine?(owner,name)
69
+ locks[name][:count] -= 1
70
+ end
71
+ count(name)
72
+ end
73
+
74
+ def self.locks
75
+ @@locks ||= {}
76
+ end
77
+
78
+ def self.write_url(url)
79
+ File.open(File.join(settings['directory'],'with_lock'),'w'){|file| file.write(url)}
80
+ end
81
+
82
+ def self.started?
83
+ pid.to_i > 0 && running?(pid)
84
+ end
85
+
86
+ def self.daemon_settings
87
+ {
88
+ :multiple => false,
89
+ :ontop => false,
90
+ :backtrace => true,
91
+ :log_output => true,
92
+ :monitor => false,
93
+ :dir_mode => :normal,
94
+ :dir => 'tmp/pids'
95
+ }
96
+ end
97
+
98
+ def self.start_service
99
+ return if started?
100
+ FileUtils.rm(pidfile) if File.exists?(pidfile)
101
+ options = daemon_settings.merge(:ARGV => ['start'])
102
+ Daemons.run_proc('with_lock', options) do
103
+ DRb.start_service(WithLock::Server::url,WithLock::Server)
104
+ DRb.thread.join
105
+ end
106
+ end
107
+
108
+ def self.run_service
109
+ return if started?
110
+ DRb.start_service(WithLock::Server::url,WithLock::Server)
111
+ DRb.thread.join
112
+ end
113
+
114
+ def self.stop_service
115
+ return unless started?
116
+ `kill #{pid}`
117
+ FileUtils.rm_f(pidfile)
118
+ end
119
+ end
@@ -0,0 +1,4 @@
1
+ module WithLock
2
+ VERSION = "0.0.4.alpha"
3
+ end
4
+
data/script/with_lock ADDED
@@ -0,0 +1,37 @@
1
+ #!/usr/bin/env ruby
2
+ # -*- encoding: utf-8 -*-
3
+ $:.push File.expand_path(File.join('..','..','lib'), __FILE__)
4
+
5
+ require "rubygems"
6
+ require "bundler"
7
+ Bundler.setup
8
+
9
+ FileUtils.mkdir_p('tmp/pids') unless File.exists?('tmp/pids')
10
+
11
+ require 'with_lock'
12
+ if ARGV.include?('start')
13
+ begin
14
+ locker = WithLock::Client.locker
15
+ rescue WithLock::LockException => e
16
+ puts "Starting WithLock on #{WithLock::Server::url}!"
17
+ WithLock::Server::start_service
18
+ locker = WithLock::Client.locker
19
+ end
20
+ puts "Clearing WithLock locks!"
21
+ locker = WithLock::Client.locker
22
+ locker.locks.each_pair do |lock,data|
23
+ pid = data[:owner].split('|').last
24
+ if locker.running?(pid) || !data[:owner].include?(`hostname`.strip)
25
+ puts "Running - pid"
26
+ else
27
+ puts "Not Running - pid"
28
+ locker.release(data[:owner],lock)
29
+ end
30
+ end
31
+ elsif ARGV.include?('stop')
32
+ puts "Stopping WithLock!"
33
+ WithLock::Server::stop_service
34
+ elsif ARGV.include?('run')
35
+ puts "Running WithLock!"
36
+ WithLock::Server::run_service
37
+ end
@@ -0,0 +1,2 @@
1
+ $:.unshift(File.join(File.dirname(__FILE__),'..','lib'))
2
+ require 'with_lock'
@@ -0,0 +1,2 @@
1
+ #!/bin/bash
2
+ echo $$
@@ -0,0 +1,21 @@
1
+ #!/usr/bin/env ruby
2
+ # -*- encoding: utf-8 -*-
3
+
4
+ $:.push File.expand_path(File.join('..','..','lib'), __FILE__)
5
+
6
+ require "rubygems"
7
+ require "bundler"
8
+ Bundler.setup
9
+
10
+ require 'with_lock'
11
+ include WithLock::Public
12
+
13
+ begin
14
+ with_lock(ARGV[0],ARGV[1].to_f||0.5) do
15
+ sleep ARGV[2].to_f
16
+ Kernel.exit! if ARGV[3].eql?('kernel_exit')
17
+ exit(0) if ARGV[2].eql?('exit')
18
+ end
19
+ rescue WithLock::LockException => e
20
+ puts exit(1)
21
+ end
@@ -0,0 +1,130 @@
1
+ # encoding: utf-8
2
+ require File.expand_path(File.join('..','spec','spec_helper'), File.dirname(__FILE__))
3
+
4
+ describe WithLock do
5
+ describe "#settings" do
6
+ it "should have default settings" do
7
+ WithLock::Client::settings.should == {
8
+ 'url' => 'druby://localhost:9999',
9
+ 'directory' => 'tmp',
10
+ 'scope' => 'with_lock'
11
+ }
12
+ end
13
+ end
14
+
15
+ describe "#url" do
16
+ it "returns the druby url from settings" do
17
+ WithLock::Client::settings['url'].should == WithLock::Client::url
18
+ end
19
+ end
20
+
21
+ describe "#running(pid)" do
22
+ it "should report if given process id represents a running pid" do
23
+ WithLock::Server::running?($$).should be_true
24
+ end
25
+ it "should report if given process id doesn't represent a running pid" do
26
+ pid = `spec/support/echo_pid.sh`.to_s.strip
27
+ sleep 0.2
28
+ WithLock::Server::running?(pid).should be_false
29
+ end
30
+ end
31
+
32
+ describe "#with_lock" do
33
+ it "should raise an exception if with_lock server not started" do
34
+ WithLock::Server.stop_service
35
+ started_trying = Time.now
36
+ while WithLock::Server.started? do
37
+ sleep 0.2
38
+ raise Exception.new("Couldn't stop server!") unless (Time.now - 3.seconds) > started_trying
39
+ end
40
+ error_message = ''
41
+ begin
42
+ with_lock('my_lock') do
43
+ "I should not get here!".should be_nil
44
+ end
45
+ rescue WithLock::LockException => e
46
+ e.message.should == "Couldn't connect to locker."
47
+ end
48
+ end
49
+ describe "when the server is running" do
50
+ before(:all) do
51
+ `script/with_lock start`
52
+ started_trying = Time.now
53
+ while !WithLock::Server.started? do
54
+ sleep 0.2
55
+ raise Exception.new("Couldn't start server!") unless (Time.now - 3.seconds) > started_trying
56
+ end
57
+ @locker = WithLock::Client.locker
58
+ end
59
+ after(:all) do
60
+ `script/with_lock stop`
61
+ while WithLock::Server.started? do
62
+ sleep 0.1
63
+ end
64
+ end
65
+ it "should grab the named lock if its not locked" do
66
+ with_lock('name') do
67
+ WithLock::Client.mine?('name').should be_true
68
+ end
69
+ end
70
+ it "should not allow another process to grab the same named lock" do
71
+ system("spec/support/get_lock.rb name 0.5 10 &")
72
+ sleep 1
73
+ expect {
74
+ with_lock('name',0.5) do
75
+ end
76
+ }.to raise_exception(WithLock::LockException)
77
+ end
78
+
79
+ it "should have a counter of 1 when it first grabs the lock" do
80
+ with_lock('blarg') do
81
+ @locker.count(WithLock::Client.scoped_name('blarg')).should == 1
82
+ end
83
+ end
84
+
85
+ it "should allow the same process to grab the same lock and increment its counter" do
86
+ with_lock('blarg') do
87
+ with_lock('blarg') do
88
+ @locker.count(WithLock::Client.scoped_name('blarg')).should == 2
89
+ end
90
+ end
91
+ end
92
+
93
+ it "should decrement a lock's counter when it ends the block" do
94
+ with_lock('blarg') do
95
+ with_lock('blarg') do
96
+ end
97
+ @locker.count(WithLock::Client.scoped_name('blarg')).should == 1
98
+ end
99
+ end
100
+
101
+ it "should release the lock when the block ends" do
102
+ with_lock('blarg') do
103
+ end
104
+ @locker.locks[WithLock::Client.scoped_name('blarg')].should be_nil
105
+ end
106
+
107
+ it "should release the lock if an exception closes the block" do
108
+ begin
109
+ with_lock('blarg') do
110
+ raise "Blarg!!"
111
+ end
112
+ rescue => e
113
+ end
114
+ @locker.locks[WithLock::Client.scoped_name('blarg')].should be_nil
115
+ end
116
+
117
+ it "should release the lock on a clean exit" do
118
+ `spec/support/get_lock.rb blarg 0.3 exit`
119
+ sleep 0.2
120
+ @locker.locks[WithLock::Client.scoped_name('blarg')].should be_nil
121
+ end
122
+
123
+ it "should release the lock on an immediate exit" do
124
+ `spec/support/get_lock.rb blarg 0.3 kernel_exit`
125
+ sleep 0.2
126
+ @locker.locks[WithLock::Client.scoped_name('blarg')].should be_nil
127
+ end
128
+ end
129
+ end
130
+ end
data/with_lock.gemspec ADDED
@@ -0,0 +1,23 @@
1
+ # -*- encoding: utf-8 -*-
2
+ $:.push File.expand_path("../lib", __FILE__)
3
+ require 'with_lock/version'
4
+
5
+ Gem::Specification.new do |s|
6
+ s.name = "with_lock"
7
+ s.version = WithLock::VERSION
8
+ s.authors = ["Christopher Louis Hauboldt"]
9
+ s.email = ["chris@hauboldt.us"]
10
+ s.homepage = "https://github.com/chrisboy333/with_lock"
11
+ s.summary = %q{Implements named mutexes for ruby applications.}
12
+ s.description = %q{Implements named mutexes for ruby applications by creating a resource server to query for locks.}
13
+
14
+ s.rubyforge_project = "with_lock"
15
+
16
+ s.files = `git ls-files`.split("\n")
17
+ s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
18
+ s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
19
+ s.require_paths = ["lib"]
20
+
21
+ s.add_development_dependency "rspec"
22
+ s.add_dependency "daemons"
23
+ end
metadata ADDED
@@ -0,0 +1,94 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: with_lock
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.4.alpha
5
+ platform: ruby
6
+ authors:
7
+ - Christopher Louis Hauboldt
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2014-10-13 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: rspec
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ! '>='
18
+ - !ruby/object:Gem::Version
19
+ version: '0'
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ! '>='
25
+ - !ruby/object:Gem::Version
26
+ version: '0'
27
+ - !ruby/object:Gem::Dependency
28
+ name: daemons
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ! '>='
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ! '>='
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
41
+ description: Implements named mutexes for ruby applications by creating a resource
42
+ server to query for locks.
43
+ email:
44
+ - chris@hauboldt.us
45
+ executables: []
46
+ extensions: []
47
+ extra_rdoc_files: []
48
+ files:
49
+ - .gitignore
50
+ - .rspec
51
+ - Gemfile
52
+ - Gemfile.lock
53
+ - README.md
54
+ - Rakefile
55
+ - config/with_lock.local.yml
56
+ - config/with_lock.yml
57
+ - lib/with_lock.rb
58
+ - lib/with_lock/client.rb
59
+ - lib/with_lock/server.rb
60
+ - lib/with_lock/version.rb
61
+ - script/with_lock
62
+ - spec/spec_helper.rb
63
+ - spec/support/echo_pid.sh
64
+ - spec/support/get_lock.rb
65
+ - spec/with_lock_spec.rb
66
+ - with_lock.gemspec
67
+ homepage: https://github.com/chrisboy333/with_lock
68
+ licenses: []
69
+ metadata: {}
70
+ post_install_message:
71
+ rdoc_options: []
72
+ require_paths:
73
+ - lib
74
+ required_ruby_version: !ruby/object:Gem::Requirement
75
+ requirements:
76
+ - - ! '>='
77
+ - !ruby/object:Gem::Version
78
+ version: '0'
79
+ required_rubygems_version: !ruby/object:Gem::Requirement
80
+ requirements:
81
+ - - ! '>'
82
+ - !ruby/object:Gem::Version
83
+ version: 1.3.1
84
+ requirements: []
85
+ rubyforge_project: with_lock
86
+ rubygems_version: 2.2.2
87
+ signing_key:
88
+ specification_version: 4
89
+ summary: Implements named mutexes for ruby applications.
90
+ test_files:
91
+ - spec/spec_helper.rb
92
+ - spec/support/echo_pid.sh
93
+ - spec/support/get_lock.rb
94
+ - spec/with_lock_spec.rb