asynchronous 3.0.1 → 4.0.0.pre

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.
@@ -0,0 +1,8 @@
1
+ class Asynchronous::Error < StandardError
2
+
3
+ attr_reader :wrapped_error
4
+ def initialize(wrapped_error)
5
+ @wrapped_error= wrapped_error
6
+ end
7
+
8
+ end
@@ -10,32 +10,33 @@
10
10
  # "some awsome ruby code here!"
11
11
  # end
12
12
  #
13
- module Kernel
13
+ module Asynchronous::DCI
14
14
 
15
- def async type= :VM ,&block
15
+ extend self
16
16
 
17
+ def async(type= :VM, &block)
17
18
  case type.to_s.downcase[0]
19
+
18
20
  # Concurrency / VM / Green
19
- when "c","v","g"
20
- begin
21
- Asynchronous::Concurrency.new(block)
22
- end
21
+ when *%W[ c v g ]
22
+ ::Asynchronous::Concurrency.new(&block)
23
+
23
24
  # Parallelism / OS / Native
24
- when "p","o","n"
25
- begin
26
- Asynchronous::Parallelism.new(block)
27
- end
25
+ when *%W[ p o n ]
26
+ ::Asynchronous::Parallelism.new(&block)
27
+
28
28
  else
29
- begin
30
- Asynchronous::Concurrency.new(block)
31
- end
29
+ ::Asynchronous::Concurrency.new(&block)
32
30
 
33
31
  end
34
-
35
32
  end
36
33
 
37
- def shared_memory
38
- Asynchronous::SharedMemory
39
- end unless method_defined? :shared_memory
34
+ end
35
+
36
+ Kernel.class_eval do
37
+
38
+ def async(type=nil, &block)
39
+ ::Asynchronous::DCI.async(type, &block)
40
+ end
40
41
 
41
42
  end
@@ -1,139 +1,135 @@
1
- module Asynchronous
2
- # now let's see the Parallelism
3
- # you can use simple :p also instead of :parallelism
4
- # remember :parallelism is all about real OS thread case, so
5
- # you CANT modify the objects in memory only copy on write modify
6
- # This is ideal for big operations where you need do a big process
7
- # and only get the return value so you can do big works without the fear of the
8
- # Garbage collector slowness or the GIL lock
9
- # when you need to update objects in the memory use :concurrency
10
- class Parallelism < Asynchronous::CleanClass
11
-
12
- @@pids ||= []
13
- @@motherpid ||= $$
14
-
15
- def asynchronous_fork callable
16
- return ::Kernel.fork do
1
+ # now let's see the Parallelism
2
+ # you can use simple :p also instead of :parallelism
3
+ # remember :parallelism is all about real OS thread case, so
4
+ # you CANT modify the objects in memory only copy on write modify
5
+ # This is ideal for big operations where you need do a big process
6
+ # and only get the return value so you can do big works without the fear of the
7
+ # Garbage collector slowness or the GIL lock
8
+ # when you need to update objects in the memory use :concurrency
9
+ class Asynchronous::Parallelism
17
10
 
18
- begin
19
- ::Kernel.trap("TERM") do
20
- ::Kernel.exit
21
- end
22
- ::Thread.new do
23
- ::Kernel.loop do
24
- begin
25
- ::Kernel.sleep 1
26
- if ::Asynchronous::Parallelism.asynchronous_alive?(@@motherpid) == false
27
- ::Kernel.exit
28
- end
29
- end
30
- end
31
- end
32
- end
11
+ attr_reader :pid
33
12
 
34
- @comm_line[0].close
35
- @comm_line[1].write ::Marshal.dump(callable.call)
36
- @comm_line[1].flush
13
+ @@pids ||= []
14
+ @@motherpid ||= $$
37
15
 
38
- #::Kernel.loop do
39
- # #::Kernel.puts @comm_line[0].closed?
40
- # #::Kernel.puts @comm_line[1].closed?
41
- # ::Kernel.sleep 1
42
- #end
16
+ def initialize(disable_gc=true,&callable)
43
17
 
18
+ @disable_gc = !!disable_gc
44
19
 
45
- end
46
- end
20
+ @comm_line = ::IO.pipe
47
21
 
