ichannel 6.1.1.1 → 7.0.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.
- data/ChangeLog.txt +26 -12
- data/README.md +44 -49
- data/ichannel.gemspec +1 -2
- data/lib/ichannel.rb +3 -3
- data/lib/ichannel/redis.rb +8 -9
- data/lib/ichannel/unix_socket.rb +2 -14
- data/lib/ichannel/version.rb +1 -1
- data/test/ichannel_redis_test.rb +5 -2
- data/test/ichannel_unix_test.rb +11 -20
- metadata +6 -6
data/ChangeLog.txt
CHANGED
@@ -1,3 +1,17 @@
|
|
1
|
+
== v7.0.0
|
2
|
+
- IChannel::UNIXSocket#get! raises Timeout::Error
|
3
|
+
When a read does not complete in time a Timeout::Error will be
|
4
|
+
raised (IChannel::Redis#get! already has this behavior).
|
5
|
+
|
6
|
+
- IChannel::Redis#get is a blocking read.
|
7
|
+
IChannel::Redis#get now blocks on read(by using the BRPOP command)
|
8
|
+
|
9
|
+
- Remove serialization support for IChannel::UNIXSocket.
|
10
|
+
The support is severely limited and the source of too many
|
11
|
+
edge cases to continue support. Even if serialization was
|
12
|
+
limited to a single machine it only works under specific
|
13
|
+
circumstances.
|
14
|
+
|
1
15
|
== v6.1.1.1
|
2
16
|
- Documentation improvements
|
3
17
|
|
@@ -24,15 +38,15 @@
|
|
24
38
|
- IChannel::UNIXSocket can now be serialized by Marshal.
|
25
39
|
IChannel::UNIXSocket can be serialized by Marshal but there's a gotcha: it
|
26
40
|
only really works on the same machine between one or more Ruby processes.
|
27
|
-
The UNIXSocket#marshal_dump method is implemented to dump the FDs in an array,
|
28
|
-
so this feature won't fair well across different machines or time but I've
|
41
|
+
The UNIXSocket#marshal_dump method is implemented to dump the FDs in an array,
|
42
|
+
so this feature won't fair well across different machines or time but I've
|
29
43
|
found this feature useful nonetheless.
|
30
44
|
|
31
45
|
- add IChannel.unix(…)
|
32
46
|
Returns an instance of IChannel::UNIXSocket.
|
33
47
|
|
34
48
|
- add IChannel::UNIXSocket
|
35
|
-
rename IChannel as IChannel::UNIXSocket in preparation for multiple
|
49
|
+
rename IChannel as IChannel::UNIXSocket in preparation for multiple
|
36
50
|
backends(UNIXSocket, Redis, …).
|
37
51
|
|
38
52
|
== v5.2.0
|
@@ -50,29 +64,29 @@
|
|
50
64
|
|
51
65
|
== v5.1.0
|
52
66
|
- Remove restriction on size of message.
|
53
|
-
IChannel#get can read a message of any size(before hand it was limited to
|
67
|
+
IChannel#get can read a message of any size(before hand it was limited to
|
54
68
|
1MB in size). Thanks to @quezacoatl.
|
55
69
|
|
56
70
|
- IChannel#readable? no longer blocks.
|
57
71
|
IChannel#readable? no longer blocks for 0.1 seconds on IO.select call.
|
58
|
-
Thanks to quezacoatl(https://github.com/quezacoatl) for the initial
|
59
|
-
implementation.
|
72
|
+
Thanks to quezacoatl(https://github.com/quezacoatl) for the initial
|
73
|
+
implementation.
|
60
74
|
|
61
75
|
== v5.0.0
|
62
76
|
- Remove IChannel#empty?
|
63
|
-
I think the #readable? method is all you need, and is a much more
|
77
|
+
I think the #readable? method is all you need, and is a much more
|
64
78
|
accurate description of what the method is asking. We cannot determine
|
65
|
-
if the channel is really empty, but we can ask if it is readable at the
|
79
|
+
if the channel is really empty, but we can ask if it is readable at the
|
66
80
|
time you ask.
|
67
81
|
|
68
82
|
== v4.1.0
|
69
83
|
- Add IChannel#readable?
|
70
|
-
A method that can tell you whether or not a read would block.
|
84
|
+
A method that can tell you whether or not a read would block.
|
71
85
|
When it returns true, a read shouldn't block, on the other hand
|
72
86
|
if it were false it'd likely block by the time you call #get.
|
73
87
|
== v4.0.0
|
74
88
|
- Modify IChannel#empty?
|
75
|
-
It now returns true in case the underlying UNIXSocket being used as a
|
89
|
+
It now returns true in case the underlying UNIXSocket being used as a
|
76
90
|
reader is closed.
|
77
91
|
|
78
92
|
== v3.1.0
|
@@ -80,7 +94,7 @@
|
|
80
94
|
IChannel#empty? returns true when the channel is empty(nothing to read).
|
81
95
|
|
82
96
|
- Micro speed improvement on #write!, & #recv! operations.
|
83
|
-
By passing nil instead of creating two empty arrays for every read/write
|
97
|
+
By passing nil instead of creating two empty arrays for every read/write
|
84
98
|
operation we should see a very small improvement in their performance.
|
85
99
|
|
86
|
-
- Add ChangeLog.txt
|
100
|
+
- Add ChangeLog.txt
|
data/README.md
CHANGED
@@ -1,44 +1,42 @@
|
|
1
|
-
__OVERVIEW__
|
1
|
+
__OVERVIEW__
|
2
2
|
|
3
|
-
| Project | ichannel
|
3
|
+
| Project | ichannel
|
4
4
|
|:----------------|:--------------------------------------------------
|
5
5
|
| Homepage | https://github.com/robgleeson/ichannel
|
6
|
-
| Documentation | http://rubydoc.info/github/robgleeson/ichannel/frames
|
6
|
+
| Documentation | http://rubydoc.info/github/robgleeson/ichannel/frames
|
7
|
+
| Metrics | [](https://codeclimate.com/github/robgleeson/ichannel)
|
7
8
|
| CI | [](https://travis-ci.org/robgleeson/ichannel)
|
8
|
-
| Author | Robert Gleeson
|
9
|
+
| Author | Robert Gleeson
|
9
10
|
|
10
11
|
|
11
12
|
__DESCRIPTION__
|
12
13
|
|
13
14
|
ichannel is a channel for interprocess communication between ruby processes on
|
14
|
-
the same machine or network. The basic premise is that you can "put" a ruby
|
15
|
-
object onto the channel and on the other end(maybe in a different process,
|
15
|
+
the same machine or network. The basic premise is that you can "put" a ruby
|
16
|
+
object onto the channel and on the other end(maybe in a different process,
|
16
17
|
or maybe on a different machine) you can "get" the object from the channel.
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
to you. The default is set to be [Marshal](http://ruby-doc.org/core-2.0/Marshal.html)
|
28
|
-
but a serializer can be any object that implements dump and load. A few off the top of
|
29
|
-
my head would be JSON, YAML, or MessagePack(with a wrapper, see examples).
|
18
|
+
A [unix socket](http://www.ruby-doc.org/stdlib-2.0/libdoc/socket/rdoc/UNIXSocket.html)
|
19
|
+
(local to a single machine) or [redis](https://redis.io) can be used for
|
20
|
+
transport.
|
21
|
+
|
22
|
+
A channel depends on a serializer when reading and writing from the underlying
|
23
|
+
socket(e.g: redis or a unix socket) but you can use any serializer that
|
24
|
+
implements the dump and load methods. The default is set to be
|
25
|
+
[Marshal](http://ruby-doc.org/core-2.0/Marshal.html) since it is a core
|
26
|
+
ruby module but you could also use JSON, YAML, MessagePack, or <insert your
|
27
|
+
serializer here>.
|
30
28
|
|
31
29
|
__EXAMPLES__
|
32
30
|
|
33
31
|
__1.__
|
34
32
|
|
35
|
-
A demo of how to pass ruby objects through a channel and also between processes.
|
36
|
-
[Marshal](http://rubydoc.info/stdlib/core/Marshal) is the serializer of choice,
|
37
|
-
and a streamed UNIXSocket is
|
33
|
+
A demo of how to pass ruby objects through a channel and also between processes.
|
34
|
+
[Marshal](http://rubydoc.info/stdlib/core/Marshal) is the serializer of choice,
|
35
|
+
and a streamed UNIXSocket is used for transport:
|
38
36
|
|
39
37
|
```ruby
|
40
38
|
channel = IChannel.unix Marshal
|
41
|
-
pid = fork do
|
39
|
+
pid = fork do
|
42
40
|
channel.put Process.pid
|
43
41
|
channel.put 'Hello!'
|
44
42
|
end
|
@@ -46,15 +44,28 @@ Process.wait pid
|
|
46
44
|
channel.get # => Fixnum
|
47
45
|
channel.get # => 'Hello!'
|
48
46
|
```
|
49
|
-
|
50
47
|
__2.__
|
51
48
|
|
49
|
+
A demo of a channel sending messages between machines by using
|
50
|
+
[redis](https://redis.io) for transport:
|
51
|
+
|
52
|
+
```ruby
|
53
|
+
channel = IChannel.redis Marshal, host: "10.0.0.1", key: "readme-example"
|
54
|
+
channel.put %w(a)
|
55
|
+
|
56
|
+
# In another process, on another machine, far away…
|
57
|
+
channel = IChannel.redis Marshal, host: "10.0.0.1", key: "readme-example"
|
58
|
+
channel.get # => ["a"]
|
59
|
+
```
|
60
|
+
|
61
|
+
__3.__
|
62
|
+
|
52
63
|
Knowing when a channel is readable can be useful so that you can avoid a
|
53
|
-
blocking read on the underlying UNIXSocket. This (bad) example demonstrates
|
64
|
+
blocking read on the underlying UNIXSocket. This (bad) example demonstrates
|
54
65
|
how to do that:
|
55
66
|
|
56
67
|
```ruby
|
57
|
-
channel = IChannel.unix Marshal
|
68
|
+
channel = IChannel.unix Marshal
|
58
69
|
pid = fork do
|
59
70
|
sleep 3
|
60
71
|
channel.put 42
|
@@ -66,20 +77,6 @@ channel.get # => 42
|
|
66
77
|
Process.wait pid
|
67
78
|
```
|
68
79
|
|
69
|
-
__3.__
|
70
|
-
|
71
|
-
A demo of a channel sending messages between machines by using
|
72
|
-
[redis](https://redis.io) as a backend:
|
73
|
-
|
74
|
-
```ruby
|
75
|
-
channel = IChannel.redis Marshal, key: "readme-example"
|
76
|
-
channel.put %w(a)
|
77
|
-
|
78
|
-
# In another process, on another machine, far away…
|
79
|
-
channel = IChannel.redis Marshal, key: "readme-example"
|
80
|
-
channel.get # => ["a"]
|
81
|
-
```
|
82
|
-
|
83
80
|
__4.__
|
84
81
|
|
85
82
|
MessagePack doesn't implement `dump` or `load` but a wrapper can be easily
|
@@ -102,18 +99,16 @@ __PLATFORM SUPPORT__
|
|
102
99
|
|
103
100
|
_supported_
|
104
101
|
|
105
|
-
* CRuby (1.9+)
|
102
|
+
* CRuby (1.9+)
|
106
103
|
* Rubinius (1.9+)
|
107
104
|
* JRuby (1.9+ - some tests skipped)
|
108
|
-
JRuby is supported and passes the test suite but it has a few skips.
|
109
|
-
Three skips are because jruby does not implement Kernel.fork
|
110
|
-
|
111
|
-
a channel that uses a unix socket. The other 24 tests pass on jruby, &
|
112
|
-
those tests cover both unix sockets & redis.
|
105
|
+
JRuby is supported and passes the test suite but it has a few skips.
|
106
|
+
Three skips are because jruby does not implement Kernel.fork.
|
107
|
+
The other tests pass on jruby, & those tests cover both unix sockets & redis.
|
113
108
|
|
114
109
|
_unsupported_
|
115
110
|
|
116
|
-
* Any 1.8 implementation
|
111
|
+
* Any 1.8 implementation
|
117
112
|
* MacRuby
|
118
113
|
|
119
114
|
__INSTALL__
|
@@ -128,8 +123,8 @@ And to finish:
|
|
128
123
|
$ gem install ichannel
|
129
124
|
|
130
125
|
__SEE ALSO__
|
131
|
-
|
132
|
-
- [ifuture](https://github.com/Havenwood/ifuture)
|
126
|
+
|
127
|
+
- [ifuture](https://github.com/Havenwood/ifuture)
|
133
128
|
futures built on process forks and ichannel.
|
134
129
|
|
135
130
|
__LICENSE__
|
data/ichannel.gemspec
CHANGED
@@ -5,8 +5,7 @@ Gem::Specification.new do |gem|
|
|
5
5
|
gem.version = IChannel::VERSION
|
6
6
|
gem.authors = ["Robert Gleeson"]
|
7
7
|
gem.email = ["rob@flowof.info"]
|
8
|
-
gem.description = %q{
|
9
|
-
primitive.}
|
8
|
+
gem.description = %q{interprocess communication channel}
|
10
9
|
gem.summary = gem.description
|
11
10
|
gem.homepage = "https://github.com/robgleeson/ichannel"
|
12
11
|
|
data/lib/ichannel.rb
CHANGED
@@ -3,8 +3,8 @@ module IChannel
|
|
3
3
|
require_relative "ichannel/unix_socket"
|
4
4
|
|
5
5
|
#
|
6
|
-
# @param
|
7
|
-
# (see UNIXSocket#initialize)
|
6
|
+
# @param
|
7
|
+
# (see UNIXSocket#initialize).
|
8
8
|
#
|
9
9
|
# @return
|
10
10
|
# (see UNIXSocket#initialize)
|
@@ -24,6 +24,6 @@ module IChannel
|
|
24
24
|
unless defined?(IChannel::Redis)
|
25
25
|
require_relative "ichannel/redis"
|
26
26
|
end
|
27
|
-
|
27
|
+
Redis.new serializer, options
|
28
28
|
end
|
29
29
|
end
|
data/lib/ichannel/redis.rb
CHANGED
@@ -100,27 +100,26 @@ class IChannel::Redis
|
|
100
100
|
|
101
101
|
#
|
102
102
|
# @param [Fixnum] timeout
|
103
|
-
# The
|
103
|
+
# The number of seconds (as an Integer) to wait before a time out will occur.
|
104
104
|
#
|
105
105
|
# @raise [IOError]
|
106
106
|
# When the channel is closed or empty.
|
107
107
|
#
|
108
108
|
# @raise [Timeout::Error]
|
109
|
-
# When the read
|
109
|
+
# When _timeout_ seconds pass and the read has not completed.
|
110
110
|
#
|
111
111
|
# @return [Object]
|
112
112
|
# The object read from the channel.
|
113
113
|
#
|
114
|
-
def recv!(timeout =
|
114
|
+
def recv!(timeout = 1)
|
115
115
|
if closed?
|
116
116
|
raise IOError, 'The channel cannot be read from (closed).'
|
117
|
-
|
118
|
-
|
117
|
+
end
|
118
|
+
_, payload = @redis.brpop @key, timeout
|
119
|
+
if payload
|
120
|
+
@last_msg = @serializer.load(payload)
|
119
121
|
else
|
120
|
-
Timeout
|
121
|
-
dump = @redis.rpop @key
|
122
|
-
@last_msg = @serializer.load dump
|
123
|
-
end
|
122
|
+
raise Timeout::Error, "timeout on read after #{timeout} seconds"
|
124
123
|
end
|
125
124
|
end
|
126
125
|
alias_method :get!, :recv!
|
data/lib/ichannel/unix_socket.rb
CHANGED
@@ -128,7 +128,7 @@ module IChannel
|
|
128
128
|
# @raise [IOError]
|
129
129
|
# (see IChannel#recv)
|
130
130
|
#
|
131
|
-
# @raise [
|
131
|
+
# @raise [Timeout::Error]
|
132
132
|
# When _timeout_ seconds elapse & the channel remains unreadable.
|
133
133
|
#
|
134
134
|
# @return [Object]
|
@@ -143,7 +143,7 @@ module IChannel
|
|
143
143
|
msg = readable[0].readline(SEP).chomp SEP
|
144
144
|
@last_msg = @serializer.load msg
|
145
145
|
else
|
146
|
-
raise
|
146
|
+
raise Timeout::Error, 'Time out on read (waited for %s second(s))' % [timeout]
|
147
147
|
end
|
148
148
|
end
|
149
149
|
alias_method :get!, :recv!
|
@@ -160,17 +160,5 @@ module IChannel
|
|
160
160
|
!! readable
|
161
161
|
end
|
162
162
|
end
|
163
|
-
|
164
|
-
# @api private
|
165
|
-
def marshal_load(array)
|
166
|
-
@serializer, reader, writer, @last_msg = array
|
167
|
-
@reader = ::UNIXSocket.for_fd(reader)
|
168
|
-
@writer = ::UNIXSocket.for_fd(writer)
|
169
|
-
end
|
170
|
-
|
171
|
-
# @api private
|
172
|
-
def marshal_dump
|
173
|
-
[@serializer, @reader.to_i, @writer.to_i, @last_msg]
|
174
|
-
end
|
175
163
|
end
|
176
164
|
end
|
data/lib/ichannel/version.rb
CHANGED
data/test/ichannel_redis_test.rb
CHANGED
data/test/ichannel_unix_test.rb
CHANGED
@@ -26,31 +26,22 @@ class IChannelUNIXTest < Test::Unit::TestCase
|
|
26
26
|
end
|
27
27
|
end
|
28
28
|
|
29
|
-
def
|
30
|
-
|
31
|
-
|
32
|
-
|
29
|
+
def test_blocking_get
|
30
|
+
assert_raises Timeout::Error do
|
31
|
+
Timeout.timeout(1) { @channel.get }
|
32
|
+
end
|
33
33
|
end
|
34
34
|
|
35
|
-
def
|
36
|
-
|
37
|
-
|
38
|
-
end
|
39
|
-
dump = Marshal.dump(@channel)
|
40
|
-
pid = fork do
|
41
|
-
Marshal.load(dump).put [42]
|
35
|
+
def test_timeout_on_get
|
36
|
+
assert_raises Timeout::Error do
|
37
|
+
@channel.get! 0.1
|
42
38
|
end
|
43
|
-
Process.wait pid
|
44
|
-
assert_equal [42], @channel.get
|
45
39
|
end
|
46
40
|
|
47
|
-
def
|
48
|
-
if RUBY_ENGINE == "jruby"
|
49
|
-
skip "fails on jruby"
|
50
|
-
end
|
41
|
+
def test_last_msg_after_read
|
51
42
|
@channel.put [42]
|
52
|
-
|
53
|
-
assert_equal [42],
|
43
|
+
@channel.get
|
44
|
+
assert_equal [42], @channel.last_msg
|
54
45
|
end
|
55
46
|
|
56
47
|
def test_fork
|
@@ -63,7 +54,7 @@ class IChannelUNIXTest < Test::Unit::TestCase
|
|
63
54
|
Process.wait pid
|
64
55
|
assert_equal [42], @channel.get
|
65
56
|
end
|
66
|
-
|
57
|
+
|
67
58
|
def test_last_msg
|
68
59
|
@channel.put %w(a)
|
69
60
|
@channel.put %w(b)
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: ichannel
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version:
|
4
|
+
version: 7.0.0
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,9 +9,9 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2013-
|
12
|
+
date: 2013-07-29 00:00:00.000000000 Z
|
13
13
|
dependencies: []
|
14
|
-
description:
|
14
|
+
description: interprocess communication channel
|
15
15
|
email:
|
16
16
|
- rob@flowof.info
|
17
17
|
executables: []
|
@@ -51,7 +51,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
51
51
|
version: '0'
|
52
52
|
segments:
|
53
53
|
- 0
|
54
|
-
hash:
|
54
|
+
hash: -3143838182628750731
|
55
55
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
56
56
|
none: false
|
57
57
|
requirements:
|
@@ -60,13 +60,13 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
60
60
|
version: '0'
|
61
61
|
segments:
|
62
62
|
- 0
|
63
|
-
hash:
|
63
|
+
hash: -3143838182628750731
|
64
64
|
requirements: []
|
65
65
|
rubyforge_project:
|
66
66
|
rubygems_version: 1.8.23
|
67
67
|
signing_key:
|
68
68
|
specification_version: 3
|
69
|
-
summary:
|
69
|
+
summary: interprocess communication channel
|
70
70
|
test_files:
|
71
71
|
- test/ichannel_redis_test.rb
|
72
72
|
- test/ichannel_unix_test.rb
|