Slide 1

Slide 1 text

Async Server And Fiber [email protected]

Slide 2

Slide 2 text

Me github/luikore ruby-china/luikore

Slide 3

Slide 3 text

Motivation

Slide 4

Slide 4 text

Challenges To Ruby

Slide 5

Slide 5 text

Ruby Advantages Unicode done right Builtin continuation - Fiber And... "" . l e n g t h

Slide 6

Slide 6 text

Fast

Slide 7

Slide 7 text

How To Build A High Performance Server

Slide 8

Slide 8 text

How To Build An Async Server

Slide 9

Slide 9 text

How To Build An Async Server Yet Providing Good API

Slide 10

Slide 10 text

Study The Background

Slide 11

Slide 11 text

No content

Slide 12

Slide 12 text

The Bottle Neck Client Side Of View IO bound - network is slow CPU bound - complex page rendering Server load - wait for other requests to finish

Slide 13

Slide 13 text

The Bottle Neck Server Side Of View IO bound - visiting database / oauth is slow CPU bound - context switch

Slide 14

Slide 14 text

Scaling Increase App Throughput Reduce server side IO-waiting is the most effective way Create less threads, to avoid context switching

Slide 15

Slide 15 text

Learn From Existing Solutions

Slide 16

Slide 16 text

Chances To Ruby

Slide 17

Slide 17 text

Limited Server Objects

Slide 18

Slide 18 text

Many Crazy Clients

Slide 19

Slide 19 text

Multiplexing

Slide 20

Slide 20 text

Single Threaded One Client, One Process, Prefork unicorn -- multiplex with accept thin -- multiplex with load balancer

Slide 21

Slide 21 text

Multithreaded One Client, One Thread, No Prefork puma, recommended for rails4 A simple way to implement is to use POSIX functions with callbacks: aio_read(), aio_write()

Slide 22

Slide 22 text

Single Threaded And Event Loop One Client, One Event Context, Prefork nginx, redis, nodejs, twisted, eventmachine

Slide 23

Slide 23 text

Thread Pool On Event Loop One Client, One Event Context, No Prefork erlang, golang, scala actors

Slide 24

Slide 24 text

Hello World

Slide 25

Slide 25 text

TCPSocket In 5 Minutes client server receive send T C P S o c k e t . n e w h o s t , p o r t T C P S e r v e r . n e w h o s t , p o r t s o c k e t . r e a d s o c k e t . r e a d _ n o n b l o c k s o c k e t . w r i t e s o c k e t . w r i t e _ n o n b l o c k

Slide 26

Slide 26 text

Hello World HTTP Server s e r v e r = T C P S e r v e r . n e w ' l o c a l h o s t ' , 4 0 0 0 l o o p d o c = s e r v e r . a c c e p t c < < " H T T P / 1 . 1 2 0 0 O K C o n t e n t - L e n g t h : 1 2 H e l l o w o r l d ! " c . c l o s e e n d

Slide 27

Slide 27 text

Make It Fast

Slide 28

Slide 28 text

Non­Blocking Our Loop l o o p d o c l i e n t = s e r v e r . a c c e p t T h r e a d . n e w d o . . . e n d e n d

Slide 29

Slide 29 text

Threads Are Outdated Lets Use System Events

Slide 30

Slide 30 text

Multiplexing Functions select poll I O . s e l e c t r , w , e r r , t i m e o u t I O . p o l l f d s , t i m e o u t

Slide 31

Slide 31 text

System Events Linux For Example poll - iterate check all fds epoll - is more effective and provides more options

Slide 32

Slide 32 text

Epoll In 5 Minutes s u d o a p t - g e t i n s t a l l m a n p a g e s - d e v m a n e p o l l

Slide 33

Slide 33 text

Epoll In 5 Minutes register event: retrieve event: e p o l l _ c t l ( ) e p o l l ( )

Slide 34

Slide 34 text

Cons Ruby does not ship with epoll API. You need to wrap it with C-ext.

