carrot_rpc 0.6.0 → 0.7.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: b377cb46e74db89d8b6bcd97d305a26a0964d539
4
- data.tar.gz: 266101d5211ce7409438a958dc5f9629e20cd43e
3
+ metadata.gz: 3aa31c8e652cfb85ca9ac63bfaff6139a0a76363
4
+ data.tar.gz: 54258fe17ecb45ff2fcfb35438cc5247c38087c6
5
5
  SHA512:
6
- metadata.gz: 4b42e357b5212e94d321a9ef2448567f23d905330a931218046f5920a39c818dadf20f3ad940d20da7b63841bb0a9e97595b911da978ae78d6305fa12c1b8dd7
7
- data.tar.gz: a23da7aca020a9b0dfc1e17a521aea69a2675db343a1065c152b628d72d90e04c47655c8a6f9b218480174e16bb282112ab6664decd22ad6ec7b0bde07a51b07
6
+ metadata.gz: 8b6f9404881d86dbecbc93ca34c717e6b3b173e71e4a35a2bf5925554397cf87307f74a87765c80d7e509999766c0422a3e9eee79667357dd66b214dcfc05be0
7
+ data.tar.gz: c628f3b026f123530d3abe3ba5f5b5b49464a38e84814a06df73915d130b7f254caf98cd539852d3b13e4c8363cd1a7ba1316f0bc74fb0fcaab341ef602cd5fb
data/CHANGELOG.md CHANGED
@@ -3,43 +3,55 @@
3
3
  **Table of Contents** *generated with [DocToc](https://github.com/thlorenz/doctoc)*
4
4
 
5
5
  - [Changelog](#changelog)
6
- - [v0.5.1](#v051)
6
+ - [v0.7.0](#v070)
7
7
  - [Bug Fixes](#bug-fixes)
8
- - [v0.5.0](#v050)
9
- - [Enhancements](#enhancements)
10
8
  - [Incompatible Changes](#incompatible-changes)
11
- - [v0.4.1](#v041)
9
+ - [v0.6.0](#v060)
10
+ - [Enhancements](#enhancements)
11
+ - [v0.5.1](#v051)
12
12
  - [Bug Fixes](#bug-fixes-1)
13
- - [v0.4.0](#v040)
13
+ - [v0.5.0](#v050)
14
14
  - [Enhancements](#enhancements-1)
15
- - [Bug Fixes](#bug-fixes-2)
16
15
  - [Incompatible Changes](#incompatible-changes-1)
17
- - [v0.3.0](#v030)
16
+ - [v0.4.1](#v041)
17
+ - [Bug Fixes](#bug-fixes-2)
18
+ - [v0.4.0](#v040)
18
19
  - [Enhancements](#enhancements-2)
19
20
  - [Bug Fixes](#bug-fixes-3)
20
- - [v0.2.3](#v023)
21
+ - [Incompatible Changes](#incompatible-changes-2)
22
+ - [v0.3.0](#v030)
21
23
  - [Enhancements](#enhancements-3)
22
24
  - [Bug Fixes](#bug-fixes-4)
25
+ - [v0.2.3](#v023)
26
+ - [Enhancements](#enhancements-4)
27
+ - [Bug Fixes](#bug-fixes-5)
23
28
  - [Upgrading](#upgrading)
24
29
  - [v0.2.1](#v021)
25
- - [Bug Fixes](#bug-fixes-5)
26
- - [v0.2.0](#v020)
27
- - [Enhancements](#enhancements-4)
28
30
  - [Bug Fixes](#bug-fixes-6)
29
- - [Incompatible Changes](#incompatible-changes-2)
30
- - [v0.1.2](#v012)
31
+ - [v0.2.0](#v020)
31
32
  - [Enhancements](#enhancements-5)
32
33
  - [Bug Fixes](#bug-fixes-7)
33
- - [v0.1.1](#v011)
34
+ - [Incompatible Changes](#incompatible-changes-3)
35
+ - [v0.1.2](#v012)
34
36
  - [Enhancements](#enhancements-6)
35
37
  - [Bug Fixes](#bug-fixes-8)
36
- - [Incompatible Changes](#incompatible-changes-3)
38
+ - [v0.1.1](#v011)
39
+ - [Enhancements](#enhancements-7)
40
+ - [Bug Fixes](#bug-fixes-9)
41
+ - [Incompatible Changes](#incompatible-changes-4)
37
42
 
38
43
  <!-- END doctoc generated TOC please keep comment here to allow auto update -->
39
44
 
40
45
  # Changelog
41
46
  All significant changes in the project are documented here.
42
47
 
48
+ ## v0.7.0
49
+ ### Bug Fixes
50
+ * [#38](https://github.com/C-S-D/carrot_rpc/pull/38) - The `until quit` busy-wait loop consumes ~1 core for each instance of `carrot_rpc` as the default `sleep 0` does the minimal amount of sleep before waking up to check the boolean `quit`. I've replaced it with an `IO.pipe` and `IO.select` that does not consume any resources while it waits. **NOTE: A Queue could not be used here because the MRI VM blocks use of Mutexes inside signal handlers to prevent deadlocks because the Mutex code is not-reentrant (i.e signal-interrupt-safe). If a Queue is used the thread silently fails with an exception and the signal is ignored.** - [@KronicDeth](https://github.com/KronicDeth)
51
+
52
+ ### Incompatible Changes
53
+ * [#38](https://github.com/C-S-D/carrot_rpc/pull/38) - Removal of the busy-wait removes the `-s` (`--runloop_sleep`) option as it is no longer needed. - [@KronicDeth](https://github.com/KronicDeth)
54
+
43
55
  ## v0.6.0
44
56
  ### Enhancements
45
57
  * [#34](https://github.com/C-S-D/carrot_rpc/pull/34) - `--server_test_mode` options for `carrot_rpc` sets `CarrotRpc.configuration.server_test_mode` to `true`. When `server_test_mode` is true, `_test` is appended to the queue name used by `CarrotRpc::RpcServer` and `CarrotRpc::RpcClient`, so that tests don't use the same queue as production or development. - [@shamil614](https://github.com/C-S-D/carrot_rpc/pull/34)
data/README.md CHANGED
@@ -10,6 +10,7 @@
10
10
  - [Usage](#usage)
11
11
  - [Writing Servers](#writing-servers)
12
12
  - [Writing Clients](#writing-clients)
13
+ - [Using request threading in clients](#using-request-threading-in-clients)
13
14
  - [Support for JSONAPI::Resources](#support-for-jsonapiresources)
14
15
  - [Development](#development)
15
16
  - [Contributing](#contributing)
@@ -55,7 +56,6 @@ Usage: server [options]
55
56
  Process options:
56
57
  -d, --daemonize run daemonized in the background (default: false)
57
58
  --pidfile PIDFILE the pid filename
58
- -s, --runloop_sleep VALUE Configurable sleep time in the runloop
59
59
  --autoload_rails VALUE loads rails env by default. Uses Rails Logger by default.
60
60
  --logfile VALUE relative path and name for Log file. Overrides Rails logger.
61
61
  --loglevel VALUE levels of loggin: DEBUG < INFO < WARN < ERROR < FATAL < UNKNOWN
@@ -98,7 +98,6 @@ CarrotRpc.configure do |config|
98
98
  # Don't use. Server implementation only. The values below are set via CLI:
99
99
  # config.logfile = nil
100
100
  # config.pidfile = nil
101
- # config.runloop_sleep = 0
102
101
  # config.thread_request_variable = nil
103
102
  end
104
103
  ```
data/bin/carrot_rpc CHANGED
@@ -14,6 +14,5 @@ end
14
14
  config = CarrotRpc.configuration
15
15
  config.bunny.start
16
16
 
17
- runner = CarrotRpc::ServerRunner.new(pidfile: config.pidfile, runloop_sleep: config.runloop_sleep,
18
- daemonize: config.daemonize)
17
+ runner = CarrotRpc::ServerRunner.new(pidfile: config.pidfile, daemonize: config.daemonize)
19
18
  runner.run!
@@ -34,10 +34,6 @@ module CarrotRpc::CLI
34
34
  CarrotRpc.configuration.pidfile = value
35
35
  end
36
36
 
37
- option_parser.on("-s", "--runloop_sleep VALUE", Float, "Configurable sleep time in the runloop") do |value|
38
- CarrotRpc.configuration.runloop_sleep = value
39
- end
40
-
41
37
  stm_msg = "runs servers with '_test' appended to queue names." \
42
38
  "Set Rails Rack env vars to 'test' when used in conjunction with '--autoload_rails'"
43
39
  option_parser.on(" ", "--server_test_mode", stm_msg) do
@@ -1,6 +1,6 @@
1
1
  # Global configuration for {CarrotRpc}. Access with {CarrotRpc.configuration}.
2
2
  class CarrotRpc::Configuration
3
- attr_accessor :logger, :logfile, :loglevel, :daemonize, :pidfile, :runloop_sleep, :autoload_rails, :bunny,
3
+ attr_accessor :logger, :logfile, :loglevel, :daemonize, :pidfile, :autoload_rails, :bunny,
4
4
  :before_request, :rpc_client_timeout, :rpc_client_response_key_format, :rpc_client_request_key_format,
5
5
  :server_test_mode, :client_test_mode, :thread_request_variable
6
6
 
@@ -12,7 +12,6 @@ class CarrotRpc::Configuration
12
12
  @logger = nil
13
13
  @daemonize = false
14
14
  @pidfile = nil
15
- @runloop_sleep = 0
16
15
  @autoload_rails = true
17
16
  @bunny = nil
18
17
  @before_request = nil
@@ -0,0 +1,60 @@
1
+ # Stores a signal and allows for it to be waited on
2
+ class CarrotRpc::ServerRunner::Signal
3
+ #
4
+ # Attributes
5
+ #
6
+
7
+ attr_reader :name
8
+
9
+ def initialize
10
+ self.reader, self.writer = IO.pipe
11
+ end
12
+
13
+ #
14
+ # Instance Methods
15
+ #
16
+
17
+ # Traps all {CarrotRpc::ServerRunner::Signals}.
18
+ #
19
+ # @return [void]
20
+ def trap
21
+ CarrotRpc::ServerRunner::Signals.trap do |name|
22
+ # @note can't log from a trap context: since Ruby 2.0 traps don't allow mutexes as it could lead to a dead lock,
23
+ # so `logger.info` here would return "log writing failed. can't be called from trap context"
24
+ receive(name)
25
+ end
26
+ end
27
+
28
+ # Waits for a signal trapped by {#trap} to be received.
29
+ #
30
+ # @return [String]
31
+ def wait
32
+ loop do
33
+ # Wait {#receive}. IO.select can wake up
34
+ read_ready, _write_ready, _error_ready = IO.select([reader])
35
+
36
+ next unless read_ready.include? reader
37
+
38
+ reader.read_nonblock(1)
39
+
40
+ break name
41
+ end
42
+ end
43
+
44
+ private
45
+
46
+ attr_writer :name
47
+
48
+ attr_accessor :reader,
49
+ :writer
50
+
51
+ # Sets `name` as the received signal
52
+ #
53
+ # @param name [String] name of the signal that was received from the trap
54
+ # @return [void]
55
+ def receive(name)
56
+ self.name = name
57
+ # any single byte works
58
+ writer.write_nonblock(".")
59
+ end
60
+ end
@@ -7,11 +7,13 @@ class CarrotRpc::ServerRunner
7
7
  autoload :AutoloadRails
8
8
  autoload :Logger
9
9
  autoload :Pid
10
+ autoload :Signal
10
11
  autoload :Signals
11
12
 
12
13
  # Attributes
13
14
 
14
- attr_reader :quit, :servers
15
+ attr_reader :signal,
16
+ :servers
15
17
 
16
18
  # @return [CarrotRpc::ServerRunner::Pid]
17
19
  attr_reader :pid
@@ -19,13 +21,13 @@ class CarrotRpc::ServerRunner
19
21
  # Methods
20
22
 
21
23
  # Instantiate the ServerRunner.
22
- def initialize(rails_path: ".", pidfile: nil, runloop_sleep: 0, daemonize: false)
23
- @runloop_sleep = runloop_sleep
24
+ def initialize(rails_path: ".", pidfile: nil, daemonize: false)
25
+ self.signal = CarrotRpc::ServerRunner::Signal.new
26
+
24
27
  @daemonize = daemonize
25
28
  @servers = []
26
29
 
27
30
  CarrotRpc::ServerRunner::AutoloadRails.conditionally_load_root(rails_path, logger: logger)
28
- trap_signals
29
31
 
30
32
  @pid = CarrotRpc::ServerRunner::Pid.new(
31
33
  path: pidfile,
@@ -35,24 +37,20 @@ class CarrotRpc::ServerRunner
35
37
 
36
38
  # Start the servers and the run loop.
37
39
  def run!
40
+ signal.trap
41
+
38
42
  pid.check
39
43
  daemonize && suppress_output if daemonize?
40
44
  pid.ensure_written
41
45
 
42
46
  # Initialize the servers. Set logger.
43
47
  run_servers
44
-
45
- # Sleep for a split second.
46
- until quit
47
- sleep @runloop_sleep
48
- end
49
- # When runtime gets here, quit signal is received.
50
- stop_servers
48
+ stop_servers(signal.wait)
51
49
  end
52
50
 
53
51
  # Shutdown all servers defined.
54
- def stop_servers
55
- logger.info "#{@siginal_name} signal received!"
52
+ def stop_servers(signal_name)
53
+ logger.info "#{signal_name} signal received!"
56
54
  @servers.each do |s|
57
55
  logger.info "Shutting Down Server Queue: #{s.server_queue.name}"
58
56
  s.channel.close
@@ -130,23 +128,10 @@ class CarrotRpc::ServerRunner
130
128
  $stdout.reopen($stderr)
131
129
  end
132
130
 
133
- # Set a value to signal shutdown.
134
- def shutdown(name)
135
- @signal_name = name
136
- @quit = true
137
- end
138
-
139
- # Handle signal events.
140
- def trap_signals
141
- CarrotRpc::ServerRunner::Signals.trap do |name|
142
- # @note can't log from a trap context: since Ruby 2.0 traps don't allow mutexes as it could lead to a dead lock,
143
- # so `logger.info` here would return "log writing failed. can't be called from trap context"
144
- shutdown(name)
145
- end
146
- end
147
-
148
131
  private
149
132
 
133
+ attr_writer :signal
134
+
150
135
  # Determine how to create logger. Config can specify log file.
151
136
  def set_logger
152
137
  logger = CarrotRpc::ServerRunner::Logger.configured
@@ -154,4 +139,17 @@ class CarrotRpc::ServerRunner
154
139
 
155
140
  logger
156
141
  end
142
+
143
+ def wait_for_shutdown
144
+ loop do
145
+ # Wait for quit message
146
+ read_ready, _write_ready, _error_ready = IO.select([shutdown_reader])
147
+
148
+ next unless read_ready.include? shutdown_reader
149
+
150
+ shutdown_reader.read_nonblock(1)
151
+ # When runtime gets here, quit signal is received.
152
+ stop_servers
153
+ end
154
+ end
157
155
  end
@@ -1,3 +1,3 @@
1
1
  module CarrotRpc
2
- VERSION = "0.6.0".freeze
2
+ VERSION = "0.7.0".freeze
3
3
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: carrot_rpc
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
  - Scott Hamilton
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2016-07-17 00:00:00.000000000 Z
12
+ date: 2016-08-08 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: activesupport
@@ -170,6 +170,7 @@ files:
170
170
  - lib/carrot_rpc/server_runner/autoload_rails.rb
171
171
  - lib/carrot_rpc/server_runner/logger.rb
172
172
  - lib/carrot_rpc/server_runner/pid.rb
173
+ - lib/carrot_rpc/server_runner/signal.rb
173
174
  - lib/carrot_rpc/server_runner/signals.rb
174
175
  - lib/carrot_rpc/tagged_log.rb
175
176
  - lib/carrot_rpc/version.rb