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 +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
|