The reduced, 30 minutes version of this collection of Ruby Systems Horror Stories, including:
- Mark & Sweep, a tale of a dumb garbage collector - Our Time is Running Out, a tale of tricky timeouts
Originally presented at Rubyfuza.
View Slide
Once upona time…
These arehorror storiesfrom theGitHub Systems team(the rainbows are just to make them less awful)
I HAVE ALOTOF SPARETIME
Ogre Magi is (C) 2013 by Valve Software and takes 0 skill to play
Mark SweepThe Garba eCollector
Garba e Collector
ConservativeGarba e Collector
ConservativeGarba e CollectorNon-deterministic
ConservativeStop The WorldGarba e CollectorNon-deterministic
ConservativeStop The WorldMark and SweepGarba e CollectorNon-deterministic
ConservativeStop The WorldMark and SweepGarba e CollectorNon-deterministicBasically a shitshow.
Mark
Mark 1. Walk theobject raph2. Look forthin s thatlook likeRuby objects
Ruby handles raw pointersto C extensions.
Ruby handles raw pointersto C extensions.The Garba e Collector must findroots in the stack, the heap andin re isters.
“This kinda looks like a pointer”
“This kinda looks like a pointer”“I uess…”
“This kinda looks like a pointer”“I uess…”*dramatization
Sweep
Sweep1. Go throu hevery sin leobject2. Free theones thathave not beenmarked
The Problem
The ProblemThere is memory allocated byRuby that the Ruby GC cannotdetect.
char *VALUE *……RStrinMAGICALRUBYTHINGSint a_ruby_function(VALUE rb_foo){char *str = RSTRING_PTR(rb_foo);return do_smthing(str);}
char *VALUE *……RStrinMAGICALRUBYTHINGSint a_ruby_function(VALUE rb_foo){char *str = RSTRING_PTR(rb_foo);return do_smthing(str);}H e l l o W o r l d \0
char *……H e l l o W o r l d \0int do_smthing(char *str){/* do stuff */return strlen(str);}
int do_smthing(char *str){/* do stuff */return strlen(str);}Un ! Un ! Mark o throu hstack. Yes. Stack.
Un ! This no look likeRuby object. Mark no touchie!char *………H e l l o W o r l d \0
No root.H e l l o W o r l d \0RStrinMAGICALRUBYTHINGSStrin object with no roots?Set fire. Yes. Fire.
No root.H e l l o W o r l d \0Strin object with no roots?Set fire. Yes. Fire.
No root.Strin object with no roots?Set fire. Yes. Fire.
int do_smthing(char *str){/* do stuff */return strlen(str);}
int do_smthing(char *str){/* do stuff */return strlen(str);}*sound of an explosion*“What was that?”“Dunno.”
HAPPYENDINGS:(sorry about this slide)
1. DrinkYourself ToSleep EveryNi ht
2. Stress theGarba eCollector inCritical Paths
mallopt(M_PERTURB, 0x33);C land
mallopt(M_PERTURB, 0x33);C landGC.stress = trueRuby land
Bonus PointsUse Val rind/ASaninstead of tamperin .
Bonus PointsUse Val rind/ASaninstead of tamperin .Your Rails test suiteHeat death of the Universe
3. StaticAnalysis
How do you feelabout timeouts?
THERE ARENOTIMEOUTS INRUBY(just ask the Timeout Rabbit)
require ‘timeout’
require ‘timeout’Timeout::timeout(5) {# Do something}
require ‘timeout’Timeout::timeout(5) {# Do something}…
…
……
……oh hey
“Sorry I’m late.Couldn’t et hereany faster.”
Beautiful
Beautifulwronalso:
MRI 1.8.7Ruby ProcessGreen ThreadGreen ThreadGreen ThreadTHEKERNEL
MRI 1.9.3Ruby ProcessTHEKERNELNNative ThreadNNative ThreadNNative Thread
MRI 1.9.3Ruby ProcessTHEKERNELNNative ThreadNNative ThreadNNative ThreadGVL
Use theforce,kid
“Unix, you moron.Unix is the force.”
MRI 1.8.7Use si nals & thepower of Unix
MRI 1.8.7Use si nals & thepower of UnixMRI 1.9.3Release the GVL
Mathiasman the Wise
“I, too, had adreadful problemwith timeouts”
You see, I wasusin JRuby…
JRuby?Sounds like youhave twoproblems now.
(shut up, kid)You see, I wasusin JRuby, andthe GitHub APIyou uys keepbreakin …
Duh.That’s probablybecause thethread issleepin or stuckin the GVL.
You fool!JRuby has native threadsand fine- rainedlockin !*smack*
JRUBY 1.6.7Timeout::timeout(5) {Timeout::timeout(60) {# Do something}}Lon est timeoutclobbers the short one
I LIKE THIS BUGBecause JRuby wins
Simple BuComplex BuPainful BuKernel BuNESTEDTIMEOUTSIN THE JVM
Now Leavin :Realm of Bu sValley of Common Sense
mmon SenseMountains of Reason
Country ofWHAT THEHELL ARE YOUDOINGMRI Timeoutsin Green Threads
MORALOFTHESTORY
BETTERWORSEISSometimes*this doesn’t apply to the MRI GC
Computersbreak Ruby breakstwice as often
If you build simplersystems, they willbreakin simplerways.