tribe 0.0.4 → 0.0.5

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.
Files changed (5) hide show
  1. data/README.md +82 -1
  2. data/Rakefile +4 -97
  3. data/lib/tribe/version.rb +1 -1
  4. data/tribe.gemspec +1 -1
  5. metadata +2 -8
data/README.md CHANGED
@@ -1,6 +1,7 @@
1
1
  # Tribe
2
2
 
3
- Actor Model for Ruby. Currently experimental and not recommend for production.
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
- #!/usr/bin/env rake
2
- require 'bundler/gem_tasks'
3
- require 'benchmark'
1
+ require "bundler/gem_tasks"
4
2
 
5
- begin
6
- Bundler.setup(:default, :development)
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
- desc 'Start an IRB console with offier loaded'
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
@@ -1,3 +1,3 @@
1
1
  module Tribe
2
- VERSION = '0.0.4'
2
+ VERSION = '0.0.5'
3
3
  end
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 designed for high performance.}
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
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 designed for high performance.
73
+ summary: Event driven actors for Ruby
80
74
  test_files: []