officer 0.6.0 → 0.7.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
@@ -18,8 +18,8 @@ Here are some simple examples in case you aren't familiar with it.
18
18
  Officer's help information:
19
19
  sudo officer run -- --help
20
20
 
21
- Run Officer in the foreground with verbose mode enabled (useful for debugging):
22
- sudo officer run -- -v
21
+ Run Officer in the foreground with full logging and statistics:
22
+ sudo officer run -- -l debug -s
23
23
 
24
24
  Run Officer in the background (production mode) and listen on a specific IP and port:
25
25
  sudo officer start -- -h 127.0.0.1 -p 9999
@@ -33,41 +33,63 @@ Run Officer in the background (production mode) and listen on a specific IP and
33
33
  require 'rubygems'
34
34
  require 'officer'
35
35
 
36
- ### Create a client object (defaults to localhost:11500)
36
+ ### Create a client object
37
37
 
38
38
  client = Officer::Client.new :host => 'localhost', :port => 11500
39
39
 
40
+ Options:
41
+
42
+ - :host => Hostname or IP address of the server to bind to (default: 0.0.0.0).
43
+ - :port => TCP Port to listen on (default: 11500).
44
+
45
+
40
46
  ### Lock
41
47
 
42
48
  client.lock 'some_lock_name'
43
49
 
50
+ Options:
51
+
52
+ - :timeout => The number of seconds to wait for a lock to become available (default: wait forever).
53
+ - :namespace => Prepend a namespace to each lock name (default: empty string).
54
+ - :queue_max => If the lock queue length is greater than :queue_max then don't wait for the lock.
55
+
56
+
44
57
  ### Unlock
45
58
 
46
59
  client.unlock 'some_lock_name'
47
60
 
48
- ### Wrap a block of code in a lock/unlock (with optional 5 second timeout)
61
+
62
+ ### Lock a block of code
49
63
 
50
64
  client.with_lock('some_lock_name', :timeout => 5) do
51
65
  puts 'hello world'
52
66
  end
53
67
 
68
+ Options:
69
+
70
+ - Same options as the above Lock command.
71
+
72
+
54
73
  ### Release all locks for this connection
55
74
 
56
75
  client.reset
57
76
 
77
+
58
78
  ### Reconnect (all locks will be released)
59
79
 
60
80
  client.reconnect
61
81
 
62
82
  - Useful if you use Officer with Phusion Passenger and smart spawning. See [Passenger's documentation](http://www.modrails.com/documentation/Users%20guide%20Apache.html#_smart_spawning_gotcha_1_unintential_file_descriptor_sharing) for more information.
63
83
 
64
- ### Locks
84
+
85
+ ### Show locks
65
86
 
66
87
  client.locks
67
88
 
68
89
  - Returns the internal state of all the server's locks.
69
90
 
70
- ### Connections
91
+
92
+ ### Show connections
71
93
 
72
94
  client.connections
73
95
 
@@ -77,7 +99,6 @@ Run Officer in the background (production mode) and listen on a specific IP and
77
99
 
78
100
  - Retrieve the list of locks for the current connection.
79
101
  - Client: Option to abort a lock request if there is already a certain number of clients waiting for the lock.
80
- - Client: Namespaced lock names.
81
102
  - Server: configure the daemons gem to allow multiple server processes to run on one box.
82
103
  - Tests
83
104
 
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.6.0
1
+ 0.7.0
data/bin/officer CHANGED
@@ -38,7 +38,7 @@ def parse_command_line
38
38
  option :stats do
39
39
  short '-s'
40
40
  long '--stats'
41
- desc 'Log stats every 5 seconds (default: off, requires log level: info)'
41
+ desc 'Log stats every 5 seconds (default: off, required log level: info)'
42
42
  end
43
43
 
44
44
  option :help do
@@ -10,12 +10,14 @@ module Officer
10
10
  class AlreadyConnectedError < GenericError; end
11
11
  class LockError < GenericError; end
12
12
  class LockTimeoutError < LockError; end
13
+ class LockQueuedMaxError < LockError; end
13
14
  class UnlockError < GenericError; end
14
15
 
15
16
  class Client
16
17
  def initialize options={}
17
18
  @host = options[:host] || 'localhost'
18
19
  @port = options[:port] || 11500
20
+ @namespace = options[:namespace]
19
21
 
20
22
  connect
21
23
  end
@@ -26,11 +28,12 @@ module Officer
26
28
  end
27
29
 
28
30
  def lock name, options={}
29
- execute :command => 'lock', :name => name, :timeout => options[:timeout]
31
+ execute :command => 'lock', :name => name_with_ns(name),
32
+ :timeout => options[:timeout], :queue_max => options[:queue_max]
30
33
  end
31
34
 
32
35
  def unlock name
33
- execute :command => 'unlock', :name => name
36
+ execute :command => 'unlock', :name => name_with_ns(name)
34
37
  end
35
38
 
36
39
  def with_lock name, options={}
@@ -38,6 +41,7 @@ module Officer
38
41
  result = response['result']
39
42
 
40
43
  raise LockTimeoutError if result == 'timed_out'
44
+ raise LockQueuedMaxError if result == 'queue_maxed'
41
45
  raise LockError unless %w(acquired already_acquired).include?(result)
42
46
 
43
47
  begin
@@ -85,6 +89,10 @@ module Officer
85
89
  reconnect
86
90
  raise
87
91
  end
92
+
93
+ def name_with_ns name
94
+ @namespace ? "#{@namespace}:#{name}" : name
95
+ end
88
96
  end
89
97
 
90
98
  end
@@ -68,18 +68,21 @@ module Officer
68
68
  register
69
69
 
70
70
  def execute
71
- Officer::LockStore.instance.acquire @name, @connection, :timeout => @timeout
71
+ Officer::LockStore.instance.acquire @name, @connection,
72
+ :timeout => @timeout, :queue_max => @queue_max
72
73
  end
73
74
 
74
75
  private
75
76
  def setup
76
77
  @name = @request['name']
77
78
  @timeout = @request['timeout']
79
+ @queue_max = @request['queue_max']
78
80
  end
79
81
 
80
82
  def valid?
81
83
  require_string @request['name']
82
84
  optional_positive_integer @request['timeout']
85
+ optional_positive_integer @request['queue_max']
83
86
  end
84
87
  end
85
88
 
@@ -77,6 +77,10 @@ module Officer
77
77
  def connections conns_hash
78
78
  send_result 'connections', :value => conns_hash
79
79
  end
80
+
81
+ def queue_maxed name
82
+ send_result 'queue_maxed', :name => name
83
+ end
80
84
  end
81
85
 
82
86
  class Connection < EventMachine::Protocols::LineAndTextProtocol
@@ -46,6 +46,15 @@ module Officer
46
46
  end
47
47
 
48
48
  def acquire name, connection, options={}
49
+ if options[:queue_max]
50
+ if @locks[name] && !@locks[name].queue.include?(connection)
51
+ if @locks[name].queue.length >= options[:queue_max]
52
+ connection.queue_maxed name
53
+ return
54
+ end
55
+ end
56
+ end
57
+
49
58
  @acquire_counter += 1
50
59
 
51
60
  lock = @locks[name] ||= Lock.new(name)
data/officer.gemspec CHANGED
@@ -5,7 +5,7 @@
5
5
 
6
6
  Gem::Specification.new do |s|
7
7
  s.name = %q{officer}
8
- s.version = "0.6.0"
8
+ s.version = "0.7.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"]
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.6.0
4
+ version: 0.7.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Chad Remesch