officer 0.6.0 → 0.7.0

Sign up to get free protection for your applications and to get access to all the features.
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