He llo , I a m Ya s s e r Idris . A fe llo w ru b y is t fro m E g y pt . I a m a le a d de ve lo pe r a t
To da y I a m g o in g to t a lk a b o u t
W h a t?
N e ve rB lo c k b rin g s c o n c u rre n c y to s in g le t h re a de d a pplic a tio n s t h a t a re w ritte n in a s y n c h ro n o u s (b lo c k in g ) m a nne r
Ho w ?
N e ve rB lo c k e n a b le s c o n c u rre n t DB a n d n e t w o rk a c c e s s w it h o u t th e n e e d to c h a n g e pro g ra m flo w
F o u r dif fe re n t R u b y pro g ra m s th a t pe rfo rm DB O pe ra tio n s
N o rm a l
re qu ire 'm y s qlplu s ' @c o u n t = 1 0 0 @re s u lt s = [ ] @c o n n = My s ql.n e w (h o s t ,u s e r,pa s s ,db ) @b lo c k = P ro c .n e w do re s = @c o n n .qu e r y ('s e le c t s le e p(0 .1 )') re s .e a c h { |r| @re s u lt s << r }.fre e e nd @c o u n t .t im e s do @b lo c k .c a ll e nd # ru n s in ~ 1 0 s e c o n ds
T h re a de d
re qu ire 'm y s qlplu s ' re qu ire 'th re a d' @c o u n t = 1 0 0 @c o n n s , @re s u lts = [ ], [ ] @c o u n t.tim e s {@c o n n s << My s ql.n e w ('lo c a lh o s t','ro o t',n il,'db ')} @b lo c k = P ro c .n e w do re s = @c o n n s .s h ift.a s y n c _qu e ry ('s e le c t s le e p(0 .1 )') re s .e a c h { |r| @re s u lts << r }.fre e e nd @th re a ds , @m u t e x = [ ], Mu te x .n e w @c o u n t.tim e s do @th re a ds << T h re a d.n e w { @m u te x .s y n c h ro n ize { @b lo c k .c a ll } } e nd @th re a ds .e a c h { |t| t .jo in } # ru n s in ~ 1 s e c o n d
E ve n te d
re qu ire 'm y s qlplu s ' @c o u n t = 1 0 0 @c o n n s , @re a da b le s , @b u s y, @re s u lt s = [ ], [ ], { }, [ ] @c o u n t.tim e s { @c o n n s << My s ql.n e w (h o s t ,u s e r,pa s s ,db ) } @b e fo re = P ro c .n e w do (c o n n = @c o n n s .s h ift ).s e n d_qu e ry ('s e le c t s le e p(0 .1 )') @re a da b le s << IO.n e w (c o n n .s o c ke t) @b u s y [c o n n .s o c ke t ] = c o n n e nd @a ft e r = P ro c .n e w do |s o c ke t| @b u s y [s o c ke t.to _i].g e t _re s u lt .e a c h {|r| @re s u lt << r}.fre e e nd @c o u n t.tim e s { @b e fo re .c a ll } lo o p do re s = s e le c t (@re a da b le s ,n il,n il,n il) re s [0 ].e a c h { |s | @a ft e r.c a ll(s ) } if re s e nd # ru n s in ~ 1 s e c o n d
N e ve rB lo c k
re qu ire 'n e ve rb lo c k -m y s ql' re qu ire 'e ve n t m a c h in e ' @c o u n t = 1 0 0 @re s u lts = [ ] @fp = N B ::P o o l::F ib e rP o o l.n e w (@c o u n t ) @c = N B ::DB ::P DB C .n e w (@c o u n t) do N B ::DB ::F MC .n e w (h o s t,u s e r,pa s s ,db ) e nd @b lo c k = P ro c .n e w do re s = @c .qu e ry ('s e le c t s le e p(0 .1 )') re s .e a c h {|r| @re s u lts << r}.fre e e nd E M.ru n { @c o u n t .tim e s { |i| @fp.s pa w n { @b lo c k .c a ll } } } # ru n s in ~ 1 s e c o n d
E ve n te d V s T h re a de d
E ve n t e d m o de l in R u b y is fa s t e r, m o re s c a la b le , w it h n o th re a d s a fe ty re qu ire m e n ts b u t w ith A tw is t e d de ve lo pm e n t m o de l
T h re a de d m o de l in R u b y is s lo w e r, le s s s c a la b le , w it h t h re a d s a fe ty re qu ire m e n ts b u t w ith a dire c t de ve lo pm e n t m o de l
Me e t N e ve rB lo c k
Me e t N e ve rB lo c k T h e B e s t o f B o th Wo rlds
N e ve rB lo c k is fa s t, m o re s c a la b le , w ith n o th re a d s a fe t y re qu ire m e n ts b u t w it h a dire c t de ve lo pm e n t do de l
T h is is po s s ib le th a n k s t o F ib e rs (C o ro u tin e s )
F ib e rs a re n o rm a l m e th o ds t h a t c a n b e pa u s e d a n d re s u m e d a t w ill
f = F ib e r.n e w do x =5 F ib e r.y ie ld x x =6 F ib e r.y ie ld x y =7 e nd pu ts pu ts pu ts pu ts
f.re s u m e f.re s u m e f.re s u m e f.re s u m e
#=> #=> #=> #=>
5 6 7 E rro r, de a d fib e r c a lle d
F ib e rs c a n do t w o w a y c o m m u n ic a tio n
f = F ib e r.n e w do |x | y = F ib e r.y ie ld x z = F ib e r.y ie ld y a =2 e nd pu ts pu ts pu ts pu ts
f.re s u m e (7 ) #=> 7 f.re s u m e (6 ) #=> 6 f.re s u m e (5 ) #=> 2 f.re s u m e #=> E rro r c a llin g de a d fib e r
F ib e rs a re m u c h lig h te r th a n t h re a ds a n d re qu ire m u c h le s s m e m o ry
N e ve rB lo c k U s e s F ib e rs A n d E ve n tMa c h in e To A c h ie ve A lm o s t T ra n s pa re n t C o n c u rre n c y
N e ve rB lo c k re qu ire s th a t I/O a c c e s s c la s s e s s u ppo rt n o n b lo c k in g m o de s
N e ve rB lo c k c u rre n t ly s u ppo rts P o s tg re S Q L a n d My S Q L (v ia th e My S Q L P lu s drive r)
N e ve rB lo c k A ls o S u ppo rts R u b y s o c ke ts m a k in g lib ra rie s like N e t/HT T P ru n c o n c u rre n tly
A T h in s e rve r a d d o n prov ide s a N e ve rB lo c k re a dy c o n ta in e r fo r yo u r R u b y w e b a pplic a tio n s
A N e ve rB lo c k a da pte r fo r A c tive Re c o rd c a u s e s R a ils a pplic a tio n s to pro c e s s re qu e s ts C o n c u rre n tly if u s e d w it h T h in s e rve r
V is u a lize d R a ils e x a m ple
EventMachine
T h in S e rve r
...
F ib e r P o o l
A Fiber Pool Is Injected In The Thin Server
EventMachine Request A CPU
T h in S e rve r
I/O Request A
...
Request A arrives
Thin grabs a fiber from the pool
F ib e r P o o l
Request A goes to Rails wrapped in the fiber
EventMachine
CPU I/O
T h in S e rve r
Registers With EM
Request A reaches a blocking I/O call.
...
The fiber yields Control To The Thin Server
F ib e r P o o l
EventMachine Request B CPU
T h in S e rve r
I/O Request B
...
Thin Receives Request B
It sends it to Rails for processing wrapped in another fiber
F ib e r P o o l
EventMachine
CPU
T h in S e rve r
I/O Registers With EM
Request B starts processing and also reaches a blocking I/O call
...
The fiber then yields control to Thin
F ib e r P o o l
EventMachine
CPU
T h in S e rve r
I/O Completion Notification
●
The EventMachine detects an I/O completion event
... ●
It resumes the fiber which continues processing till the
F ib e r P o o l
next I/O call or end of request
And s o on
W h a t m o dific a tio n s yo u n e e d t o a pply t o yo u r R a ils a pplic a tio n ?
pro du c tio n .rb require 'neverblock' require 'never_block/frameworks/rails' require 'never_block/servers/thin'
da t a b a s e .y m l production: adapter: neverblock_postgresql # or neverblock_mysql . . . connections: 8
A n d yo u 're g o o d t o g o
C a n I u s e it in pro du c tio n ?
Ye s
A n d yo u w o n t b e th e firs t
T h e O w n in g s S o c ia l N e tw o rk
U s e s N e ve rB lo c k fo r a 7 5 % m e m o ry s a v in g a n d re du c t io n o f de la ye d re qu e s ts
F e a tu re L is t
My S Q L P o s tg re S Q L R u b y s o c ke ts N e t/HT T P A c tive Re c o rd R a ils 2 .1 T h in s e rve r
F u t u re Wo rk
B e tte r n e tw o rk s u ppo rt R a ils 2 .2 Mo re b a c ke n ds (Re v a c to r) Me rb a n d R a m a ze Da ta Ma ppe r a n d S e qu e l Ide a s A re We lc o m e
T h a n k Yo u