Created
November 20, 2012 04:05
-
-
Save MarkBennett/4115894 to your computer and use it in GitHub Desktop.
Celluloid Talk
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
_____ _ _ _ _ _ | |
/ __ \ | | | | | (_) | | | |
| / \/ ___| | |_ _| | ___ _ __| | | |
| | / _ \ | | | | | |/ _ \| |/ _` | | |
| \__/\ __/ | | |_| | | (_) | | (_| | | |
\____/\___|_|_|\__,_|_|\___/|_|\__,_| | |
> Painless multithreaded programming for Ruby < | |
_____ _ _ ___ | |
|_ _| | | | |__ \ | |
| | | |__ _ __ ___ __ _ __| |___ ) | | |
| | | '_ \| '__/ _ \/ _` |/ _` / __|/ / | |
| | | | | | | | __/ (_| | (_| \__ \_| | |
\_/ |_| |_|_| \___|\__,_|\__,_|___(_) | |
require 'thread' | |
mutex = Mutex.new | |
count1 = count2 = 0 | |
difference = 0 | |
a = Thread.new { | |
loop do | |
mutex.synchronize do | |
count1 += 1 | |
count2 += 1 | |
end | |
end | |
} | |
spy = Thread.new { | |
loop do | |
mutex.synchronize do | |
difference += (count1 - count2).abs | |
end | |
end | |
} | |
_____ _ _ _ | |
|_ _| | | | | | | |
| | | |__ _ __ ___ __ _ __| |___| | | |
| | | '_ \| '__/ _ \/ _` |/ _` / __| | | |
| | | | | | | | __/ (_| | (_| \__ \_| | |
\_/ |_| |_|_| \___|\__,_|\__,_|___(_) | |
* Mutexes, locks, conditional variables | |
* Confusing and hard to debug | |
_ _ _____ _____ _ _ ______ _____ ___ ______ _____ | |
| \ | | _ | |_ _| | | || ___ \ ___|/ _ \| _ \/ ___| | |
| \| | | | | | | | |_| || |_/ / |__ / /_\ \ | | |\ `--. | |
| . ` | | | | | | | _ || /| __|| _ | | | | `--. \ | |
| |\ \ \_/ / | | | | | || |\ \| |___| | | | |/ / /\__/ / | |
\_| \_/\___/ \_/ \_| |_/\_| \_\____/\_| |_/___/ \____/ | |
___ _ ___ ___ _ _____ ___ | |
/ _ \ | \ | \ \ / / | | |/ _ \ \ / / | | |
/ /_\ \| \| |\ V /| | | / /_\ \ V /| | | |
| _ || . ` | \ / | |/\| | _ |\ / | | | |
| | | || |\ | | | \ /\ / | | || | |_| | |
\_| |_/\_| \_/ \_/ \/ \/\_| |_/\_/ (_) | |
* Unless you use jRuby, Rubinius, et al. | |
_____ _ _ ___ | |
| _ | | | (_) |__ \ | |
| | | |_ __ | |_ _ ___ _ __ ___ ) | | |
| | | | '_ \| __| |/ _ \| '_ \/ __|/ / | |
\ \_/ / |_) | |_| | (_) | | | \__ \_| | |
\___/| .__/ \__|_|\___/|_| |_|___(_) | |
| | | |
|_| | |
_____ _ _ _ | |
|_ _| | | | | | | | |
| | _ __ ___ _ __ ___ _ _| |_ __ _| |__ | | ___ | |
| || '_ ` _ \| '_ ` _ \| | | | __/ _` | '_ \| |/ _ \ | |
_| || | | | | | | | | | | |_| | || (_| | |_) | | __/ | |
\___/_| |_| |_|_| |_| |_|\__,_|\__\__,_|_.__/|_|\___| | |
* Lisp, Clojure style | |
* Just don't share any state and things are easy | |
* Most Ruby code isn't written to work this way | |
_____ _ ______ _ | |
| ___| | | | ___ \ | | | |
| |____ _____ _ __ | |_ | |_/ /___ __ _ ___| |_ ___ _ __ | |
| __\ \ / / _ \ '_ \| __| | // _ \/ _` |/ __| __/ _ \| '__| | |
| |___\ V / __/ | | | |_ | |\ \ __/ (_| | (__| || (_) | | | |
\____/ \_/ \___|_| |_|\__| \_| \_\___|\__,_|\___|\__\___/|_| | |
* node.js, EventMachine, Golliath | |
* Make everything events in a continuous queue | |
* Mostly still single threaded, multi-process | |
* Lots of callbacks | |
* One large event handler wrecks the whole show | |
___ _ ______ _ _ | |
/ _ \ | | | ___ \ | | | | | |
/ /_\ \ ___| |_ ___ _ __ | |_/ /_ _| |_| |_ ___ _ __ _ __ ___ | |
| _ |/ __| __/ _ \| '__| | __/ _` | __| __/ _ \ '__| '_ \/ __| | |
| | | | (__| || (_) | | | | | (_| | |_| || __/ | | | | \__ \ | |
\_| |_/\___|\__\___/|_| \_| \__,_|\__|\__\___|_| |_| |_|___/ | |
* Erlang, Celluloid, ATOM in Python | |
* Actors send and receive messages | |
* Queue up messages in mailboxes | |
* Actors are supervised | |
_____ _ | |
| ___| | | | |
| |____ ____ _ _ __ ___ _ __ | | ___ ___ | |
| __\ \/ / _` | '_ ` _ \| '_ \| |/ _ \/ __| | |
| |___> < (_| | | | | | | |_) | | __/\__ \ | |
\____/_/\_\__,_|_| |_| |_| .__/|_|\___||___/ | |
| | | |
|_| | |
* assume we require 'celluloid' in all examples | |
* won't show to save some space | |
___ _ | |
/ _ \ | | | |
/ /_\ \ ___| |_ ___ _ __ ___ | |
| _ |/ __| __/ _ \| '__/ __| | |
| | | | (__| || (_) | | \__ \ | |
\_| |_/\___|\__\___/|_| |___/ | |
class Sheen | |
include Celluloid | |
def initialize(name) | |
@name = name | |
end | |
def set_status(status) | |
@status = status | |
end | |
def report | |
"#{@name} is #{@status}" | |
end | |
end | |
charlie = Sheen.new("Charlie") | |
charlie.set_status("winning") # => "winning" | |
charlie.report # => "Charlie is winning" | |
charlie.async.set_status("asynchronously winning") # => nil | |
charlie.report # => "Charlie is asynchronously winning" | |
______ _ _ | |
| ___| (_) | | |
| |_ __ _ _| |_ _ _ __ ___ | |
| _/ _` | | | | | | '__/ _ \ | |
| || (_| | | | |_| | | | __/ | |
\_| \__,_|_|_|\__,_|_| \___| | |
class JamesDean | |
include Celluloid | |
class CarInMyLaneError < StandardError; end | |
def drive_little_bastard | |
raise CarInMyLaneError, "that guy's gotta stop. he'll see us" | |
end | |
end | |
james = JamesDean.new | |
james.drive_little_bastard # James is now dead | |
james.inspect # Raises attempt to call a dead actor | |
james = JamesDean.new | |
james.async.drive_little_bastard # Returns nil | |
james.inspect # He's still dead though! | |
_ _ _ _ | |
| | (_) | | (_) | |
| | _ _ __ | | ___ _ __ __ _ | |
| | | | '_ \| |/ / | '_ \ / _` | | |
| |___| | | | | <| | | | | (_| | | |
\_____/_|_| |_|_|\_\_|_| |_|\__, | | |
__/ | | |
|___/ | |
* One actor cares about the fate of another | |
class ElizabethTaylor | |
include Celluloid | |
trap_exit :actor_died | |
def actor_died(actor, reason) | |
p "Oh no! #{actor.inspect} has died because of a #{reason.class}" | |
end | |
end | |
james = JamesDean.new | |
liz = ElizabethTaylor.new | |
liz.link james | |
james.async.drive_little_bastard # Liz is mortified! | |
______ _ | |
| ___| | | | |
| |_ _ _| |_ _ _ _ __ ___ ___ | |
| _| | | | __| | | | '__/ _ \/ __| | |
| | | |_| | |_| |_| | | | __/\__ \ | |
\_| \__,_|\__|\__,_|_| \___||___/ | |
* Get what you ask for | |
future = charle.future.report # Create a future | |
future.value # Block until the future returns a value | |
class SlowLoris | |
include Celluloid | |
def slow_to_move | |
sleep 5 | |
"Hello!" | |
end | |
end | |
loris = SlowLoris.new | |
future = loris.future.slow_to_move # The future starts working now | |
future.value # But doesn't return until now | |
_____ _ _ | |
/ ___| (_) (_) | |
\ `--. _ _ _ __ ___ _ ____ ___ ___ _ ___ _ __ | |
`--. \ | | | '_ \ / _ \ '__\ \ / / / __| |/ _ \| '_ \ | |
/\__/ / |_| | |_) | __/ | \ V /| \__ \ | (_) | | | | | |
\____/ \__,_| .__/ \___|_| \_/ |_|___/_|\___/|_| |_| | |
| | | |
|_| | |
* The show must go on | |
* Keep your actors in line | |
supervisor = JamesDean.supervise | |
james = supervisor.actors.first # => #<Celluloid::Actor(JamesDean:0x96e)> | |
james.drive_little_bastard # Dead again! | |
supervisor.actors.first # => #<Celluloid::Actor(JamesDean:0x96f)> | |
... | |
supervisor.actors.first # => #<Celluloid::Actor(JamesDean:0x970)> | |
... | |
supervisor.actors.first # => #<Celluloid::Actor(JamesDean:0x971)> | |
______ _ | |
| ___ \ | | | |
| |_/ /__ ___ | |___ | |
| __/ _ \ / _ \| / __| | |
| | | (_) | (_) | \__ \ | |
\_| \___/ \___/|_|___/ | |
* Actors love a pool (party!) | |
class MyWorker | |
include Celluloid | |
def add_one(number) | |
# roflscale computation goes here | |
number + 1 | |
end | |
end | |
pool = MyWorker.pool | |
i_am_three = pool.add_one(2) | |
___ ___ | |
| \/ | | |
| . . | ___ _ __ ___ | |
| |\/| |/ _ \| '__/ _ \ | |
| | | | (_) | | | __/_ _ _ | |
\_| |_/\___/|_| \___(_|_|_) | |
* http://celluloid.io/ | |
* https://github.com/celluloid/celluloid/wiki | |
_____ _ _ _ | |
|_ _| | | | | | | |
| | | |__ __ _ _ __ | | _____| | | |
| | | '_ \ / _` | '_ \| |/ / __| | | |
| | | | | | (_| | | | | <\__ \_| | |
\_/ |_| |_|\__,_|_| |_|_|\_\___(_) | |
* Tony Arcieri --> https://github.com/tarcieri | |
* me --> https://twitter.com/markbennett |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment