SlideShare a Scribd company logo
Concurrent Programming with Ruby and Tuple Spaces Luc Castera Founder / messagepub.com
The Free Lunch is Over: A Fundamental Turn Toward Concurrency in Software Source: http://www.gotw.ca/publications/concurrency-ddj.htm “ The major processor manufacturers and architectures have run out of room with most of their traditional approaches to boosting CPU performance. Instead of driving clock speeds ands straight-line instruction throughput ever higher, they are instead turning en masse to hyperthreading and multicore architectures. […] And that puts us at a fundamental turning point in software development, at least for the next few years...” –  Herb Sutter –  March 2005
Outline 1. The problem with Ruby Threads 2. Multiple Ruby Processes 3. Inter-process Communication  with TupleSpaces
PART 1 The Problem With Threads A closer look at the Ruby threading model
3 Types of Threading Models: 1 : N 1 : 1 M : N
3 Types of Threading Models: 1 : N 1 : 1 M : N Kernel Threads User-Space Threads
1 : N -> Green Threads One kernel thread for N user threads aka “lightweight threads”
 
10 ms
10 ms
10 ms
10 ms
10 ms
10 ms
10 ms
10 ms
RUBY 1.8
Pros and Cons Pros: Thread creation, execution, and cleanup are cheap
Lots of threads can be created Cons: Not really parallel because kernel scheduler doesn't know about threads and can't schedule them across CPUs or take advantage of SMP
Blocking I/O operation can block all green threads Example: C Extension
Example: mysql gem (solution: NeverBlock mysqlplus)
blocking
1 : 1 -> Native Threads 1 kernel thread for each user thread
 
Pros and Cons Pros: Threads can execute on different CPUs (truly parallel)
Threads do not block each other Cons: Setup Overhead
Low limit on number of threads
Linux kernel bug with lots of threads
RUBY 1.9
I lied.
Global Interpreter Lock A Global Interpreter Lock (GIL) is a mutual exclusion lock held by a programming language interpreter thread to avoid sharing code that is not thread-safe with other threads. There is always one GIL for one interpreter process. Usage of a Global Interpreter Lock in a language effectively limits concurrency of a single interpreter process with multiple threads – there is no or very little increase in speed when running the process on a multiprocessor machine. Source:  Wikipedia
A person (male or female) who intentionally or unintentionally stops the progress of two others getting their game on.
 
“ Concurrency is a myth in Ruby” – Ilya Grigorik
Unless you are  using JRuby.
 
A note on Fibers Ruby 1.9 introduces fibers.
Fibers are green threads, but scheduling must be done by the programmer and not the VM.
Faster and cheaper then native threads.
Implemented for Ruby 1.8 by Aman Gupta.
Learn More: http://tinyurl.com/rubyfibers
http://all-thing.net/fibers
http://all-thing.net/fibers-via-continuations
M : N -> Hybrid Model M kernel threads for N user threads “ best of both worlds”
 
Pros and Cons Pros: Take advantage of multiple CPUs
Not all threads are blocked by blocking system calls
Cheap creation, execution, and cleanup Cons: Need scheduler in userland and kernel to work with each other
Green threads doing blocking I/O operations will block all other green threads sharing same kernel thread
Difficult to write, maintain, and debug code
 
“ Writing multi-threaded code is really, really hard. And it is hard because of Shared Memory.” –  Jim Weirich The Other Problem with Threads http://rubyconf2008.confreaks.com/what-all-rubyist-should-know-about-threads.html
Multi-Threaded Code is Hard + Concurrency is a myth = FAIL!
Stop thinking in threads Design your application to use multiple processes
PART 2 Multiple Ruby Processes
 
Pros and Cons Pros: No longer sharing memory
Take advantage of multiple CPUs (Performance)
Not all threads are blocked by blocking system calls.
Scalability
Fault-Tolerance Cons: Process creation, execution and cleanup is expensive
Uses a lot of memory (loading Ruby VM for every process)
Need a way for processes to communicate!
Latency Starting/Stopping Fault-Tolerance Monitoring
but we will focus on...
How do the processes communicate?
Options DRB
Sockets
Queues RabbitMQ
ActiveMQ Key-Value Databases Redis
Tokyo Cabinet
Memcached Relational Databases
XMPP
TupleSpaces
Examples
Rails + Mongrel/Thin Cluster of application servers (Mongrel, Thin...)
Communication between processes is done via the database.
Nanite A self-assembling fabric of Ruby daemons
http://github.com/ezmobius/nanite
Uses RabbitMQ/AMQP for IPC
Revactor Uses the actor model
Actors are kinda like threads, with messaging baked-in.
Each Actor has a mailbox.
It's like coding erlang in Ruby.
Messages are passed between actors using TCP sockets.
Good Documentation
http://revactor.org/
“ Erlang provides a sledgehammer for the problems of concurrent programming. But, sometimes you don't need a sledgehammer... just a flyswatter will do.” – Tony Arcieri
Discontinued for Reia
Journeta Journeta  is a dirt simple library for peer discovery  and message passing  between Ruby  applications on a LAN
Uses UDP Sockets for IPC
“ Uses the fucked up Ruby socket API” ->  from their RDOC Demo(?)

More Related Content

Concurrent Programming with Ruby and Tuple Spaces