Concurrency & Ruby

Post on 30-Jun-2015

677 views 4 download

description

Slides for my talk at RubyConf India 2013

Transcript of Concurrency & Ruby

CONCURRENCY&

RUBY

RockyJaiswalRubyConfIndia2013

WHYCONCURRENCY?

ABOUTMELearningprogrammingforthelast11years

DidJavaforaround8years

StartedlearningRuby~3yearsback

♥Ruby♥theRubycommunity

AlsolearningsomeCoffeeScriptandScala

http://rockyj.in@whatsuprocky

CONCURRENCY?

Concurrencyiswhentwotaskscanstart,run,andcompleteinoverlappingtimeperiods

Concurrencycanbeimplementedeveninsingleprocessingunitstospeedthingsup

Concurrencyisnon-deterministic

Whereasaparallelprogramisonethatmerelyrunsonmultipleprocessors,withthegoalofhopefullyrunning

fasterthanitwouldonasingleCPU

THREADSVSPROCESSESS

Threadsarelightweightprocessesthatruninthesamememorycontext

RubyhasGreenThreadswhicharemanagedbytheRubyprocess

JRubyhasrealOSthreadthatrunparalleltotheparentthread

THREADSINRUBY

SAMPLEUNICORNSETUP

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

Scalingthismeansmoreprocesses=morememory=moremoney

Also,IfyouareCPUboundyouwanttousenomoreunicornprocessesthanyouhavecores,otherwiseyouoverloadthesystemandslowdownthescheduler.

CONCURRENCYISGOOD

JRuby+Puma/Torquebox

High-Scalabilitywithlessmemory

Resque/Sidekiq

Moreworkersandfasterprocessingwithlessmemory

SOISITALLDOOMANDGLOOM?

No!

MostRailsapplicationsareIOboundWithMRIyouarealwaysthreadsafeMRIisgettingfasterandGCisgettingbetterProcessesmanagementisoptimizedPassengerisusingahybrid-evented+threaded/processarchitecture

THREAD-SAFETYLETMEGIVEYOUADEMO

AppendingtoArrays:

MRIVersionvs

JRubyVersion

DEMO

RUNCODEONMRI&JRUBY

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

EVENAPPENDINGTOARRAYSISNOTTHREADSAFE!

WHATABOUTRAILS

config.threadsafe!

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

JRUBYONRAILS

DEMO

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

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

RAILS4ISCONCURRENCYENABLEDBYDEFAULT

CONCURRENCYINTRODUCES

RaceConditionsDeadlocksStarvation

etc.

BUTGIVESYOUSpeed

LessMemoryUsage

SAFECONCURRENCY

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

THREADSAFETYINJRUBY

LOCKS

ATOMICITY

IMMUTABILITY

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

ALLTHISSUCKS!

95%ofsyncronizedcodeisbroken.Theother5%iswrittenbyBrianGoetz.-VenkatSubramaniam

ENTERACTOR

THEACTORMODEL

IntroducedbyCarlHewittin1973Contributionsbyalotofscholarsanduniversities

PopularizedbyErlang,nowinScala

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

THEACTORMODEL-2

Easiertodealwithhumansthanwiththreads

Likehumans,Actorscommunicateviamessages

Nostatesharing,communicateviaimmutablemessages

IMPLEMENTATIONS

PRODUCERCONSUMERPROBLEM

DemowithJRuby+LocksDemowithJRuby+Celluloid

PRODUCERCONSUMERwithlocks

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

PRODUCERCONSUMERwithactors

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

SUMMARY

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

*IdidnotcoverSTM(providedbyClojure)

THANKYOU!

QUESTIONS

#Alotofthiscontenthasbeentakenfromblogs,wikisandbooks.Idonotclaimitismy

ownandIwholeheartedlythankeveryonewhohelpedmewiththispresentation.