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 +4 -4
- data/CHANGELOG.md +27 -15
- data/README.md +1 -2
- data/bin/carrot_rpc +1 -2
- data/lib/carrot_rpc/cli.rb +0 -4
- data/lib/carrot_rpc/configuration.rb +1 -2
- data/lib/carrot_rpc/server_runner/signal.rb +60 -0
- data/lib/carrot_rpc/server_runner.rb +26 -28
- data/lib/carrot_rpc/version.rb +1 -1
- metadata +3 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 3aa31c8e652cfb85ca9ac63bfaff6139a0a76363
|
4
|
+
data.tar.gz: 54258fe17ecb45ff2fcfb35438cc5247c38087c6
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
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.
|
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.
|
9
|
+
- [v0.6.0](#v060)
|
10
|
+
- [Enhancements](#enhancements)
|
11
|
+
- [v0.5.1](#v051)
|
12
12
|
- [Bug Fixes](#bug-fixes-1)
|
13
|
-
- [v0.
|
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.
|
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
|
-
|
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
|
-
|
30
|
-
- [v0.1.2](#v012)
|
31
|
+
- [v0.2.0](#v020)
|
31
32
|
- [Enhancements](#enhancements-5)
|
32
33
|
- [Bug Fixes](#bug-fixes-7)
|
33
|
-
|
34
|
+
- [Incompatible Changes](#incompatible-changes-3)
|
35
|
+
- [v0.1.2](#v012)
|
34
36
|
- [Enhancements](#enhancements-6)
|
35
37
|
- [Bug Fixes](#bug-fixes-8)
|
36
|
-
|
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,
|
18
|
-
daemonize: config.daemonize)
|
17
|
+
runner = CarrotRpc::ServerRunner.new(pidfile: config.pidfile, daemonize: config.daemonize)
|
19
18
|
runner.run!
|
data/lib/carrot_rpc/cli.rb
CHANGED
@@ -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, :
|
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 :
|
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,
|
23
|
-
|
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 "#{
|
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
|
data/lib/carrot_rpc/version.rb
CHANGED
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.
|
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-
|
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
|