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.
- checksums.yaml +5 -13
- data/Gemfile.lock +1 -13
- data/README.md +36 -87
- data/VERSION +1 -1
- data/asynchronous.gemspec +0 -4
- data/examples/async_patterns.rb +17 -14
- data/examples/bootstrap.rb +2 -0
- data/examples/no_zombie_test.rb +5 -2
- data/examples/parallelism.rb +35 -0
- data/lib/async.rb +1 -0
- data/lib/asynchronous.rb +4 -9
- data/lib/asynchronous/concurrency.rb +33 -67
- data/lib/asynchronous/error.rb +8 -0
- data/lib/asynchronous/kernel.rb +18 -17
- data/lib/asynchronous/parallelism.rb +102 -106
- metadata +12 -45
- data/dump/async.rb +0 -4
- data/dump/shared_memory.rb +0 -138
- data/examples/array_of_value_with_native_threads.rb +0 -23
- data/examples/ruby_worker.rb +0 -54
- data/examples/shared_memory1.rb +0 -19
- data/examples/shared_memory2.rb +0 -29
- data/lib/asynchronous/clean_class.rb +0 -14
- data/lib/asynchronous/shared_memory.rb +0 -214
data/lib/asynchronous/kernel.rb
CHANGED
@@ -10,32 +10,33 @@
|
|
10
10
|
# "some awsome ruby code here!"
|
11
11
|
# end
|
12
12
|
#
|
13
|
-
module
|
13
|
+
module Asynchronous::DCI
|
14
14
|
|
15
|
-
|
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
|
20
|
-
|
21
|
-
|
22
|
-
end
|
21
|
+
when *%W[ c v g ]
|
22
|
+
::Asynchronous::Concurrency.new(&block)
|
23
|
+
|
23
24
|
# Parallelism / OS / Native
|
24
|
-
when
|
25
|
-
|
26
|
-
|
27
|
-
end
|
25
|
+
when *%W[ p o n ]
|
26
|
+
::Asynchronous::Parallelism.new(&block)
|
27
|
+
|
28
28
|
else
|
29
|
-
|
30
|
-
Asynchronous::Concurrency.new(block)
|
31
|
-
end
|
29
|
+
::Asynchronous::Concurrency.new(&block)
|
32
30
|
|
33
31
|
end
|
34
|
-
|
35
32
|
end
|
36
33
|
|
37
|
-
|
38
|
-
|
39
|
-
|
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
|
-
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
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
|
-
|
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
|
-
|
35
|
-
|
36
|
-
@comm_line[1].flush
|
13
|
+
@@pids ||= []
|
14
|
+
@@motherpid ||= $$
|
37
15
|
|
38
|
-
|
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
|
-
|
46
|
-
end
|
20
|
+
@comm_line = ::IO.pipe
|
47
21
|
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
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
|
-
|
30
|
+
end
|
58
31
|
|
59
|
-
|
60
|
-
|
61
|
-
|
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
|
-
|
64
|
-
|
65
|
-
@@pids.push(@pid)
|
39
|
+
def join
|
40
|
+
if @value.nil?
|
66
41
|
|
67
|
-
|
42
|
+
::Process.wait(@pid, ::Process::WNOHANG)
|
68
43
|
|
69
|
-
|
70
|
-
|
71
|
-
|
44
|
+
@comm_line[1].close
|
45
|
+
@read_buffer.join
|
46
|
+
@comm_line[0].close
|
72
47
|
|
73
|
-
|
74
|
-
|
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
|
-
|
52
|
+
end; self
|
53
|
+
end
|
83
54
|
|
84
|
-
|
55
|
+
def value
|
56
|
+
join; @value
|
57
|
+
end
|
85
58
|
|
86
|
-
|
59
|
+
protected
|
87
60
|
|
88
|
-
|
89
|
-
|
90
|
-
|
61
|
+
def pipe_read
|
62
|
+
@comm_line[0]
|
63
|
+
end
|
91
64
|
|
92
|
-
|
65
|
+
def pipe_write
|
66
|
+
@comm_line[1]
|
67
|
+
end
|
93
68
|
|
94
|
-
|
69
|
+
def fork(&block)
|
70
|
+
return ::Kernel.fork do
|
95
71
|
|
96
|
-
|
72
|
+
GC.disable if @disable_gc
|
97
73
|
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
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
|
-
|
90
|
+
@comm_line[0].close
|
120
91
|
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
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
|
-
|
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:
|
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:
|
12
|
-
dependencies:
|
13
|
-
|
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/
|
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:
|
54
|
+
version: 1.3.1
|
87
55
|
requirements: []
|
88
56
|
rubyforge_project:
|
89
|
-
rubygems_version: 2.2.
|
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:
|
data/dump/async.rb
DELETED
data/dump/shared_memory.rb
DELETED
@@ -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
|
-
|