Building Scalable Systems Safely in Ruby with Samuel Williams

Samuel Williams explains the difference between concurrency and parallelism, the dangers of writing multi-threaded code, how languages like Node, Go, and Erlang safely handle parallelism, and how to build scalable systems safely.

Samuel is a member of the Ruby core team.  He's working on making it safer and easier to write scalable applications in Ruby.

Conference Talks:
Fibers are the Right Solution
The Journey to One Million

Posts:
Asynchronous Ruby
Fibers Are the Right Solution
Early Hints and HTTP/2 Push with Falcon
2019 Ruby Association Grant
Source with comments on why the Global VM Lock exists

Ruby gems:
Async
Falcon

Contact:
@ioquatix
Samuel's website

Timestamps:
  • 0:51 - What's concurrency? What's parallelism?
  • 5:49 - Piping commands between Unix processes provides easy parallelism
  • 6:58 - Some types of applications abstract out threads/processes,
  • 9:27 - Many Ruby gems have thread safety issues
  • 10:44 - The CRuby Global VM Lock hides thread safety issues
  • 11:24 - The problems with threads and shared mutable state
  • 13:58 - Examples of mutexes causing problems in Ruby gems.
  • 19:09 - What a deadlock is and how it causes problems
  • 19:51 - Running separate processes to get parallelism and using an external database to communicate
  • 21:01 -  Lightweight process model used by Go and Erlang vs threads in Ruby
  • 23:50 - Why async was created
  • 24:38 - What is Celluloid? (Actor based concurrency for Ruby)
  • 26:29 - Problems with shared global state in Celluloid
  • 27:12 -  Lifecycle management problems (getting and cleaning up objects)
  • 28:19 - Maintaining Celluloid IO, issues with the library
  • 29:43 - What's async?
  • 32:00 - What's an event loop?
  • 35:20 - How tasks execute in an event loop
  • 37:29 - How IO tasks are scheduled with IO.select
  • 39:41 - The importance of predictable and sequential code
  • 41:48 - Comparing async library to async/await
  • 45:23 - What node got right with its worker model
  • 47:10 - How async/await works
  • 48:35 - Fibers as an alternative to callbacks
  • 51:10 - How async uses fibers, minimizes need to change code
  • 56:19 - Libraries don't have to know they're using async
  • 1:04:55 - Reasons for the CRuby Global VM Lock
  • 1:07:13 - Guilds as a solution
  • 1:09:14 - Sharing state across threads
  • 1:11:33 - Limitations of Ruby GC at 10-20K connections
  • 1:12:00 - Sharing state across processes
  • 1:13:12 - Handling CPU bound tasks with threads and processes
  • 1:17:42 - Which dependencies are messing with state? (Check memory allocations, sockets closed)
  • 1:25:00 - Async in production
  • 1:27:17 - Wrap up