concurrency & ruby

31
CONCURRENCY & RUBY Rocky Jaiswal RubyConf India 2013

Upload: rockyjaiswal

Post on 30-Jun-2015

687 views

Category:

Technology


4 download

DESCRIPTION

Slides for my talk at RubyConf India 2013

TRANSCRIPT

Page 1: Concurrency & Ruby

CONCURRENCY&

RUBY

RockyJaiswalRubyConfIndia2013

Page 2: Concurrency & Ruby

WHYCONCURRENCY?

Page 3: Concurrency & Ruby

ABOUTMELearningprogrammingforthelast11years

DidJavaforaround8years

StartedlearningRuby~3yearsback

♥Ruby♥theRubycommunity

AlsolearningsomeCoffeeScriptandScala

http://rockyj.in@whatsuprocky

Page 4: Concurrency & Ruby

CONCURRENCY?

Concurrencyiswhentwotaskscanstart,run,andcompleteinoverlappingtimeperiods

Concurrencycanbeimplementedeveninsingleprocessingunitstospeedthingsup

Concurrencyisnon-deterministic

Whereasaparallelprogramisonethatmerelyrunsonmultipleprocessors,withthegoalofhopefullyrunning

fasterthanitwouldonasingleCPU

Page 5: Concurrency & Ruby

THREADSVSPROCESSESS

Threadsarelightweightprocessesthatruninthesamememorycontext

RubyhasGreenThreadswhicharemanagedbytheRubyprocess

JRubyhasrealOSthreadthatrunparalleltotheparentthread

Page 6: Concurrency & Ruby

THREADSINRUBY

Page 7: Concurrency & Ruby

SAMPLEUNICORNSETUP

15Unicorns=15Processes1UnicornProcess~=150MB15Processes~=2GBRAM*

Scalingthismeansmoreprocesses=morememory=moremoney

Also,IfyouareCPUboundyouwanttousenomoreunicornprocessesthanyouhavecores,otherwiseyouoverloadthesystemandslowdownthescheduler.

Page 8: Concurrency & Ruby

CONCURRENCYISGOOD

JRuby+Puma/Torquebox

High-Scalabilitywithlessmemory

Resque/Sidekiq

Moreworkersandfasterprocessingwithlessmemory

Page 9: Concurrency & Ruby

SOISITALLDOOMANDGLOOM?

No!

MostRailsapplicationsareIOboundWithMRIyouarealwaysthreadsafeMRIisgettingfasterandGCisgettingbetterProcessesmanagementisoptimizedPassengerisusingahybrid-evented+threaded/processarchitecture

Page 10: Concurrency & Ruby

THREAD-SAFETYLETMEGIVEYOUADEMO

AppendingtoArrays:

MRIVersionvs

JRubyVersion

DEMO

Page 11: Concurrency & Ruby

RUNCODEONMRI&JRUBY

array=[]5.times.mapdoThread.newdo#Init5threads1000.timesdoarray<<nil#Ineachthreadadd1000elementstotheArrayendendend.each(&:join)putsarray.size

Page 12: Concurrency & Ruby

EVENAPPENDINGTOARRAYSISNOTTHREADSAFE!

Page 13: Concurrency & Ruby

WHATABOUTRAILS

config.threadsafe!

defthreadsafe!@preload_frameworks=true@cache_classes=true@dependency_loading=false@allow_concurrency=trueselfend

Page 14: Concurrency & Ruby

JRUBYONRAILS

DEMO

Page 15: Concurrency & Ruby

BADCOUNTERCODE

classPagesController<ApplicationController@counter=0class<<selfattr_accessor:counterend#Classicread-modify-writeproblemdefindexcounter=self.class.counter#readsleep(0.1)counter+=1#updatesleep(0.1)self.class.counter=counter#writeusers=User.allputs"-----------"+self.class.counter.to_s+"------------"endend

Page 16: Concurrency & Ruby