48
- def asynchronous_read_buffer
49
- @read_buffer = ::Thread.new do
50
- while !@comm_line[0].eof?
51
- @value = ::Marshal.load(@comm_line[0])
52
- end
53
- end
54
- end
22
+ @value = nil
23
+ @read_buffer = nil
24
+
25
+ read_buffer
55
26
 
27
+ @pid = fork(&callable)
28
+ @@pids.push(@pid)
56
29
 
57
- def initialize callable
30
+ end
58
31
 
59
- @comm_line = ::IO.pipe
60
- @value = nil
61
- @read_buffer = nil
32
+ def self.alive?(pid)
33
+ ::Process.kill(0, pid)
34
+ return true
35
+ rescue ::Errno::ESRCH
36
+ return false
37
+ end
62
38
 
63
- asynchronous_read_buffer
64
- @pid= asynchronous_fork callable
65
- @@pids.push(@pid)
39
+ def join
40
+ if @value.nil?
66
41
 
67
- end
42
+ ::Process.wait(@pid, ::Process::WNOHANG)
68
43
 
69
- def asynchronous_get_pid
70
- return @pid
71
- end
44
+ @comm_line[1].close
45
+ @read_buffer.join
46
+ @comm_line[0].close
72
47
 
73
- def self.asynchronous_alive?(pid)
74
- begin
75
- ::Process.kill(0,pid)
76
- return true
77
- rescue ::Errno::ESRCH
78
- return false
48
+ if @value.is_a?(::Asynchronous::Error)
49
+ raise(@value.wrapped_error)
79
50
  end
80
- end
81
51
 
82
- def asynchronous_get_value
52
+ end; self
53
+ end
83
54
 
84
- if @value.nil?
55
+ def value
56
+ join; @value
57
+ end
85
58
 
86
- ::Process.wait(@pid, ::Process::WNOHANG )
59
+ protected
87
60
 
88
- @comm_line[1].close
89
- @read_buffer.join
90
- @comm_line[0].close
61
+ def pipe_read
62
+ @comm_line[0]
63
+ end
91
64
 
92
- end
65
+ def pipe_write
66
+ @comm_line[1]
67
+ end
93
68
 
94
- return @value
69
+ def fork(&block)
70
+ return ::Kernel.fork do
95
71
 
96
- end
72
+ GC.disable if @disable_gc
97
73
 
98
- def asynchronous_set_value(obj)
99
- @value= obj
100
- end
101
- alias :asynchronous_set_value= :asynchronous_set_value
102
-
103
- def synchronize
104
- asynchronous_get_value
105
- end
106
- alias :sync :synchronize
107
-
108
- # kill kidos at Kernel Exit
109
- ::Kernel.at_exit {
110
- @@pids.each { |pid|
111
- begin
112
- ::Process.kill(:TERM, pid)
113
- rescue ::Errno::ESRCH, ::Errno::ECHILD
114
- #::STDOUT.puts "`kill': No such process (Errno::ESRCH)"
74
+ begin
75
+ ::Kernel.trap("TERM") do
76
+ ::Kernel.exit
77
+ end
78
+ ::Thread.new do
79
+ ::Kernel.loop do
80
+ begin
81
+ ::Kernel.sleep 1
82
+ if ::Asynchronous::Parallelism.alive?(@@motherpid) == false
83
+ ::Kernel.exit!
84
+ end
85
+ end
115
86
  end
116
- }
117
- }
87
+ end
88
+ end
118
89
 
119
- def method_missing(method, *args)
90
+ @comm_line[0].close
120
91
 
121
- return_value= nil
122
- new_value= asynchronous_get_value
123
- begin
124
- original_value= new_value.dup
125
- rescue ::TypeError
126
- original_value= new_value
92
+ result = begin
93
+ block.call
94
+ rescue ::Exception => ex
95
+ ::Asynchronous::Error.new(ex)
127
96
  end
128
- return_value= new_value.__send__(method,*args)
129
- unless new_value == original_value
130
- asynchronous_set_value new_value
131
- end
132
97
 
133
- return return_value
98
+ dumped_result = ::Marshal.dump(result).to_s
99
+
100
+ @comm_line[1].write(dumped_result)
101
+ ::Kernel.sleep(dumped_result.length.to_f*0.005)
102
+
103
+ @comm_line[1].flush
104
+ @comm_line[1].close
134
105
 
135
106
  end
107
+ end
136
108
 
109
+ def read_buffer
110
+ @read_buffer = ::Thread.new do
111
+ while !@comm_line[0].eof?
137
112
 
