iprocess 3.1.2 → 3.2.0

Sign up to get free protection for your applications and to get access to all the features.
data/.pryrc ADDED
@@ -0,0 +1 @@
1
+ require "./lib/iprocess"
data/.yardopts CHANGED
@@ -1,4 +1,5 @@
1
1
  -m markdown
2
+ -M redcarpet
2
3
  --no-private
3
4
  --hide-void-return
4
5
  --no-cache
data/README.md CHANGED
@@ -5,15 +5,16 @@ __OVERVIEW__
5
5
  |:----------------|:--------------------------------------------------
6
6
  | Homepage | https://github.com/robgleeson/IProcess
7
7
  | Documentation | http://rubydoc.info/gems/iprocess/frames
8
+ | CI | [![Build Status](https://travis-ci.org/robgleeson/iprocess.png)](https://travis-ci.org/robgleeson/iprocess)
8
9
  | Author | Rob Gleeson
9
10
 
10
11
 
11
12
  __DESCRIPTION__
12
13
 
13
- Provides a number of abstractions on top of spawning subprocesses and
14
- interprocess communication. It has a simple and easy to use API that
15
- supports synchronous and asynchronous method calls plus one or two other
16
- useful features shown in the examples below.
14
+ Provides a number of abstractions on top of spawning subprocesses and
15
+ interprocess communication. It has a simple and easy to use API that
16
+ supports synchronous and asynchronous method calls plus one or two other
17
+ useful features shown in the examples below.
17
18
 
18
19
  __EXAMPLES__
19
20
 
@@ -59,7 +60,7 @@ A demo of how you would spawn two subprocesses asynchronously:
59
60
  end
60
61
  inbox = Inbox.new
61
62
  jobs = IProcess.spawn!(2) { Process.pid }
62
- jobs.map { |job| job.report_to(inbox) }
63
+ jobs.each { |job| job.report_to(inbox) }
63
64
 
64
65
  __SERIALIZERS__
65
66
 
@@ -69,8 +70,8 @@ the `IProcess.serializer=` method:
69
70
 
70
71
  IProcess.serializer = JSON
71
72
 
72
- I know JSON & Marshal(the default) are supported out of
73
- the box because they implement both of those methods.
73
+ I know JSON, YAML & Marshal(the default) are supported out of
74
+ the box because all of them implement both of those methods.
74
75
  MessagePack does not however but you could easily write
75
76
  a wrapper:
76
77
 
data/lib/iprocess.rb CHANGED
@@ -1,66 +1,63 @@
1
1
  class IProcess
2
2
  require_relative 'iprocess/version'
3
3
  require_relative 'iprocess/channel'
4
-
5
- class << self
6
- #
7
- # @return [#load,#dump]
8
- # Returns the serializer used by IProcess.
9
- #
10
- def serializer
11
- @serializer || Marshal
12
- end
4
+ #
5
+ # @return [#load,#dump]
6
+ # Returns the serializer used by IProcess.
7
+ #
8
+ def self.serializer
9
+ @serializer || Marshal
10
+ end
13
11
 
14
- #
15
- # @param [#load,#dump] obj
16
- # Any object that implements #load, & #dump.
17
- # Examples could be JSON & Marshal.
18
- #
19
- def serializer=(obj)
20
- @serializer = obj
21
- end
12
+ #
13
+ # @param [#load,#dump] obj
14
+ # Any object that implements #load, & #dump.
15
+ # Examples could be JSON & Marshal.
16
+ #
17
+ def self.serializer=(obj)
18
+ @serializer = obj
19
+ end
22
20
 
23
- #
24
- # @overload spawn(number_of = 1, worker)
25
- #
26
- # Spawn one or more subprocesses.
27
- #
28
- # @param [Integer] number_of
29
- # The number of subprocesses to spawn.
30
- #
31
- # @param [#call] worker
32
- # The unit of work to execute in a subprocess.
33
- #
34
- # @return [Array<Object>]
35
- # The return value(s) of the unit(s) of work.
36
- #
37
- def spawn(*args, &worker)
38
- fork(*args, &worker).map(&:result)
39
- end
21
+ #
22
+ # @overload spawn(number_of = 1, worker)
23
+ #
24
+ # Spawn one or more subprocesses.
25
+ #
26
+ # @param [Integer] number_of
27
+ # The number of subprocesses to spawn.
28
+ #
29
+ # @param [#call] worker
30
+ # The unit of work to execute in a subprocess.
31
+ #
32
+ # @return [Array<Object>]
33
+ # The return value(s) of the unit(s) of work.
34
+ #
35
+ def self.spawn(*args, &worker)
36
+ fork(*args, &worker).map(&:result)
37
+ end
40
38
 
41
- #
42
- # @overload
43
- #
44
- # Spawn one or more subprocesses asynchronously.
45
- #
46
- # @param
47
- # (see IProcess.spawn)
48
- #
49
- # @return [Array<IProcess>]
50
- # An array of IProcess objects. See {#report_to}.
51
- #
52
- def spawn!(*args, &worker)
53
- fork *args, &worker
54
- end
55
-
56
- def fork(number_of = 1, obj = nil, &worker)
57
- worker = obj || worker
58
- Array.new(number_of) do
59
- IProcess.new(worker).tap { |job| job.execute }
60
- end
39
+ #
40
+ # @overload
41
+ #
42
+ # Spawn one or more subprocesses asynchronously.
43
+ #
44
+ # @param
45
+ # (see IProcess.spawn)
46
+ #
47
+ # @return [Array<IProcess>]
48
+ # An array of IProcess objects. See {#report_to}.
49
+ #
50
+ def self.spawn!(*args, &worker)
51
+ fork *args, &worker
52
+ end
53
+
54
+ def self.fork(number_of = 1, obj = nil, &worker)
55
+ worker = obj || worker
56
+ Array.new(number_of) do
57
+ IProcess.new(worker).tap { |job| job.execute }
61
58
  end
62
- private :fork
63
59
  end
60
+ private_class_method :fork
64
61
 
65
62
  #
66
63
  # @param [#call] worker
@@ -95,7 +92,8 @@ class IProcess
95
92
  end
96
93
  pid = Process.pid
97
94
  at_exit do
98
- if pid == Process.pid && thr.alive?
95
+ is_parent = pid == Process.pid
96
+ if is_parent && thr.alive?
99
97
  thr.join
100
98
  end
101
99
  end
@@ -1,5 +1,5 @@
1
+ require 'socket'
1
2
  class IProcess::Channel
2
-
3
3
  #
4
4
  # @param [#dump,#load}] serializer
5
5
  # Any object that implements dump, & load.
@@ -9,7 +9,7 @@ class IProcess::Channel
9
9
  # Yields self.
10
10
  #
11
11
  def initialize(serializer = IProcess.serializer)
12
- @reader, @writer = IO.pipe
12
+ @reader, @writer = UNIXSocket.pair :DGRAM
13
13
  @serializer = serializer
14
14
  if block_given?
15
15
  yield self
@@ -17,7 +17,14 @@ class IProcess::Channel
17
17
  end
18
18
 
19
19
  #
20
- # Is the channel closed?
20
+ # Close the channel.
21
+ #
22
+ # @return [void]
23
+ #
24
+ def close
25
+ [@reader.close,@writer.close]
26
+ end
27
+
21
28
  #
22
29
  # @return [Boolean]
23
30
  # Returns true if the channel is closed.
@@ -26,8 +33,6 @@ class IProcess::Channel
26
33
  @reader.closed? && @writer.closed?
27
34
  end
28
35
 
29
- #
30
- # Is the channel open?
31
36
  #
32
37
  # @return [Boolean]
33
38
  # Returns true if the channel is open.
@@ -37,18 +42,18 @@ class IProcess::Channel
37
42
  end
38
43
 
39
44
  #
40
- # Write a object to the channel.
45
+ # Add an object to the channel.
41
46
  #
42
47
  # @param [Object] object
43
- # A object to add to the channel.
48
+ # An object to add to the channel.
44
49
  #
45
50
  def write object
46
- if open?
47
- @reader.close
48
- @writer.write @serializer.dump(object)
49
- @writer.close
51
+ _, writable, _ = IO.select [], [@writer], [], 0.1
52
+ if writable
53
+ @writer.send @serializer.dump(object), 0
50
54
  end
51
55
  end
56
+ alias_method :put, :write
52
57
 
53
58
  #
54
59
  # Receive a object from the channel.
@@ -57,12 +62,11 @@ class IProcess::Channel
57
62
  # The object added to the channel.
58
63
  #
59
64
  def recv
60
- if open?
61
- @writer.close
62
- obj = @serializer.load @reader.read
63
- @reader.close
64
- obj
65
+ readable, _ = IO.select [@reader], [], [], 0.1
66
+ if readable
67
+ msg, _ = @reader.recvmsg
68
+ @serializer.load msg
65
69
  end
66
70
  end
67
-
71
+ alias_method :get, :recv
68
72
  end
@@ -1,3 +1,3 @@
1
1
  class IProcess
2
- VERSION = '3.1.2'
2
+ VERSION = '3.2.0'
3
3
  end
data/test/setup.rb CHANGED
@@ -1,5 +1,3 @@
1
1
  require 'iprocess'
2
2
  require 'test/unit'
3
- Dir.glob("test/*.rb").each do |test|
4
- require "./#{test}"
5
- end
3
+ require 'minitest/mock'
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: iprocess
3
3
  version: !ruby/object:Gem::Version
4
- version: 3.1.2
4
+ version: 3.2.0
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2012-10-28 00:00:00.000000000 Z
12
+ date: 2012-11-05 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: yard
@@ -83,6 +83,7 @@ extra_rdoc_files: []
83
83
  files:
84
84
  - .gemtest
85
85
  - .gitignore
86
+ - .pryrc
86
87
  - .travis.yml
87
88
  - .yardopts
88
89
  - Gemfile