ichannel 1.0.0 → 2.0.0

Sign up to get free protection for your applications and to get access to all the features.
data/README.md CHANGED
@@ -11,12 +11,14 @@ __OVERVIEW__
11
11
 
12
12
  __DESCRIPTION__
13
13
 
14
- Provides a modern and easy to use interprocess communication(IPC) primitive.
15
- It can be used to transport Ruby objects between Ruby processes running on the
16
- same machine. The serialization options are flexible: any serializer that
17
- implements `#dump` & `#load` can be used -- this covers Marshal, YAML, & JSON
18
- out of the box but not MsgPack -- although you could easily write a wrapper
19
- around msgpack.
14
+ A modern, flexible & easy to use interprocess communication(IPC) primitive. The
15
+ basic premise is that you can "put" and "get" Ruby objects to/from a channel.
16
+ This works across any Ruby process & its subprocesses, though, which is why it
17
+ can be useful. You could describe putting and getting objects to/from the channel
18
+ as message passing but the message could potentially be any Ruby object,
19
+ although I think sending small messages(as a Hash) works very well for most
20
+ scenarios. You have the potential to serialize any object that `Marshal` can
21
+ dump+load, though.
20
22
 
21
23
  __EXAMPLES__
22
24
 
@@ -26,14 +28,43 @@ The first example shows off how you'd pass Ruby objects through a channel.
26
28
  The serializer of choice is `Marshal` but it could just as easily be `JSON` or
27
29
  `YAML`.
28
30
 
29
- channel = IChannel.new Marshal
30
- channel.put 'hello'
31
- channel.put 'goodbye'
32
- pid = fork do
33
- channel.get # => 'hello'
34
- channel.get # => 'goodbye'
35
- end
36
- Process.wait pid
31
+ ```ruby
32
+ channel = IChannel.new Marshal
33
+ pid = fork do
34
+ channel.put Process.pid
35
+ channel.put 'Hello!'
36
+ end
37
+ Process.wait pid
38
+ channel.get # => Fixnum
39
+ channel.get # => 'Hello!'
40
+ ```
41
+
42
+ __SERIALIZERS__
43
+
44
+ To send Ruby objects between processes they have to be serialized, but on the
45
+ bright side the number of serializers to choose from is vast. Marshal, JSON, &
46
+ YAML are supported out of the box to name a few but adding support for other
47
+ serializers is a trivial amount of work.
48
+
49
+ For example, here is a MessagePack serializer you could use:
50
+
51
+ ```ruby
52
+ require 'ichannel'
53
+ require 'msgpack'
54
+ serializer = Class.new do
55
+ def self.dump(msg)
56
+ MessagePack.pack msg
57
+ end
58
+
59
+ def self.load(msg)
60
+ MessagePack.unpack msg
61
+ end
62
+ end
63
+ channel = IChannel.new serializer
64
+ ```
65
+
66
+ As you can see above as long as the serializer responds to `.dump` & `.load` it
67
+ can be passed as a serializer to IChannel.
37
68
 
38
69
  __REAL WORLD EXAMPLES__
39
70
 
