carrot_rpc 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.
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