UGLYSYNCHRONIZEDCODE

classPagesController<ApplicationController@counter=0@semaphore=Mutex.newclass<<selfattr_accessor:counterattr_accessor:semaphoreenddefindex#counter=self.class.counter#readsleep(0.1)self.class.semaphore.synchronize{self.class.counter+=1#update}sleep(0.1)#self.class.counter=counter#writeusers=User.allputs"-----------"+self.class.counter.to_s+"------------"endend

Page 17: Concurrency & Ruby

RAILS4ISCONCURRENCYENABLEDBYDEFAULT

Page 18: Concurrency & Ruby

CONCURRENCYINTRODUCES

RaceConditionsDeadlocksStarvation

etc.

BUTGIVESYOUSpeed

LessMemoryUsage

Page 19: Concurrency & Ruby

SAFECONCURRENCY

Don'tdoit.Ifyoumustdoit,don'tsharedataacrossthreads.Ifyoumustsharedataacrossthreads,don'tsharemutabledata.Ifyoumustsharemutabledataacrossthreads,synchronizeaccesstothatdata.

Page 20: Concurrency & Ruby

THREADSAFETYINJRUBY

LOCKS

ATOMICITY

IMMUTABILITY

Page 21: Concurrency & Ruby

ATOMICCOUNTER

java_import'java.util.concurrent.atomic.AtomicInteger'

classPagesController<ApplicationController@counter=AtomicInteger.new(1)class<<selfattr_accessor:counterend

defindexsleep(0.1)counter=self.class.counter.getAndIncrement()#updatesleep(0.1)users=User.allputs"-----------------"+counter.to_s+"-----------------"endend

Page 22: Concurrency & Ruby

ALLTHISSUCKS!

95%ofsyncronizedcodeisbroken.Theother5%iswrittenbyBrianGoetz.-VenkatSubramaniam

Page 23: Concurrency & Ruby

ENTERACTOR

Page 24: Concurrency & Ruby

THEACTORMODEL

IntroducedbyCarlHewittin1973Contributionsbyalotofscholarsanduniversities

PopularizedbyErlang,nowinScala

Simpleandhigh-levelabstractionsforconcurrencyandparallelismObjectsareActorseachwiththeirownstatewhichisneversharedCommunicationhappensthroughmessagesVerylightweightevent-drivenprocesses(approximately2.7millionactorsperGBRAM[Akka])

Page 25: Concurrency & Ruby

THEACTORMODEL-2

Easiertodealwithhumansthanwiththreads

Likehumans,Actorscommunicateviamessages

Nostatesharing,communicateviaimmutablemessages

Page 26: Concurrency & Ruby

IMPLEMENTATIONS

Page 27: Concurrency & Ruby

PRODUCERCONSUMERPROBLEM

DemowithJRuby+LocksDemowithJRuby+Celluloid

Page 28: Concurrency & Ruby

PRODUCERCONSUMERwithlocks

HTTPS://GIST.GITHUB.COM/ROCKY-JAISWAL/5847810

Page 29: Concurrency & Ruby

PRODUCERCONSUMERwithactors

HTTPS://GIST.GITHUB.COM/ROCKY-JAISWAL/5847814

Page 30: Concurrency & Ruby

SUMMARY

ConcurrencyistheneedofthehourMRIisthreadsafebydefaultduetoGIL/GVLJRubygivesyourealconcurrency(RBXaswell)WithpowercomesresponsibilityDon'tworry,concurrencycanbeeasyifyoufollowthegroundrulesIfyouwanttowriteconcurrentcodeyourself,useActors

*IdidnotcoverSTM(providedbyClojure)

Page 31: Concurrency & Ruby

THANKYOU!

QUESTIONS

#Alotofthiscontenthasbeentakenfromblogs,wikisandbooks.Idonotclaimitismy

ownandIwholeheartedlythankeveryonewhohelpedmewiththispresentation.