data/ichannel.gemspec CHANGED
@@ -5,7 +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{A simple and modern interprocess communication
8
+ gem.description = %q{A modern and easy-to-use interprocess communication
9
9
  primitive.}
10
10
  gem.summary = gem.description
11
11
  gem.homepage = "https://github.com/robgleeson/ichannel"
data/lib/ichannel.rb CHANGED
@@ -9,34 +9,33 @@ class IChannel
9
9
  @serializer = serializer
10
10
  end
11
11
 
12
- #
13
- # Close the channel.
14
- #
15
- # @return [void]
16
- #
17
- def close
18
- [@reader.close,@writer.close]
19
- end
20
-
21
12
  #
22
13
  # @return [Boolean]
23
- # Returns true if the channel is closed.
14
+ # Returns true when the channel is closed.
24
15
  #
25
16
  def closed?
26
17
  @reader.closed? && @writer.closed?
27
18
  end
28
19
 
20
+ #
21
+ # Close the channel.
29
22
  #
30
23
  # @return [Boolean]
31
- # Returns true if the channel is open.
24
+ # Returns true when the channel has been closed.
25
+ # Returns nil when the channel is already closed.
32
26
  #
33
- def open?
34
- !closed?
27
+ def close
28
+ if !@reader.closed? && !@writer.closed?
29
+ !! [@reader.close, @writer.close]
30
+ end
35
31
  end
36
32
 
37
33
  #
38
34
  # Add an object to the channel.
39
35
  #
36
+ # @raise [IOError]
37
+ # When the channel cannot be written to.
38
+ #
40
39
  # @param [Object] object
41
40
  # An object to add to the channel.
42
41
  #
@@ -44,6 +43,8 @@ class IChannel
44
43
  _, writable, _ = IO.select [], [@writer], [], 0.1
45
44
  if writable
46
45
  @writer.send @serializer.dump(object), 0
46
+ else
47
+ raise IOError, 'The channel cannot be written to.'
47
48
  end
48
49
  end
49
50
  alias_method :put, :write
@@ -51,6 +52,9 @@ class IChannel
51
52
  #
52
53
  # Receive a object from the channel.
53
54
  #
55
+ # @raise [IOError]
56
+ # When the channel cannot be read from.
57
+ #
54
58
  # @return [Object]
55
59
  # The object added to the channel.
56
60
  #
@@ -59,6 +63,8 @@ class IChannel
59
63
  if readable
60
64
  msg, _ = @reader.recvmsg
61
65
  @serializer.load msg
66
+ else
67
+ raise IOError, 'The channel cannot be read from.'
62
68
  end
63
69
  end
64
70
  alias_method :get, :recv
@@ -1,3 +1,3 @@
1
1
  class IChannel
2
- VERSION = "1.0.0"
2
+ VERSION = "2.0.0"
3
3
  end
@@ -16,6 +16,20 @@ class IChannelTest < Test::Unit::TestCase
16
16
  assert_equal %w(a b c), @channel.get
17
17
  end
18
18
 
19
+ def test_put_on_closed_channel
20
+ @channel.close
21
+ assert_raises IOError do
22
+ @channel.put %w(a)
23
+ end
24
+ end
25
+
26
+ def test_get_on_closed_channel
27
+ @channel.close
28
+ assert_raises IOError do
29
+ @channel.put %w(b)
30
+ end
31
+ end
32
+
19
33
  def test_queued_messages
20
34
  pid = fork do
21
35
  @channel.put %w(a)
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: 1.0.0
4
+ version: 2.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: 2012-11-15 00:00:00.000000000 Z
12
+ date: 2012-11-17 00:00:00.000000000 Z
13
13
  dependencies: []
14
- description: ! "A simple and modern interprocess communication \n primitive."
14
+ description: ! "A modern and easy-to-use interprocess communication \n primitive."
15
15
  email:
16
16
  - rob@flowof.info
17
17
  executables: []
@@ -43,7 +43,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
43
43
  version: '0'
44
44
  segments:
45
45
  - 0
46
- hash: -3802321299613243923
46
+ hash: -795267943345486764
47
47
  required_rubygems_version: !ruby/object:Gem::Requirement
48
48
  none: false
49
49
  requirements:
@@ -52,13 +52,13 @@ required_rubygems_version: !ruby/object:Gem::Requirement
52
52
  version: '0'
53
53
  segments:
54
54
  - 0
55
- hash: -3802321299613243923
55
+ hash: -795267943345486764
56
56
  requirements: []
57
57
  rubyforge_project:
58
58
  rubygems_version: 1.8.23
59
59
  signing_key:
60
60
  specification_version: 3
61
- summary: A simple and modern interprocess communication primitive.
61
+ summary: A modern and easy-to-use interprocess communication primitive.
62
62
  test_files:
63
63
  - test/ichannel_class_test.rb
64
64
  - test/setup.rb