officer 0.2.2 → 0.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.
data/README.markdown CHANGED
@@ -5,8 +5,8 @@ It is implemented using Ruby and Eventmachine. Inspiration comes from [elock](ht
5
5
 
6
6
  ## Installation
7
7
 
8
- install gemcutter
9
- gem install officer
8
+ gem install gemcutter
9
+ gem install officer
10
10
 
11
11
  ## Usage
12
12
 
@@ -47,7 +47,6 @@ All debugging output goes to stdout for now.
47
47
 
48
48
  ## Planned Features
49
49
 
50
- - Properly handle nested with_lock() blocks.
51
50
  - Option to abort a lock request if there is already a certain number of clients waiting for the lock.
52
51
  - Lock statistics.
53
52
  - Retrieve the complete list of locks.
data/Rakefile CHANGED
@@ -12,7 +12,8 @@ begin
12
12
  gem.authors = ["Chad Remesch"]
13
13
  gem.add_development_dependency "eventmachine", ">= 0"
14
14
  gem.add_development_dependency "json", ">= 0"
15
- gem.add_development_dependency "active_support", ">= 0"
15
+ gem.add_development_dependency "activesupport", ">= 0"
16
+ gem.add_development_dependency "daemons", ">= 0"
16
17
  # gem is a Gem::Specification... see http://www.rubygems.org/read/chapter/20 for additional settings
17
18
  end
18
19
  Jeweler::GemcutterTasks.new
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.2.2
1
+ 0.3.0
data/bin/officer CHANGED
@@ -1,7 +1,15 @@
1
1
  #!/usr/bin/env ruby
2
2
 
3
- Dir.chdir File.dirname(__FILE__) + '/../lib'
4
-
3
+ require 'rubygems'
5
4
  require 'officer'
6
5
 
7
- Officer::Server.new.run
6
+ options = {
7
+ :dir_mode => :system,
8
+ :multiple => false,
9
+ :monitor => true
10
+ }
11
+
12
+
13
+ Daemons.run_proc('officer', options) do
14
+ Officer::Server.new.run
15
+ end
@@ -42,13 +42,16 @@ module Officer
42
42
  result = response['result']
43
43
 
44
44
  raise LockTimeoutError if result == 'timed_out'
45
- raise LockError if result != 'acquired'
45
+ raise LockError unless %w(acquired already_acquired).include?(result)
46
46
 
47
47
  begin
48
48
  yield
49
49
  ensure
50
- response = unlock name
51
- raise UnlockError unless response['result'] == 'released'
50
+ # Deal with nested with_lock calls. Only the outer most call should tell the server to unlock.
51
+ if result == 'acquired'
52
+ response = unlock name
53
+ raise UnlockError unless response['result'] == 'released'
54
+ end
52
55
  end
53
56
  end
54
57
 
@@ -57,7 +57,6 @@ module Officer
57
57
  register
58
58
 
59
59
  def execute
60
- L.debug 'executing lock command.'
61
60
  Officer::LockStore.instance.acquire @name, @connection, :timeout => @timeout
62
61
  end
63
62
 
@@ -77,7 +76,6 @@ module Officer
77
76
  register
78
77
 
79
78
  def execute
80
- L.debug 'executing unlock command.'
81
79
  Officer::LockStore.instance.release @name, @connection
82
80
  end
83
81
 
@@ -95,7 +93,6 @@ module Officer
95
93
  register
96
94
 
97
95
  def execute
98
- L.debug 'executing reset command.'
99
96
  Officer::LockStore.instance.reset @connection
100
97
  end
101
98
  end
@@ -3,8 +3,6 @@ module Officer
3
3
 
4
4
  module EmCallbacks
5
5
  def post_init
6
- L.debug "Client connected."
7
-
8
6
  @connected = true
9
7
  @timers = {} # name => Timer
10
8
  end
@@ -12,8 +10,6 @@ module Officer
12
10
  def receive_line line
13
11
  line.chomp!
14
12
 
15
- L.debug "Received line: #{line}"
16
-
17
13
  command = Officer::Command::Factory.create line, self
18
14
  command.execute
19
15
 
@@ -25,43 +21,35 @@ module Officer
25
21
  def unbind
26
22
  @connected = false
27
23
 
28
- L.debug "client disconnected."
29
-
30
24
  Officer::LockStore.instance.reset self
31
25
  end
32
26
  end
33
27
 
34
28
  module LockCallbacks
35
29
  def acquired name
36
- L.debug "acquired lock: #{name}"
37
-
38
30
  @timers.delete(name).cancel if @timers[name]
39
31
 
40
32
  send_line({:result => 'acquired', :name => name}.to_json)
41
33
  end
42
34
 
43
- def released name
44
- L.debug "released lock: #{name}"
35
+ def already_acquired name
36
+ send_line({:result => 'already_acquired', :name => name}.to_json)
37
+ end
45
38
 
39
+ def released name
46
40
  send_line({:result => 'released', :name => name}.to_json)
47
41
  end
48
42
 
49
43
  def release_failed name
50
- L.debug "release lock failed: #{name}"
51
-
52
44
  send_line({:result => 'release_failed', :name => name}.to_json)
53
45
  end
54
46
 
55
47
  def reset_succeeded
56
- L.debug "reset"
57
-
58
48
  @timers.values.each {|timer| timer.cancel}
59
49
  send_line({:result => 'reset_succeeded'}.to_json)
60
50
  end
61
51
 
62
52
  def queued name, options={}
63
- L.debug "queued. options=#{options.inspect}"
64
-
65
53
  timeout = options[:timeout]
66
54
 
67
55
  return if timeout.nil? || @timers[name]
@@ -72,8 +60,6 @@ module Officer
72
60
  end
73
61
 
74
62
  def timed_out name
75
- L.debug "Timed out connection=#{object_id}, name=#{name}"
76
-
77
63
  @timers.delete name
78
64
  send_line({:result => 'timed_out', :name => name}.to_json)
79
65
  end
@@ -16,40 +16,47 @@ module Officer
16
16
  def initialize
17
17
  @locks = {} # name => Lock
18
18
  @connections = {} # Connection => Set(name, ...)
19
+ @acquire_counter = 0
19
20
  end
20
21
 
21
22
  def log_state
22
- L.debug '-----'
23
+ L.info '-----'
23
24
 
24
- L.debug 'LOCK STORE:'
25
- puts
25
+ L.info 'LOCK STORE:'
26
+ L.info ''
26
27
 
27
- puts "locks:"
28
+ L.info "locks:"
28
29
  @locks.each do |name, lock|
29
- puts "#{name}: connections=[#{lock.queue.map{|c| c.object_id}.join(', ')}]"
30
+ L.info "#{name}: connections=[#{lock.queue.map{|c| c.object_id}.join(', ')}]"
30
31
  end
31
- puts
32
+ L.info ''
32
33
 
33
- puts "Connections:"
34
+ L.info "Connections:"
34
35
  @connections.each do |connection, names|
35
- puts "#{connection.object_id}: names=[#{names.to_a.join(', ')}]"
36
+ L.info "#{connection.object_id}: names=[#{names.to_a.join(', ')}]"
36
37
  end
37
- puts
38
+ L.info ''
38
39
 
39
- L.debug '-----'
40
+ L.info "Acquire Rate: #{@acquire_counter.to_f / 5}/s"
41
+ @acquire_counter = 0
42
+ L.info ''
43
+
44
+ L.info '-----'
40
45
  end
41
46
 
42
47
  def acquire name, connection, options={}
48
+ @acquire_counter += 1
49
+
43
50
  lock = @locks[name] ||= Lock.new(name)
44
51
 
45
- lock.queue << connection unless lock.queue.include? connection
52
+ if lock.queue.include? connection
53
+ lock.queue.first == connection ? connection.already_acquired(name) : connection.queued(name, options)
46
54
 
47
- (@connections[connection] ||= Set.new) << name
48
-
49
- if lock.queue.first == connection
50
- connection.acquired name
51
55
  else
52
- connection.queued name, options
56
+ lock.queue << connection
57
+ (@connections[connection] ||= Set.new) << name
58
+
59
+ lock.queue.count == 1 ? connection.acquired(name) : connection.queued(name, options)
53
60
  end
54
61
  end
55
62
 
data/lib/officer/log.rb CHANGED
@@ -4,7 +4,15 @@ module Officer
4
4
  include Singleton
5
5
 
6
6
  def debug message
7
- puts message
7
+ return unless [:debug].include?(LOG_LEVEL)
8
+
9
+ write message
10
+ end
11
+
12
+ def info message
13
+ return unless [:debug, :info].include?(LOG_LEVEL)
14
+
15
+ write message
8
16
  end
9
17
 
10
18
  def debug_exception e
@@ -14,8 +22,14 @@ module Officer
14
22
  debug e.backtrace.join "\n "
15
23
  debug '-----'
16
24
  end
25
+
26
+ private
27
+ def write message
28
+ puts message
29
+ end
17
30
  end
18
31
 
19
32
  end
20
33
 
21
- L = Officer::Log.instance
34
+ L = Officer::Log.instance
35
+ LOG_LEVEL = :info
@@ -17,7 +17,7 @@ module Officer
17
17
  EM::PeriodicTimer.new(5) do
18
18
  Officer::LockStore.instance.log_state
19
19
  end
20
-
20
+
21
21
  EM::start_server @host, @port, Connection::Connection
22
22
  end
23
23
  end
data/lib/officer.rb CHANGED
@@ -7,6 +7,7 @@ require 'rubygems'
7
7
  require 'active_support'
8
8
  require 'eventmachine'
9
9
  require 'json'
10
+ require 'daemons'
10
11
 
11
12
  # Application.
12
13
  require 'officer/log'
data/officer.gemspec CHANGED
@@ -5,11 +5,11 @@
5
5
 
6
6
  Gem::Specification.new do |s|
7
7
  s.name = %q{officer}
8
- s.version = "0.2.2"
8
+ s.version = "0.3.0"
9
9
 
10
10
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
11
  s.authors = ["Chad Remesch"]
12
- s.date = %q{2010-02-03}
12
+ s.date = %q{2010-02-07}
13
13
  s.default_executable = %q{officer}
14
14
  s.description = %q{Distributed lock server and client written in Ruby and EventMachine}
15
15
  s.email = %q{chad@remesch.com}
@@ -54,16 +54,19 @@ Gem::Specification.new do |s|
54
54
  if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then
55
55
  s.add_development_dependency(%q<eventmachine>, [">= 0"])
56
56
  s.add_development_dependency(%q<json>, [">= 0"])
57
- s.add_development_dependency(%q<active_support>, [">= 0"])
57
+ s.add_development_dependency(%q<activesupport>, [">= 0"])
58
+ s.add_development_dependency(%q<daemons>, [">= 0"])
58
59
  else
59
60
  s.add_dependency(%q<eventmachine>, [">= 0"])
60
61
  s.add_dependency(%q<json>, [">= 0"])
61
- s.add_dependency(%q<active_support>, [">= 0"])
62
+ s.add_dependency(%q<activesupport>, [">= 0"])
63
+ s.add_dependency(%q<daemons>, [">= 0"])
62
64
  end
63
65
  else
64
66
  s.add_dependency(%q<eventmachine>, [">= 0"])
65
67
  s.add_dependency(%q<json>, [">= 0"])
66
- s.add_dependency(%q<active_support>, [">= 0"])
68
+ s.add_dependency(%q<activesupport>, [">= 0"])
69
+ s.add_dependency(%q<daemons>, [">= 0"])
67
70
  end
68
71
  end
69
72
 
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: officer
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.2
4
+ version: 0.3.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Chad Remesch
@@ -9,7 +9,7 @@ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
11
 
12
- date: 2010-02-03 00:00:00 -05:00
12
+ date: 2010-02-07 00:00:00 -05:00
13
13
  default_executable: officer
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
@@ -33,7 +33,17 @@ dependencies:
33
33
  version: "0"
34
34
  version:
35
35
  - !ruby/object:Gem::Dependency
36
- name: active_support
36
+ name: activesupport
37
+ type: :development
38
+ version_requirement:
39
+ version_requirements: !ruby/object:Gem::Requirement
40
+ requirements:
41
+ - - ">="
42
+ - !ruby/object:Gem::Version
43
+ version: "0"
44
+ version:
45
+ - !ruby/object:Gem::Dependency
46
+ name: daemons
37
47
  type: :development
38
48
  version_requirement:
39
49
  version_requirements: !ruby/object:Gem::Requirement