legion 0.0.1
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 +7 -0
- data/lib/legion.rb +10 -0
- data/lib/legion/object.rb +57 -0
- data/lib/legion/supervisor.rb +63 -0
- data/lib/legion/version.rb +3 -0
- data/test/example.rb +29 -0
- metadata +79 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: b4b0225245d1e96a8c1a1c67525ccbc4c016c108
|
4
|
+
data.tar.gz: 2d9a10ccffecd74598e2608fa97c45f191aa01ca
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: c637b4f433b0f0081f5158d014ab80986576d8375ef748fd3e3b0d35508d504b990629ce267ab5aa04b78396c1d567233ff5134f309284b71b849f91b856fabc
|
7
|
+
data.tar.gz: 72168bc261d81feded3b4fa9b1d4b501747e255cd2ae3762ccca0a9541a4b164a910c273b94ff3d0cfabdcb7aab8885e676006c69525a43e9e3e1af2135a13b4
|
data/lib/legion.rb
ADDED
@@ -0,0 +1,57 @@
|
|
1
|
+
require "drb"
|
2
|
+
require "monitor"
|
3
|
+
require "socket"
|
4
|
+
|
5
|
+
module Legion
|
6
|
+
class Object
|
7
|
+
include MonitorMixin
|
8
|
+
|
9
|
+
attr_reader :pid, :uri
|
10
|
+
|
11
|
+
class << self
|
12
|
+
def method_added(name)
|
13
|
+
return if name =~ /_async\z/i
|
14
|
+
define_method "#{name}_async" do |*args|
|
15
|
+
Thread.new do
|
16
|
+
synchronize { @busy = true }
|
17
|
+
self.class.callbacks[:before][name].call unless self.class.callbacks[:before][name].nil?
|
18
|
+
send(name, *args)
|
19
|
+
synchronize { @busy = false }
|
20
|
+
Thread.terminate
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
def callbacks
|
26
|
+
@callbacks ||= {before: {}}
|
27
|
+
end
|
28
|
+
|
29
|
+
def before(name, &block)
|
30
|
+
callbacks[:before][name] = block
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
def ok?
|
35
|
+
true
|
36
|
+
end
|
37
|
+
|
38
|
+
def busy?
|
39
|
+
!!@busy
|
40
|
+
end
|
41
|
+
|
42
|
+
def start_remote_instance(port: nil)
|
43
|
+
return unless pid.nil?
|
44
|
+
@uri = "druby://localhost:#{port}"
|
45
|
+
@pid = fork do
|
46
|
+
DRb.start_service uri, self
|
47
|
+
DRb.thread.join
|
48
|
+
end
|
49
|
+
Process.detach pid
|
50
|
+
end
|
51
|
+
|
52
|
+
def exit
|
53
|
+
DRb.stop_service
|
54
|
+
end
|
55
|
+
|
56
|
+
end
|
57
|
+
end
|
@@ -0,0 +1,63 @@
|
|
1
|
+
require "drb"
|
2
|
+
|
3
|
+
module Legion
|
4
|
+
class Supervisor
|
5
|
+
attr_reader(
|
6
|
+
:klass,
|
7
|
+
:processes,
|
8
|
+
:local_instances,
|
9
|
+
:remote_instances
|
10
|
+
)
|
11
|
+
|
12
|
+
def initialize(klass, processes: 1)
|
13
|
+
@klass = klass
|
14
|
+
@processes = processes
|
15
|
+
@local_instances = []
|
16
|
+
@remote_instances = []
|
17
|
+
end
|
18
|
+
|
19
|
+
def start_remote_instances(port: nil)
|
20
|
+
DRb.start_service
|
21
|
+
(1..processes).each do |i|
|
22
|
+
local_instance = klass.new
|
23
|
+
local_instance.start_remote_instance(port: port)
|
24
|
+
port += 1
|
25
|
+
local_instances << local_instance
|
26
|
+
remote_instance = DRbObject.new_with_uri(local_instance.uri)
|
27
|
+
verify_remote_instance(remote_instance)
|
28
|
+
remote_instances << remote_instance
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
def stop_remote_instances
|
33
|
+
remote_instances.each do |remote_instance|
|
34
|
+
remote_instance.exit rescue nil
|
35
|
+
end
|
36
|
+
DRb.stop_service
|
37
|
+
end
|
38
|
+
|
39
|
+
def get_remote_instance
|
40
|
+
@remote_instance_index ||= 0
|
41
|
+
remote_instance = remote_instances[@remote_instance_index]
|
42
|
+
sleep 0.01 while remote_instance.busy?
|
43
|
+
@remote_instance_index += 1
|
44
|
+
@remote_instance_index = 0 if @remote_instance_index >= remote_instances.length
|
45
|
+
remote_instance
|
46
|
+
end
|
47
|
+
|
48
|
+
protected
|
49
|
+
|
50
|
+
def verify_remote_instance(remote_instance)
|
51
|
+
ok = false
|
52
|
+
while !ok
|
53
|
+
begin
|
54
|
+
ok = remote_instance.ok?
|
55
|
+
rescue DRb::DRbConnError
|
56
|
+
sleep 0.1
|
57
|
+
end
|
58
|
+
end
|
59
|
+
ok
|
60
|
+
end
|
61
|
+
|
62
|
+
end
|
63
|
+
end
|
data/test/example.rb
ADDED
@@ -0,0 +1,29 @@
|
|
1
|
+
require_relative "../lib/legion"
|
2
|
+
|
3
|
+
class Example < Legion::Object
|
4
|
+
|
5
|
+
def work(index)
|
6
|
+
sleep 2
|
7
|
+
end
|
8
|
+
|
9
|
+
before :work do
|
10
|
+
puts "before work"
|
11
|
+
end
|
12
|
+
|
13
|
+
end
|
14
|
+
|
15
|
+
def run_example
|
16
|
+
supervisor = Legion::Supervisor.new(Example, processes: 7)
|
17
|
+
supervisor.start_remote_instances(port: 42042)
|
18
|
+
|
19
|
+
1000.times do |i|
|
20
|
+
worker = supervisor.get_remote_instance
|
21
|
+
worker.work_async(i)
|
22
|
+
puts i
|
23
|
+
end
|
24
|
+
|
25
|
+
supervisor.stop_remote_instances
|
26
|
+
end
|
27
|
+
|
28
|
+
run_example
|
29
|
+
|
metadata
ADDED
@@ -0,0 +1,79 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: legion
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.1
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Nathan Hopkins
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2013-08-05 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: bundler
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - ~>
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '1.3'
|
20
|
+
type: :development
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - ~>
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '1.3'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: rake
|
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: True concurrent processing power made easy... even for MRI.
|
42
|
+
email:
|
43
|
+
- natehop@gmail.com
|
44
|
+
executables: []
|
45
|
+
extensions: []
|
46
|
+
extra_rdoc_files: []
|
47
|
+
files:
|
48
|
+
- lib/legion/object.rb
|
49
|
+
- lib/legion/supervisor.rb
|
50
|
+
- lib/legion/version.rb
|
51
|
+
- lib/legion.rb
|
52
|
+
- test/example.rb
|
53
|
+
homepage: https://github.com/hopsoft/legion
|
54
|
+
licenses:
|
55
|
+
- MIT
|
56
|
+
metadata: {}
|
57
|
+
post_install_message:
|
58
|
+
rdoc_options: []
|
59
|
+
require_paths:
|
60
|
+
- lib
|
61
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
62
|
+
requirements:
|
63
|
+
- - '>='
|
64
|
+
- !ruby/object:Gem::Version
|
65
|
+
version: '0'
|
66
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
67
|
+
requirements:
|
68
|
+
- - '>='
|
69
|
+
- !ruby/object:Gem::Version
|
70
|
+
version: '0'
|
71
|
+
requirements: []
|
72
|
+
rubyforge_project:
|
73
|
+
rubygems_version: 2.0.3
|
74
|
+
signing_key:
|
75
|
+
specification_version: 4
|
76
|
+
summary: True concurrent processing power made easy... even for MRI.
|
77
|
+
test_files:
|
78
|
+
- test/example.rb
|
79
|
+
has_rdoc:
|