tribe 0.0.4 → 0.0.5
Sign up to get free protection for your applications and to get access to all the features.
- data/README.md +82 -1
- data/Rakefile +4 -97
- data/lib/tribe/version.rb +1 -1
- data/tribe.gemspec +1 -1
- metadata +2 -8
data/README.md
CHANGED
@@ -1,6 +1,7 @@
|
|
1
1
|
# Tribe
|
2
2
|
|
3
|
-
|
3
|
+
Tribe is a Ruby gem that implements event driven actors.
|
4
|
+
Actors are light weight concurrent objects that use asynchronous message passing for communication.
|
4
5
|
|
5
6
|
## Installation
|
6
7
|
|
@@ -16,6 +17,86 @@ Or install it yourself as:
|
|
16
17
|
|
17
18
|
$ gem install tribe
|
18
19
|
|
20
|
+
## Actors
|
21
|
+
|
22
|
+
# Create your custom actor class.
|
23
|
+
class MyActor < Tribe::Actor
|
24
|
+
private
|
25
|
+
def initialize(options = {})
|
26
|
+
super
|
27
|
+
end
|
28
|
+
|
29
|
+
def process_event(event)
|
30
|
+
case event.command
|
31
|
+
when :my_custom
|
32
|
+
my_custom_handler(event)
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
def my_custom_handler(event)
|
37
|
+
puts "Received a custom event (#{event.inspect})"
|
38
|
+
end
|
39
|
+
|
40
|
+
def exception_handler(e)
|
41
|
+
puts concat_e("MyActor (#{identifier}) died.", e)
|
42
|
+
end
|
43
|
+
|
44
|
+
def shutdown_handler(event)
|
45
|
+
puts "MyActor (#{identifier}) is shutting down. Put cleanup code here."
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
# Create some named actors.
|
50
|
+
100.times do |i|
|
51
|
+
MyActor.new(:name => "my_actor_#{i}")
|
52
|
+
end
|
53
|
+
|
54
|
+
# Send an event to each actors. Find each actor using the registry.
|
55
|
+
100.times do |i|
|
56
|
+
actor = Tribe.registry["my_actor_#{i}"]
|
57
|
+
actor.enqueue(:my_custom, 'hello world')
|
58
|
+
end
|
59
|
+
|
60
|
+
# Shutdown the actors.
|
61
|
+
100.times do |i|
|
62
|
+
actor = Tribe.registry["my_actor_#{i}"]
|
63
|
+
actor.enqueue(:shutdown)
|
64
|
+
end
|
65
|
+
|
66
|
+
### Implementation notes
|
67
|
+
Because actors use a shared thread pool, it is important that they don't block for long periods of time.
|
68
|
+
Actors that block for long periods of time should use a dedicated thread (:dedicated => true or subclass from Tribe::DedicatedActor).
|
69
|
+
|
70
|
+
## Registries
|
71
|
+
|
72
|
+
Registries hold references to named actors.
|
73
|
+
In general you shouldn't have to create your own since there is a global one (Tribe.registry).
|
74
|
+
|
75
|
+
## Options (defaults below):
|
76
|
+
|
77
|
+
actor = Tribe::Actor.new(
|
78
|
+
:logger => nil, # Ruby logger instance.
|
79
|
+
:dedicated => false, # If true, the actor runs with a worker pool that has one thread.
|
80
|
+
:pool => Workers.pool, # The workers pool used to execute events.
|
81
|
+
:mailbox => Tribe::Mailbox.new, # The mailbox used to receive events.
|
82
|
+
:registry => Tribe.registry, # The registry used to store a reference to the actor if it has a name.
|
83
|
+
:name => nil # The name of the actor (must be unique in the registry).
|
84
|
+
)
|
85
|
+
|
86
|
+
actor = Tribe::DedicatedActor.new(
|
87
|
+
:logger => nil, # Ruby logger instance.
|
88
|
+
:mailbox => Tribe::Mailbox.new, # The mailbox used to receive events.
|
89
|
+
:registry => Tribe.registry, # The registry used to store a reference to the actor if it has a name.
|
90
|
+
:name => nil # The name of the actor (must be unique in the registry).
|
91
|
+
)
|
92
|
+
|
93
|
+
## TODO - missing features
|
94
|
+
|
95
|
+
- Futures.
|
96
|
+
- Workers::Timer integration.
|
97
|
+
- Supervisors.
|
98
|
+
- Linking.
|
99
|
+
|
19
100
|
## Contributing
|
20
101
|
|
21
102
|
1. Fork it
|
data/Rakefile
CHANGED
@@ -1,106 +1,13 @@
|
|
1
|
-
|
2
|
-
require 'bundler/gem_tasks'
|
3
|
-
require 'benchmark'
|
1
|
+
require "bundler/gem_tasks"
|
4
2
|
|
5
|
-
|
6
|
-
|
7
|
-
rescue Bundler::BundlerError => e
|
8
|
-
$stderr.puts(e.message)
|
9
|
-
$stderr.puts("Run `bundle install` to install missing gems")
|
10
|
-
exit e.status_code
|
11
|
-
end
|
12
|
-
|
13
|
-
task :environment do
|
3
|
+
desc 'Start an IRB console with Workers loaded'
|
4
|
+
task :console do
|
14
5
|
$LOAD_PATH.unshift(File.join(File.dirname(__FILE__), 'lib'))
|
15
|
-
require 'tribe'
|
16
|
-
end
|
17
6
|
|
18
|
-
|
19
|
-
task :console => :environment do
|
7
|
+
require 'tribe'
|
20
8
|
require 'irb'
|
21
9
|
|
22
10
|
ARGV.clear
|
23
11
|
|
24
12
|
IRB.start
|
25
13
|
end
|
26
|
-
|
27
|
-
desc 'Demo mode (temporary)'
|
28
|
-
task :demo => :environment do
|
29
|
-
$demo_queue = Queue.new
|
30
|
-
$demo_mutex = Mutex.new
|
31
|
-
|
32
|
-
def locked_puts(msg)
|
33
|
-
$demo_mutex.synchronize { puts msg }
|
34
|
-
end
|
35
|
-
|
36
|
-
DEMO_ACTOR_COUNT = 100
|
37
|
-
DEMO_MSG_COUNT = 3000
|
38
|
-
|
39
|
-
class MyActor < Tribe::Actor
|
40
|
-
|
41
|
-
def pre_init
|
42
|
-
reset_count
|
43
|
-
end
|
44
|
-
|
45
|
-
def increment
|
46
|
-
@count += 1
|
47
|
-
|
48
|
-
if @count >= DEMO_MSG_COUNT
|
49
|
-
locked_puts("#{@name} done.")
|
50
|
-
$demo_queue.push(@name)
|
51
|
-
end
|
52
|
-
end
|
53
|
-
|
54
|
-
def reset_count
|
55
|
-
@count = 0
|
56
|
-
end
|
57
|
-
|
58
|
-
def go(friend_name)
|
59
|
-
friend = Tribe.registry[friend_name]
|
60
|
-
|
61
|
-
DEMO_MSG_COUNT.times do
|
62
|
-
friend.increment!
|
63
|
-
end
|
64
|
-
end
|
65
|
-
end
|
66
|
-
|
67
|
-
def tribe_demo
|
68
|
-
actors = []
|
69
|
-
|
70
|
-
locked_puts('Create actors...')
|
71
|
-
(0...DEMO_ACTOR_COUNT).each do |i|
|
72
|
-
name = i.to_s
|
73
|
-
actor = Tribe.registry[name] || MyActor.new(:name => name)
|
74
|
-
actors.push(actor)
|
75
|
-
locked_puts(name)
|
76
|
-
end
|
77
|
-
|
78
|
-
locked_puts('Resetting...')
|
79
|
-
actors.each do |actor|
|
80
|
-
actor.reset_count!
|
81
|
-
end
|
82
|
-
|
83
|
-
locked_puts('Go...')
|
84
|
-
actors.each do |actor|
|
85
|
-
friend = actor.name.to_i
|
86
|
-
friend += 1
|
87
|
-
friend = 0 if friend == DEMO_ACTOR_COUNT
|
88
|
-
friend = friend.to_s
|
89
|
-
|
90
|
-
locked_puts("pair: #{actor.name}, #{friend}")
|
91
|
-
actor.go!(friend)
|
92
|
-
end
|
93
|
-
|
94
|
-
locked_puts('Benchmark...')
|
95
|
-
result = Benchmark.realtime do
|
96
|
-
DEMO_ACTOR_COUNT.times do
|
97
|
-
$demo_queue.pop
|
98
|
-
end
|
99
|
-
end
|
100
|
-
|
101
|
-
nil
|
102
|
-
end
|
103
|
-
|
104
|
-
tribe_demo
|
105
|
-
end
|
106
|
-
|
data/lib/tribe/version.rb
CHANGED
data/tribe.gemspec
CHANGED
@@ -5,7 +5,7 @@ Gem::Specification.new do |gem|
|
|
5
5
|
gem.authors = ["Chad Remesch"]
|
6
6
|
gem.email = ["chad@remesch.com"]
|
7
7
|
gem.description = %q{Event driven actors for Ruby}
|
8
|
-
gem.summary = %q{Event driven actors for Ruby
|
8
|
+
gem.summary = %q{Event driven actors for Ruby}
|
9
9
|
gem.homepage = ""
|
10
10
|
|
11
11
|
gem.files = `git ls-files`.split($\)
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: tribe
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.5
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -59,22 +59,16 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
59
59
|
- - ! '>='
|
60
60
|
- !ruby/object:Gem::Version
|
61
61
|
version: '0'
|
62
|
-
segments:
|
63
|
-
- 0
|
64
|
-
hash: 2679671106278227985
|
65
62
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
66
63
|
none: false
|
67
64
|
requirements:
|
68
65
|
- - ! '>='
|
69
66
|
- !ruby/object:Gem::Version
|
70
67
|
version: '0'
|
71
|
-
segments:
|
72
|
-
- 0
|
73
|
-
hash: 2679671106278227985
|
74
68
|
requirements: []
|
75
69
|
rubyforge_project:
|
76
70
|
rubygems_version: 1.8.24
|
77
71
|
signing_key:
|
78
72
|
specification_version: 3
|
79
|
-
summary: Event driven actors for Ruby
|
73
|
+
summary: Event driven actors for Ruby
|
80
74
|
test_files: []
|