113
+ begin
114
+ @value = ::Marshal.load(@comm_line[0])
115
+ rescue ::ArgumentError => ex
116
+ sleep(1)
117
+ retry if ex.respond_to?(:message) && ex.message =~ /marshal data too short/i
118
+ end
119
+
120
+ end
121
+ end
138
122
  end
123
+
124
+ # kill kidos at Kernel Exit
125
+ ::Kernel.at_exit do
126
+ @@pids.each do |pid|
127
+ begin
128
+ ::Process.kill(:TERM, pid)
129
+ rescue ::Errno::ESRCH, ::Errno::ECHILD
130
+ #::STDOUT.puts "`kill': No such process (Errno::ESRCH)"
131
+ end
132
+ end
133
+ end
134
+
139
135
  end
metadata CHANGED
@@ -1,44 +1,16 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: asynchronous
3
3
  version: !ruby/object:Gem::Version
4
- version: 3.0.1
4
+ version: 4.0.0.pre
5
5
  platform: ruby
6
6
  authors:
7
7
  - Adam Luzsi
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2014-02-17 00:00:00.000000000 Z
12
- dependencies:
13
- - !ruby/object:Gem::Dependency
14
- name: process_shared
15
- requirement: !ruby/object:Gem::Requirement
16
- requirements:
17
- - - ! '>='
18
- - !ruby/object:Gem::Version
19
- version: '0'
20
- type: :runtime
21
- prerelease: false
22
- version_requirements: !ruby/object:Gem::Requirement
23
- requirements:
24
- - - ! '>='
25
- - !ruby/object:Gem::Version
26
- version: '0'
27
- - !ruby/object:Gem::Dependency
28
- name: debugger
29
- requirement: !ruby/object:Gem::Requirement
30
- requirements:
31
- - - ! '>='
32
- - !ruby/object:Gem::Version
33
- version: '0'
34
- type: :development
35
- prerelease: false
36
- version_requirements: !ruby/object:Gem::Requirement
37
- requirements:
38
- - - ! '>='
39
- - !ruby/object:Gem::Version
40
- version: '0'
41
- description: ! 'DSL for for dead simple to use asynchronous patterns in both VM managed
11
+ date: 2015-06-22 00:00:00.000000000 Z
12
+ dependencies: []
13
+ description: 'DSL for for dead simple to use asynchronous patterns in both VM managed
42
14
  and OS managed way (Concurrency and Parallelism) '
43
15
  email:
44
16
  - adamluzsi@gmail.com
@@ -52,21 +24,17 @@ files:
52
24
  - Rakefile
53
25
  - VERSION
54
26
  - asynchronous.gemspec
55
- - dump/async.rb
56
- - dump/shared_memory.rb
57
- - examples/array_of_value_with_native_threads.rb
58
27
  - examples/async_patterns.rb
28
+ - examples/bootstrap.rb
59
29
  - examples/no_zombie_test.rb
60
- - examples/ruby_worker.rb
61
- - examples/shared_memory1.rb
62
- - examples/shared_memory2.rb
30
+ - examples/parallelism.rb
63
31
  - files.rb
32
+ - lib/async.rb
64
33
  - lib/asynchronous.rb
65
- - lib/asynchronous/clean_class.rb
66
34
  - lib/asynchronous/concurrency.rb
35
+ - lib/asynchronous/error.rb
67
36
  - lib/asynchronous/kernel.rb
68
37
  - lib/asynchronous/parallelism.rb
69
- - lib/asynchronous/shared_memory.rb
70
38
  homepage: https://github.com/adamluzsi/asynchronous
71
39
  licenses: []
72
40
  metadata: {}
@@ -76,19 +44,18 @@ require_paths:
76
44
  - lib
77
45
  required_ruby_version: !ruby/object:Gem::Requirement
78
46
  requirements:
79
- - - ! '>='
47
+ - - ">="
80
48
  - !ruby/object:Gem::Version
81
49
  version: '0'
82
50
  required_rubygems_version: !ruby/object:Gem::Requirement
83
51
  requirements:
84
- - - ! '>='
52
+ - - ">"
85
53
  - !ruby/object:Gem::Version
86
- version: '0'
54
+ version: 1.3.1
87
55
  requirements: []
88
56
  rubyforge_project:
