Skip to content

Commit

Permalink
first commit
Browse files Browse the repository at this point in the history
  • Loading branch information
Ezra Zygmuntowicz committed Jan 2, 2010
0 parents commit 657c48f
Show file tree
Hide file tree
Showing 8 changed files with 198 additions and 0 deletions.
20 changes: 20 additions & 0 deletions LICENSE
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
Copyright (c) 2009 YOUR NAME

Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
"Software"), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to
the following conditions:

The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
61 changes: 61 additions & 0 deletions README.rdoc
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
== redactor

And Agent/Actor based system written around the Redis key value store.
Useful for coordination, command and control of distributed ruby processes

# simple getting started example

require 'redactor'

class Foo < RedActor::Actor

mailbox :foo
mailbox :bar

def recieve_foo(msg)
p [:recieve_foo, msg]
send_msg 'bar', msg
end

def recieve_bar(msg)
p [:recieve_bar, msg]
end

end


RedActor.run


Currently for each mailbox you declare we spin up a thread that does a
10 second timeout BLPOP against a redis list named after the mailbox. For each message in the mailbox we will instantiate on of your Foo actor objects and pass in the redis connection in the initialize method so that you can access @redis to talk to redis directly or use send_msg(mailbox, message) to send a message along to another actor. When you call mailbox :foo you need to define an instance method Foo#recieve_foo(msg)

TODO:
create actor registry where actors can register their capabilities to
allow for discovery of actors you want to subscribe to or send messages
to.

create a scoring system for allowing a pool of actors working off the same
mailbox and using the score to select where to route work

create a convention for identifying and passing work and data. use a
system where the publisher places JSON encoded data in a key:
# sending a mesage passing data on redis
token = rand_token()
@redis[token] = data.to_json
msg = "feed:#{token}"
send_msg :foo, msg

# on the recieving actor side:
mailbox :foo
def recieve_foo(msg)
type, data = msg.split(':')
data = JSON.parse(@redis[data])
case type
when 'feed'
process_feed(data)
when 'resize'
resize_image(data)
end
end

57 changes: 57 additions & 0 deletions Rakefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
require 'rubygems'
require 'rake/gempackagetask'
require 'rubygems/specification'
require 'date'
require 'spec/rake/spectask'

GEM = "redactor"
GEM_VERSION = "0.0.1"
AUTHOR = "Ezra Zygmuntowicz"
EMAIL = "ez@engineyard.com"
HOMEPAGE = ""
SUMMARY = "And Actor/Agent library based on Redis key value store"

spec = Gem::Specification.new do |s|
s.name = GEM
s.version = GEM_VERSION
s.platform = Gem::Platform::RUBY
s.has_rdoc = true
s.extra_rdoc_files = ["README", "LICENSE", 'TODO']
s.summary = SUMMARY
s.description = s.summary
s.author = AUTHOR
s.email = EMAIL
s.homepage = HOMEPAGE

# Uncomment this to add a dependency
s.add_dependency "redis"

s.require_path = 'lib'
s.autorequire = GEM
s.files = %w(LICENSE README Rakefile TODO) + Dir.glob("{lib,spec}/**/*")
end

task :default => :spec

desc "Run specs"
Spec::Rake::SpecTask.new do |t|
t.spec_files = FileList['spec/**/*_spec.rb']
t.spec_opts = %w(-fs --color)
end


Rake::GemPackageTask.new(spec) do |pkg|
pkg.gem_spec = spec
end

desc "install the gem locally"
task :install => [:package] do
sh %{sudo gem install pkg/#{GEM}-#{GEM_VERSION}}
end

desc "create a gemspec file"
task :make_spec do
File.open("#{GEM}.gemspec", "w") do |file|
file.puts spec.to_ruby
end
end
4 changes: 4 additions & 0 deletions TODO
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
TODO:
Fix LICENSE with your name
Fix Rakefile with your name and contact info
Add your code to lib/<%= name %>.rb
17 changes: 17 additions & 0 deletions lib/redactor.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
require 'rubygems'
require 'redis'
require 'json'
require 'redactor/actor'

module RedActor
class << self
attr_accessor :redis_options, :threads

def run(opts={})
opts[:timeout] ||= 15
RedActor.redis_options = opts
RedActor.threads.each {|t| t.join }
end
end
end

30 changes: 30 additions & 0 deletions lib/redactor/actor.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
module RedActor

class Actor
class << self
def mailbox(queue)
thread = Thread.new do
sleep 0.1 until RedActor.redis_options
redis = Redis.new(RedActor.redis_options)
loop do
msg = redis.blpop(queue, 10)
if msg
self.new(redis).__send__("recieve_#{queue}", msg)
end
end
end
RedActor.threads ||= []
RedActor.threads << thread
end
end

def initialize(redis)
@redis = redis
end


def send_msg(mailbox, msg)
@redis.rpush(mailbox, msg)
end
end
end
7 changes: 7 additions & 0 deletions spec/redactor_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
require File.dirname(__FILE__) + '/spec_helper'

describe "redactor" do
it "should do nothing" do
true.should == true
end
end
2 changes: 2 additions & 0 deletions spec/spec_helper.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
$TESTING=true
$:.push File.join(File.dirname(__FILE__), '..', 'lib')

0 comments on commit 657c48f

Please sign in to comment.