ichannel 1.0.0 → 2.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/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