89
- rubygems_version: 2.2.1
57
+ rubygems_version: 2.2.2
90
58
  signing_key:
91
59
  specification_version: 4
92
60
  summary: Simple Async Based on standard CRuby
93
61
  test_files: []
94
- has_rdoc:
@@ -1,4 +0,0 @@
1
- #encoding: UTF-8
2
- module Asynchronous
3
- require 'asynchronous'
4
- end
@@ -1,138 +0,0 @@
1
- require 'process_shared'
2
- require_relative "clean_class"
3
- module Asynchronous
4
-
5
-
6
- module Allocation
7
-
8
- class << self
9
- attr_accessor :memory_allocation_size
10
- end
11
-
12
- self.memory_allocation_size= 16384
13
-
14
- def self.mutex
15
- @@mutex
16
- end
17
-
18
- @@mutex = ProcessShared::Mutex.new
19
-
20
- end
21
-
22
-
23
- class SharedMemory < CleanClass
24
- class << self
25
- def method_missing(method, *args)
26
-
27
- ::Asynchronous::Allocation.mutex.synchronize do
28
- if method.to_s.include?('=')
29
- begin
30
- self.class_variable_get("@@#{method.to_s.sub('=','')}").write_object(args[0])
31
- rescue ::NameError
32
- self.class_variable_set(
33
- "@@#{method.to_s.sub('=','')}",
34
- ::ProcessShared::SharedMemory.new( ::Asynchronous::Allocation.memory_allocation_size )
35
- )
36
- self.class_variable_get("@@#{method.to_s.sub('=','')}").write_object(args[0])
37
- end
38
- else
39
- begin
40
- self.class_variable_get("@@#{method.to_s}").read_object
41
- rescue ::NameError
42
- return nil
43
- end
44
- end
45
- end
46
-
47
- end
48
- end
49
- end
50
-
51
-
52
- end
53
-
54
- SharedMemory ||= Asynchronous::SharedMemory
55
-
56
-
57
-
58
- =begin
59
-
60
-
61
- # The C void type; only useful for function return types
62
- :void => Type::VOID,
63
-
64
- # C boolean type
65
- :bool => Type::BOOL,
66
-
67
- # C nul-terminated string
68
- :string => Type::STRING,
69
-
70
- # C signed char
71
- :char => Type::CHAR,
72
- # C unsigned char
73
- :uchar => Type::UCHAR,
74
-
75
- # C signed short
76
- :short => Type::SHORT,
77
- # C unsigned short
78
- :ushort => Type::USHORT,
79
-
80
- # C signed int
81
- :int => Type::INT,
82
- # C unsigned int
83
- :uint => Type::UINT,
84
-
85
- # C signed long
86
- :long => Type::LONG,
87
-
88
- # C unsigned long
89
- :ulong => Type::ULONG,
90
-
91
- # C signed long long integer
92
- :long_long => Type::LONG_LONG,
93
-
94
- # C unsigned long long integer
95
- :ulong_long => Type::ULONG_LONG,
96
-
97
- # C single precision float
98
- :float => Type::FLOAT,
99
-
100
- # C double precision float
101
- :double => Type::DOUBLE,
102
-
103
- # C long double
104
- :long_double => Type::LONGDOUBLE,
105
-
106
- # Native memory address
107
- :pointer => Type::POINTER,
108
-
109
- # 8 bit signed integer
110
- :int8 => Type::INT8,
111
- # 8 bit unsigned integer
112
- :uint8 => Type::UINT8,
113
-
114
- # 16 bit signed integer
115
- :int16 => Type::INT16,
116
- # 16 bit unsigned integer
117
- :uint16 => Type::UINT16,
118
-
119
- # 32 bit signed integer
120
- :int32 => Type::INT32,
121
- # 32 bit unsigned integer
122
- :uint32 => Type::UINT32,
123
-
124
- # 64 bit signed integer
125
- :int64 => Type::INT64,
126
- # 64 bit unsigned integer
127
- :uint64 => Type::UINT64,
128
-
129
- :buffer_in => Type::BUFFER_IN,
130
- :buffer_out => Type::BUFFER_OUT,
131
- :buffer_inout => Type::BUFFER_INOUT,
132
-
133
- # Used in function prototypes to indicate the arguments are variadic
134
- :varargs => Type::VARARGS,
135
-
136
-
137
- =end
138
-