diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..4a99f6f --- /dev/null +++ b/LICENSE @@ -0,0 +1,58 @@ +Ruby is copyrighted free software by Yukihiro Matsumoto . +You can redistribute it and/or modify it under either the terms of the GPL +(see COPYING.txt file), or the conditions below: + + 1. You may make and give away verbatim copies of the source form of the + software without restriction, provided that you duplicate all of the + original copyright notices and associated disclaimers. + + 2. You may modify your copy of the software in any way, provided that + you do at least ONE of the following: + + a) place your modifications in the Public Domain or otherwise + make them Freely Available, such as by posting said + modifications to Usenet or an equivalent medium, or by allowing + the author to include your modifications in the software. + + b) use the modified software only within your corporation or + organization. + + c) rename any non-standard executables so the names do not conflict + with standard executables, which must also be provided. + + d) make other distribution arrangements with the author. + + 3. You may distribute the software in object code or executable + form, provided that you do at least ONE of the following: + + a) distribute the executables and library files of the software, + together with instructions (in the manual page or equivalent) + on where to get the original distribution. + + b) accompany the distribution with the machine-readable source of + the software. + + c) give non-standard executables non-standard names, with + instructions on where to get the original software distribution. + + d) make other distribution arrangements with the author. + + 4. You may modify and include the part of the software into any other + software (possibly commercial). But some files in the distribution + are not written by the author, so that they are not under this terms. + + They are gc.c(partly), utils.c(partly), regex.[ch], st.[ch] and some + files under the ./missing directory. See each file for the copying + condition. + + 5. The scripts and library files supplied as input to or produced as + output from the software do not automatically fall under the + copyright of the software, but belong to whomever generated them, + and may be sold commercially, and may be aggregated with this + software. + + 6. THIS SOFTWARE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR + IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED + WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + PURPOSE. + diff --git a/Rakefile b/Rakefile new file mode 100644 index 0000000..de7e76c --- /dev/null +++ b/Rakefile @@ -0,0 +1,48 @@ +require 'rake' +require 'rake/rdoctask' +require 'rake/gempackagetask' +load 'revactor.gemspec' + +# Default Rake task +task :default => :rdoc + +# RDoc +Rake::RDocTask.new(:rdoc) do |task| + task.rdoc_dir = 'doc' + task.title = 'Revactor' + task.options = %w(--title Revactor --main README --line-numbers) + task.rdoc_files.include('bin/**/*.rb') + task.rdoc_files.include('lib/**/*.rb') + task.rdoc_files.include('README') +end + +# Gem +Rake::GemPackageTask.new(GEMSPEC) do |pkg| + pkg.need_tar = true +end + +# RSpec +begin +require 'spec/rake/spectask' + +SPECS = FileList['spec/**/*_spec.rb'] + +Spec::Rake::SpecTask.new(:spec) do |task| + task.spec_files = SPECS +end + +namespace :spec do + Spec::Rake::SpecTask.new(:print) do |task| + task.spec_files = SPECS + task.spec_opts="-f s".split + end + + Spec::Rake::SpecTask.new(:rcov) do |task| + task.spec_files = SPECS + task.rcov = true + task.rcov_opts = ['--exclude', 'spec'] + end +end + +rescue LoadError +end diff --git a/lib/revactor.rb b/lib/revactor.rb index 1dc2788..c2343c4 100644 --- a/lib/revactor.rb +++ b/lib/revactor.rb @@ -6,6 +6,7 @@ require 'rubygems' require 'rev' +require 'case' # This is mostly in hopes of a bright future with Rubinius # The recommended container for all datagrams sent between diff --git a/lib/revactor/actor.rb b/lib/revactor/actor.rb index ec12b74..c397666 100644 --- a/lib/revactor/actor.rb +++ b/lib/revactor/actor.rb @@ -27,9 +27,6 @@ class ActorError < StandardError; end # class Actor < Fiber include Enumerable - - # Actor::ANY_MESSAGE can be used in a filter match any message - ANY_MESSAGE = Object unless defined? Actor::ANY_MESSAGE @@registered = {} class << self diff --git a/lib/revactor/server.rb b/lib/revactor/server.rb index 5893233..2ad0049 100644 --- a/lib/revactor/server.rb +++ b/lib/revactor/server.rb @@ -54,7 +54,7 @@ def start @running = true while @running do Actor.receive do |filter| - filter.when(Actor::ANY_MESSAGE) { |message| handle_message(message) } + filter.when(Object) { |message| handle_message(message) } filter.after(@timeout) { stop(:timeout) } if @timeout end end diff --git a/revactor.gemspec b/revactor.gemspec new file mode 100644 index 0000000..da7bf57 --- /dev/null +++ b/revactor.gemspec @@ -0,0 +1,27 @@ +require 'rubygems' + +GEMSPEC = Gem::Specification.new do |s| + s.name = "revactor" + s.version = "0.1.0" + s.authors = "Tony Arcieri" + s.email = "tony@medioh.com" + s.date = "2008-1-15" + s.summary = "Revactor is an Actor implementation for writing high performance concurrent programs" + s.platform = Gem::Platform::RUBY + + # Gem contents + s.files = Dir.glob("{bin,lib,conf,status}/**/*") + ['Rakefile', 'revactor.gemspec'] + + # Dependencies + s.add_dependency("rev", ">= 0.1.2") + s.add_dependency("case", ">= 0.1") + + # RubyForge info + s.homepage = "http://revactor.org" + s.rubyforge_project = "revactor" + + # RDoc settings + s.has_rdoc = true + s.rdoc_options = %w(--title Revactor --main README --line-numbers) + s.extra_rdoc_files = ["LICENSE", "README", "CHANGES"] +end diff --git a/tools/messaging_throughput.rb b/tools/messaging_throughput.rb new file mode 100644 index 0000000..acb0154 --- /dev/null +++ b/tools/messaging_throughput.rb @@ -0,0 +1,33 @@ +require File.dirname(__FILE__) + '/../lib/revactor' + +NTIMES=100000 + +begin_time = Time.now + +puts "#{begin_time.strftime('%H:%M:%S')} -- Sending #{NTIMES} messages" + +Actor.start do + parent = Actor.current + child = Actor.spawn do + (NTIMES / 2).times do + Actor.receive do |f| + f.when(:foo) { parent << :bar } + end + end + end + + child << :foo + (NTIMES / 2).times do + Actor.receive do |f| + f.when(:bar) { child << :foo } + end + end +end + +end_time = Time.now +duration = end_time - begin_time +throughput = NTIMES / duration + +puts "#{end_time.strftime('%H:%M:%S')} -- Finished" +puts "Duration: #{sprintf("%0.2f", duration)} seconds" +puts "Throughput: #{sprintf("%0.2f", throughput)} messages per second"