Slide 35

Slide 35 text

Loop With Epoll l o o p d o e v e n t = e p o l l ( t i m e o u t ) i f f r o m _ s e r v e r ? ( e v e n t ) c o n n e c t i o n = s e r v e r . a c c e p t e l s e c o n n e c t i o n = f i n d _ c o n n _ b y ( e v e n t ) e n d . . . # r e s u m e p r o c e s s i n g e n d

Slide 36

Slide 36 text

How To Make It Resumable?

Slide 37

Slide 37 text

Eventmachine async web server

Slide 38

Slide 38 text

clients are multiplexed to you define callbacks for readable events: E M : : C o n n e c t i o n d e f r e c e i v e _ d a t a ( d a t a )

Slide 39

Slide 39 text

"Resume Processing" c o n n e c t i o n . r e c e i v e _ d a t a r e a d _ n o n b l o c k

Slide 40

Slide 40 text

Make It Good

Slide 41

Slide 41 text

How EM Send_data Works write to socket, if the socket can’t take any more, append the rest to a buffer chain when the socket becomes writable again (IO event), try consume the buffer chain

Slide 42

Slide 42 text

Pitfalls Callbacks Are Not Sufficient avoid loss of chained buffers avoid infinite recursion when registering events in callback: c l o s e _ c o n n e c t i o n _ a f t e r _ w r i t i n g E M . n e x t _ t i c k { . . . }

Slide 43

Slide 43 text

Resume Processing With Fiber Fiber was the “Thread” in 1.8 Like thread, but lighter, pausable, and no need to lock

Slide 44

Slide 44 text

Example f i b e r = F i b e r . n e w d o i = 0 l o o p d o F i b e r . y i e l d i + = 1 e n d e n d f i b e r . r e s u m e # = > 1 f i b e r . r e s u m e # = > 2

Slide 45

Slide 45 text

Read With Fiber d e f r e a d _ w i t h _ f i b e r r e s u l t = ' ' w h i l e b u f f e r = r e a d _ n o n b l o c k r e s u l t < < b u f f e r i f n o t h i n g t o r e a d F i b e r . y i e l d : r e a d i n g ! e n d e n d r e s u l t e n d

Slide 46

Slide 46 text

Write With Fiber d e f w r i t e _ w i t h _ f i b e r c o n t e n t l o o p d o w r i t e _ n o n b l o c k c o n t e n t c o n t e n t = u n w r i t t e n p a r t o f c o n t e n t b r e a k i f c o n t e n t . e m p t y ? F i b e r . y i e l d : w r i t i n g ! e n d e n d

Slide 47

Slide 47 text

Recall Our Loop l o o p d o e v e n t = e p o l l ( t i m e o u t ) i f f r o m _ s e r v e r ? ( e v e n t ) c o n n e c t i o n = s e r v e r . a c c e p t e l s e c o n n e c t i o n = f i n d _ c o n n _ b y ( e v e n t ) e n d . . . # r e s u m e p r o c e s s i n g e n d

Slide 48

Slide 48 text

l o o p d o e v e n t = e p o l l ( t i m e o u t ) i f f r o m _ s e r v e r ? ( e v e n t ) c o n n e c t i o n = s e r v e r . a c c e p t f i b e r = F i b e r . n e w { . . . r e a d _ w i t h _ f i b e r . . . w r i t e _ w i t h _ f i b e r } e l s e f i b e r = f i n d _ f i b e r _ b y ( e v e n t ) e n d f i b e r . r e s u m e e n d

Slide 49

Slide 49 text

Summary

Slide 50

Slide 50 text

Network latency and C10k leads to async solutions. With Fiber it can be callback-free.

Slide 51

Slide 51 text

In concept it is simple. In practice it is complex: protocols, IO exceptions, ...

Slide 52

Slide 52 text

Product github.com/luikore/nyara faster than sinatra/expressjs in hello world benchmarks