6 reasons Jubilee could be a Rubyist's new best friend

Post on 02-Jul-2015

6.917 views 6 download

description

(Video here: http://confreaks.com/videos/5014-RubyConf2014-6-reasons-jubilee-could-be-a-rubyist-s-new-best-friend or https://www.youtube.com/watch?feature=player_embedded&v=FFR0G89WXI8) Rubyconf 2014 talk on Jubilee, a Vert.x module that runs rack apps. Alternate titles Beyond Rails while using Rails Rails can't do everything I want and makes me want to cry Rubyconf abstract Do you do web development in Ruby? Have you been forced to go to node or other technologies just for concurrency/websockets etc. Do miss your gems, and tire of functionality you have to implement from scratch? Do you hate javascript? Well no need to switch languages/platforms, Jubilee could be your new best friend. Jubilee, a rack server on top of Vert.x gives you * Concurrency * Speed * Easy Websockets support * Shared Memory * Access to the JVM ecosystem * Ability to reuse your existing Ruby knowledge and gems "Say Hello to your new friend" - Al Pacino

Transcript of 6 reasons Jubilee could be a Rubyist's new best friend

6 R E A S O N S J U B I L E E C O U L D B E A R U B Y I S T ’ S N E W B E S T F R I E N D

F O R R E S T C H A N G @ F K C H A N G 2 0 0 0

https://bambegin.files.wordpress.com/2014/09/tumblr_mfm9lq28cn1s14crlo1_500.jpg

A P O L O G I E S

http://images.sodahead.com/blogs/000302881/sorry20really20truly20very20apology_xlarge.jpeg.

A LT E R N AT E T I T L E S A F T E R S E E I N G

E R N I E M I L L E R ’ S R U B Y A F T E R R A I L S

!

R A I L S W H I L E S T I L L U S I N G R A I L S

O R

R A I L S C A N ’ T D O A L L T H E S T U F F I WA N T A N Y M O R E A N D < F I L L I N T H E T E C H > M A K E S M E WA N T T O C RY

http://www.louiseoneillauthor.com/wp-content/uploads/2014/06/crying-baby.jpg

P R E L U D E

Q U E S T I O N

http://wp.production.patheos.com/blogs/faithwalkers/files/2013/09/god-question.jpg

W H Y A R E Y O U H E R E AT R U B Y C O N F ?

A N A N S W E R

Y O U L I K E R U B Y

W H Y D O Y O U L I K E R U B Y ?

B E C A U S E I T M A K E S Y O U H A P P Y

– M AT Z

“For me the purpose of life is partly to have joy. Programmers often feel joy when they can

concentrate on the creative side of programming, So Ruby is designed to make programmers happy.”

http://euruko.org/img/matz_800.jpg

– M AT Z

“For me the purpose of life is partly to have joy. Programmers often feel joy when they can

concentrate on the creative side of programming, So Ruby is designed to make programmers happy.”

http://euruko.org/img/matz_800.jpg

H A P P I N E S S I S T H E R U B Y W AY

O B J E C T I V E

O B J E C T I V E

• To ensure you, the Rubyist, stays happy

H A P P I N E S S I S A R E C U R R I N G T H E M E

• J

• D

• D

I N M Y TA L K S , A S W E L L A S H E R E AT R U B Y C O N F

H A P P I N E S S I S A R E C U R R I N G T H E M E

• J

• D

• D

• Joy

I N M Y TA L K S , A S W E L L A S H E R E AT R U B Y C O N F

H A P P I N E S S I S A R E C U R R I N G T H E M E

• J

• D

• D

• Joy

• Driven

I N M Y TA L K S , A S W E L L A S H E R E AT R U B Y C O N F

H A P P I N E S S I S A R E C U R R I N G T H E M E

• J

• D

• D

• Joy

• Driven

• Development

I N M Y TA L K S , A S W E L L A S H E R E AT R U B Y C O N F

C O D I N G A N D L O V I N G I T

W H AT D O W E L I K E A B O U T R U B Y ?

1 ) L A N G U A G E I T S E L F I S D E L I G H T F U L

1 ) L A N G U A G E I T S E L F I S D E L I G H T F U L

• An entire talk can be done on this

1 ) L A N G U A G E I T S E L F I S D E L I G H T F U L

• An entire talk can be done on this

• So I won't do one

S I N G L E E X A M P L E F R O M D E V I S E C O N F I G

# ==> Configuration for :validatable!# Range for password length. Default is 8..128.!config.password_length = 8..128

S I N G L E E X A M P L E F R O M D E V I S E C O N F I G

# ==> Configuration for :validatable!# Range for password length. Default is 8..128.!config.password_length = 8..128

• Intent is so clear

S I N G L E E X A M P L E F R O M D E V I S E C O N F I G

# ==> Configuration for :validatable!# Range for password length. Default is 8..128.!config.password_length = 8..128

• Intent is so clear

• Nothing extraneous

S I N G L E E X A M P L E F R O M D E V I S E C O N F I G

# ==> Configuration for :validatable!# Range for password length. Default is 8..128.!config.password_length = 8..128

• Intent is so clear

• Nothing extraneous

• Compared to new TimeRange(8, 128)

S I N G L E E X A M P L E F R O M D E V I S E C O N F I G

# ==> Configuration for :validatable!# Range for password length. Default is 8..128.!config.password_length = 8..128

• Intent is so clear

• Nothing extraneous

• Compared to new TimeRange(8, 128)

• Beautiful

R U B Y M A K E S M E H A P P Y

R U B Y M A K E S M E H A P P Y

2 ) G E M S A N D F R A M E W O R K S

2 ) G E M S A N D F R A M E W O R K S

• Many gems, nearly anything you'd want ready to go

2 ) G E M S A N D F R A M E W O R K S

• Many gems, nearly anything you'd want ready to go

• Choice, often more than 1 gem for the job

2 ) G E M S A N D F R A M E W O R K S

• Many gems, nearly anything you'd want ready to go

• Choice, often more than 1 gem for the job

• Gem authors tend to emulate Matz and try to make the programmer happy

800lb Gorilla of Rubygems

http://www.examiner.com/images/blog/wysiwyg/image/4056_Landing_gorilla-1.jpg

R A I L S

R A I L S

• Who codes in Rails?

R A I L S

• Who codes in Rails?

• Who came to Ruby from Rails?

R A I L S

• Who codes in Rails?

• Who came to Ruby from Rails?

• Who was coding Ruby before Rails?

R A I L S

• Who codes in Rails?

• Who came to Ruby from Rails?

• Who was coding Ruby before Rails?

• Who loves Rails?

R A I L S

• Who codes in Rails?

• Who came to Ruby from Rails?

• Who was coding Ruby before Rails?

• Who loves Rails?

• Who has a job because of Rails?

W H Y W E L O V E R A I L S

W H Y W E L O V E R A I L S

• A whole talk can be done this

W H Y W E L O V E R A I L S

• A whole talk can be done this

• So I won't do one

W H Y W E L O V E R A I L S

• A whole talk can be done this

• So I won't do one

• Productivity

W H Y W E L O V E R A I L S

• A whole talk can be done this

• So I won't do one

• Productivity

• Programmer interface - Omokase, designed to make the coder happy

R A I L S C A N M A K E S Y O U H A P P Y

R A I L S C A N M A K E S Y O U H A P P Y

R U B Y I S N O T A PA N A C E A

S O M E R E A S O N S T O N O T U S E R U B Y

S O M E R E A S O N S T O N O T U S E R U B Y

• Speed

S O M E R E A S O N S T O N O T U S E R U B Y

• Speed

• Image processing, video encoding

S O M E R E A S O N S T O N O T U S E R U B Y

• Speed

• Image processing, video encoding

• Scaling

S O M E R E A S O N S T O N O T U S E R U B Y

• Speed

• Image processing, video encoding

• Scaling

• Resource heavy

S O M E R E A S O N S T O N O T U S E R U B Y

• Speed

• Image processing, video encoding

• Scaling

• Resource heavy

• Computation heavy

S O M E R E A S O N S T O N O T U S E R U B Y

• Speed

• Image processing, video encoding

• Scaling

• Resource heavy

• Computation heavy

• More/better Library functionality elsewhere

S O M E R E A S O N S T O N O T U S E R U B Y

• Speed

• Image processing, video encoding

• Scaling

• Resource heavy

• Computation heavy

• More/better Library functionality elsewhere

• Scientific programming support better in Python, etc.

A L L L E G I T R E A S O N S

P R O B L E M

P R O B L E MSome non Ruby technologies can be “Less Happy Making”

A C O M M O N A LT E R N AT I V E

N O D E , W H AT I T I S G O O D F O R ?

N O D E , W H AT I T I S G O O D F O R ?

N O D E , W H AT I T I S G O O D F O R ?

• Quick, Non blocking I/O

N O D E , W H AT I T I S G O O D F O R ?

• Quick, Non blocking I/O

• Concurrency

N O D E , W H AT I T I S G O O D F O R ?

• Quick, Non blocking I/O

• Concurrency

• Chat app demonstrates Node’s sweet spot

N O D E , W H AT I T I S G O O D F O R ?

• Quick, Non blocking I/O

• Concurrency

• Chat app demonstrates Node’s sweet spot

• high concurrency

N O D E , W H AT I T I S G O O D F O R ?

• Quick, Non blocking I/O

• Concurrency

• Chat app demonstrates Node’s sweet spot

• high concurrency

• quick, low CPU usage transactions

N O D E , W H AT I T I S G O O D F O R ?

• Quick, Non blocking I/O

• Concurrency

• Chat app demonstrates Node’s sweet spot

• high concurrency

• quick, low CPU usage transactions

• server push

N O D E , W H AT I T I S G O O D F O R ?

• Quick, Non blocking I/O

• Concurrency

• Chat app demonstrates Node’s sweet spot

• high concurrency

• quick, low CPU usage transactions

• server push

• so called "modern webapp"

W H AT I T N O D E B A D AT ?

W H AT I T N O D E B A D AT ?

• Vertical scaling

W H AT I T N O D E B A D AT ?

• Vertical scaling

• CPU intensive

W H AT I T N O D E B A D AT ?

• Vertical scaling

• CPU intensive

• Integration with other systems

W H AT I T N O D E B A D AT ?

• Vertical scaling

• CPU intensive

• Integration with other systems

• Decent language (Ruby bias)

T O O M U C H J AVA S C R I P T A N D

S O , H O W D O W E

B R I N G B A C K T H AT L O V I N G F E E L I N G ?

B R I N G B A C K T H AT L O V I N G F E E L I N G ?

• Who's heard of it?

• Who's heard of it?

• Oversimplified - Node for the JVM

• Who's heard of it?

• Oversimplified - Node for the JVM

• BUT much more - more like Node++ and then some

D E S I G N E D F O R M O D E R N A P P L I C AT I O N S

D E S I G N E D F O R M O D E R N A P P L I C AT I O N S

D E S I G N E D F O R M O D E R N A P P L I C AT I O N S

Ruby/ JRuby

D E S I G N E D F O R M O D E R N A P P L I C AT I O N S

Ruby/ JRuby

D E S I G N E D F O R M O D E R N A P P L I C AT I O N S

Ruby/ JRuby

D E S I G N E D F O R M O D E R N A P P L I C AT I O N S

Ruby/ JRuby

S O M E K E Y F E AT U R E S

S O M E K E Y F E AT U R E S

S O M E K E Y F E AT U R E S

S O M E K E Y F E AT U R E S

S O M E K E Y F E AT U R E S

L I K E N O D E

L I K E N O D E

• Concurrency - Implements the same Reactor Pattern

L I K E N O D E

• Concurrency - Implements the same Reactor Pattern

• Non blocking i/o

L I K E N O D E

• Concurrency - Implements the same Reactor Pattern

• Non blocking i/o

• Fast

B E T T E R T H A N N O D E

B E T T E R T H A N N O D E

• Handles CPU intensive

B E T T E R T H A N N O D E

• Handles CPU intensive

• JVM fast (JRuby fastes of the Rubies)

B E T T E R T H A N N O D E

• Handles CPU intensive

• JVM fast (JRuby fastes of the Rubies)

• JVM thread friendly

B E T T E R T H A N N O D E

• Handles CPU intensive

• JVM fast (JRuby fastes of the Rubies)

• JVM thread friendly

• Handles Blocking IO or Long running operations

B E T T E R T H A N N O D E

• Handles CPU intensive

• JVM fast (JRuby fastes of the Rubies)

• JVM thread friendly

• Handles Blocking IO or Long running operations

• Worker verticles - uses threadpools

B E T T E R T H A N N O D E

• Handles CPU intensive

• JVM fast (JRuby fastes of the Rubies)

• JVM thread friendly

• Handles Blocking IO or Long running operations

• Worker verticles - uses threadpools

• System scaling

B E T T E R T H A N N O D E

• Handles CPU intensive

• JVM fast (JRuby fastes of the Rubies)

• JVM thread friendly

• Handles Blocking IO or Long running operations

• Worker verticles - uses threadpools

• System scaling

• Horizontal scaling- Clustering

B E T T E R T H A N N O D E

• Handles CPU intensive

• JVM fast (JRuby fastes of the Rubies)

• JVM thread friendly

• Handles Blocking IO or Long running operations

• Worker verticles - uses threadpools

• System scaling

• Horizontal scaling- Clustering

• Vertical scaling- Verticle per CPU

B E T T E R T H A N N O D E , PA R T 2

B E T T E R T H A N N O D E , PA R T 2

• Polyglot

B E T T E R T H A N N O D E , PA R T 2

• Polyglot

• Official idiomatic API support: Java, Javascript, Groovy, Coffeescript, *Ruby (by way of JRuby)*, Python

B E T T E R T H A N N O D E , PA R T 2

• Polyglot

• Official idiomatic API support: Java, Javascript, Groovy, Coffeescript, *Ruby (by way of JRuby)*, Python

• Beta: Clojure, Scala, PhP (really?)

B E T T E R T H A N N O D E , PA R T 2

• Polyglot

• Official idiomatic API support: Java, Javascript, Groovy, Coffeescript, *Ruby (by way of JRuby)*, Python

• Beta: Clojure, Scala, PhP (really?)

• any JVM lang or one compiles to a JVM language

B E T T E R T H A N N O D E , PA R T 2

• Polyglot

• Official idiomatic API support: Java, Javascript, Groovy, Coffeescript, *Ruby (by way of JRuby)*, Python

• Beta: Clojure, Scala, PhP (really?)

• any JVM lang or one compiles to a JVM language

• General Applications platform

B E T T E R T H A N N O D E , PA R T 2

• Polyglot

• Official idiomatic API support: Java, Javascript, Groovy, Coffeescript, *Ruby (by way of JRuby)*, Python

• Beta: Clojure, Scala, PhP (really?)

• any JVM lang or one compiles to a JVM language

• General Applications platform

• “modern web pages”

B E T T E R T H A N N O D E , PA R T 2

• Polyglot

• Official idiomatic API support: Java, Javascript, Groovy, Coffeescript, *Ruby (by way of JRuby)*, Python

• Beta: Clojure, Scala, PhP (really?)

• any JVM lang or one compiles to a JVM language

• General Applications platform

• “modern web pages”

• traditional enterprise backends

B E T T E R T H A N N O D E , PA R T 3

B E T T E R T H A N N O D E , PA R T 3

• Designed to build systems of systems

B E T T E R T H A N N O D E , PA R T 3

• Designed to build systems of systems

• Easy High Availability

B E T T E R T H A N N O D E , PA R T 3

• Designed to build systems of systems

• Easy High Availability

• Easy Clustering

B E T T E R T H A N N O D E , PA R T 3

• Designed to build systems of systems

• Easy High Availability

• Easy Clustering

• Easy subsystem Intercommunication

B E T T E R T H A N N O D E , PA R T 3

• Designed to build systems of systems

• Easy High Availability

• Easy Clustering

• Easy subsystem Intercommunication

• Event Bus

B E T T E R T H A N N O D E , PA R T 3

• Designed to build systems of systems

• Easy High Availability

• Easy Clustering

• Easy subsystem Intercommunication

• Event Bus

• Shared Data

C O R E A P I S - W H AT Y O U N E E D

C O R E A P I S - W H AT Y O U N E E D

• TCP/SSL clients and servers

C O R E A P I S - W H AT Y O U N E E D

• TCP/SSL clients and servers

• HTTP/HTTPS clients and servers

C O R E A P I S - W H AT Y O U N E E D

• TCP/SSL clients and servers

• HTTP/HTTPS clients and servers

• Websockets

C O R E A P I S - W H AT Y O U N E E D

• TCP/SSL clients and servers

• HTTP/HTTPS clients and servers

• Websockets

• SockJS

C O R E A P I S - W H AT Y O U N E E D

• TCP/SSL clients and servers

• HTTP/HTTPS clients and servers

• Websockets

• SockJS

• File system

C O R E A P I S - W H AT Y O U N E E D

• TCP/SSL clients and servers

• HTTP/HTTPS clients and servers

• Websockets

• SockJS

• File system

• Event bus

C O R E A P I S - W H AT Y O U N E E D

• TCP/SSL clients and servers

• HTTP/HTTPS clients and servers

• Websockets

• SockJS

• File system

• Event bus

• DNS

C O R E A P I S - W H AT Y O U N E E D

• TCP/SSL clients and servers

• HTTP/HTTPS clients and servers

• Websockets

• SockJS

• File system

• Event bus

• DNS

• UDP

D U C T TA P E

D U C T TA P E

• Open SourceSystems are duct taped together

D U C T TA P E

• Open SourceSystems are duct taped together

• We figure out how to do to put together things

D U C T TA P E

• Open SourceSystems are duct taped together

• We figure out how to do to put together things

• Perl used to be the duct tape of the internet, Ruby a cleaner Perl…

D U C T TA P E

• Open SourceSystems are duct taped together

• We figure out how to do to put together things

• Perl used to be the duct tape of the internet, Ruby a cleaner Perl…

• Gems formalize that

D U C T TA P E

• Open SourceSystems are duct taped together

• We figure out how to do to put together things

• Perl used to be the duct tape of the internet, Ruby a cleaner Perl…

• Gems formalize that

• In Node, thats what you do even more

V E R T. X D E S I G N E D F O R I N T E G R AT E D S Y S T E M S

D I F F E R E N T T Y P E S O F P R O C E S S E S

D I F F E R E N T T Y P E S O F P R O C E S S E S

• Asynchronous - Verticle

D I F F E R E N T T Y P E S O F P R O C E S S E S

• Asynchronous - Verticle

• Blocking/CPU intensive - worker verticle

I N T E R P R O C E S S / S Y S T E M C O M M U N I C AT I O N

I N T E R P R O C E S S / S Y S T E M C O M M U N I C AT I O N

• Event Bus

I N T E R P R O C E S S / S Y S T E M C O M M U N I C AT I O N

• Event Bus

• publish

I N T E R P R O C E S S / S Y S T E M C O M M U N I C AT I O N

• Event Bus

• publish

• direct message

I N T E R P R O C E S S / S Y S T E M C O M M U N I C AT I O N

• Event Bus

• publish

• direct message

• direct message reply

I N T E R P R O C E S S / S Y S T E M C O M M U N I C AT I O N

• Event Bus

• publish

• direct message

• direct message reply

• extends into the browser

I N T E R P R O C E S S / S Y S T E M C O M M U N I C AT I O N

• Event Bus

• publish

• direct message

• direct message reply

• extends into the browser

• Shared Data

I N T E R P R O C E S S / S Y S T E M C O M M U N I C AT I O N

• Event Bus

• publish

• direct message

• direct message reply

• extends into the browser

• Shared Data

• Hash

I N T E R P R O C E S S / S Y S T E M C O M M U N I C AT I O N

• Event Bus

• publish

• direct message

• direct message reply

• extends into the browser

• Shared Data

• Hash

• Set

S C A L I N G B U I LT I N

S C A L I N G B U I LT I N

• Clustering

S C A L I N G B U I LT I N

• Clustering

• vertx process.rb —cluster

S C A L I N G B U I LT I N

• Clustering

• vertx process.rb —cluster

• High Availability

S C A L I N G B U I LT I N

• Clustering

• vertx process.rb —cluster

• High Availability

• vertx process.rb —ha

A N D M U C H M O R E

A N D M U C H M O R E

• A whole talk could be done on it

A N D M U C H M O R E

• A whole talk could be done on it

• So I won’t do one

A N D M U C H M O R E

• A whole talk could be done on it

• So I won’t do one

• 2 Good overview videos

A N D M U C H M O R E

• A whole talk could be done on it

• So I won’t do one

• 2 Good overview videos

• Tim Fox: Introducing Vert.x 2.0 - Taking Polyglot Application Development to the Next Level https://www.youtube.com/watch?v=3hv4QD5ZvKE

A N D M U C H M O R E

• A whole talk could be done on it

• So I won’t do one

• 2 Good overview videos

• Tim Fox: Introducing Vert.x 2.0 - Taking Polyglot Application Development to the Next Level https://www.youtube.com/watch?v=3hv4QD5ZvKE

• good over view of vert.x capabilities w/lots of live demos

A N D M U C H M O R E

• A whole talk could be done on it

• So I won’t do one

• 2 Good overview videos

• Tim Fox: Introducing Vert.x 2.0 - Taking Polyglot Application Development to the Next Level https://www.youtube.com/watch?v=3hv4QD5ZvKE

• good over view of vert.x capabilities w/lots of live demos

• Vert.x: This ain't your Dad's Node. https://www.youtube.com/watch?v=8ClYUo_A3h0

A N D M U C H M O R E

• A whole talk could be done on it

• So I won’t do one

• 2 Good overview videos

• Tim Fox: Introducing Vert.x 2.0 - Taking Polyglot Application Development to the Next Level https://www.youtube.com/watch?v=3hv4QD5ZvKE

• good over view of vert.x capabilities w/lots of live demos

• Vert.x: This ain't your Dad's Node. https://www.youtube.com/watch?v=8ClYUo_A3h0

• good at showing Vert.x's advantages over Node.js

V E R T. X I S P R E T T Y A W E S O M E

V E R T. X I S P R E T T Y A W E S O M E

B U T I T ’ S M O R E S T U F F T O L E A R N

W H AT I F I T O L D Y O U Y O U C O U L D ?

O R I G I N A L J U B I L E E R E A D M E S L O G A N

O R I G I N A L J U B I L E E R E A D M E S L O G A N

"We need a web framework for Vertx.", you said.

O R I G I N A L J U B I L E E R E A D M E S L O G A N

"We need a web framework for Vertx.", you said.

"But why not use Vertx in your Rails applications, it's the most productive

web framework ever created."

J U B I L E E

J U B I L E E

• Originally Rack server w/ vert.x 2.0 built in

J U B I L E E

• Originally Rack server w/ vert.x 2.0 built in

• Now a Vert.x module that runs Rack

J U B I L E E

• Originally Rack server w/ vert.x 2.0 built in

• Now a Vert.x module that runs Rack

• improved performance and interaction with the Vert.x ecosystem

J U B I L E E

• Originally Rack server w/ vert.x 2.0 built in

• Now a Vert.x module that runs Rack

• improved performance and interaction with the Vert.x ecosystem

• All the power of vert.x AND you can keep doing Ruby/Rack programming

J U B I L E E

• Originally Rack server w/ vert.x 2.0 built in

• Now a Vert.x module that runs Rack

• improved performance and interaction with the Vert.x ecosystem

• All the power of vert.x AND you can keep doing Ruby/Rack programming

• Try that with Node!

6 R E A S O N S V E R T. X C O U L D B E Y O U R N E W B E S T F R I E N D

6 R E A S O N S V E R T. X C O U L D B E Y O U R N E W B E S T F R I E N D

• Concurrency

6 R E A S O N S V E R T. X C O U L D B E Y O U R N E W B E S T F R I E N D

• Concurrency

• Speed

6 R E A S O N S V E R T. X C O U L D B E Y O U R N E W B E S T F R I E N D

• Concurrency

• Speed

• Expanded Ecosystem

6 R E A S O N S V E R T. X C O U L D B E Y O U R N E W B E S T F R I E N D

• Concurrency

• Speed

• Expanded Ecosystem

• Built in upgrade/scaling path

6 R E A S O N S V E R T. X C O U L D B E Y O U R N E W B E S T F R I E N D

• Concurrency

• Speed

• Expanded Ecosystem

• Built in upgrade/scaling path

• Easy web sockets support

6 R E A S O N S V E R T. X C O U L D B E Y O U R N E W B E S T F R I E N D

• Concurrency

• Speed

• Expanded Ecosystem

• Built in upgrade/scaling path

• Easy web sockets support

• Reuse all your existing knowledge/resources

1 ) C O N C U R R E N C Y

1 ) C O N C U R R E N C Y

• Same Reactor pattern as Node

1 ) C O N C U R R E N C Y

• Same Reactor pattern as Node

• Each Verticle single threaded

1 ) C O N C U R R E N C Y

• Same Reactor pattern as Node

• Each Verticle single threaded

• Simple concurrency model, no threading

1 ) C O N C U R R E N C Y

• Same Reactor pattern as Node

• Each Verticle single threaded

• Simple concurrency model, no threading

• Multiple verticles, can do 1 per CPU

2 ) S P E E D

2 ) S P E E D

• JVM faster and getting faster all the time

2 ) S P E E D

• JVM faster and getting faster all the time

• Can use threads, cpus

2 ) S P E E D

• JVM faster and getting faster all the time

• Can use threads, cpus

• Benchmarks

L I E S , D A M N L I E S , A N D B E N C H M A R K S

L I E S , D A M N L I E S , A N D B E N C H M A R K S• http://vertxproject.wordpress.com/2012/05/09/vert-x-vs-node-js-simple-http-

benchmarks/

L I E S , D A M N L I E S , A N D B E N C H M A R K S• http://vertxproject.wordpress.com/2012/05/09/vert-x-vs-node-js-simple-http-

benchmarks/

Ruby

L I E S , D A M N L I E S , A N D B E N C H M A R K S• http://vertxproject.wordpress.com/2012/05/09/vert-x-vs-node-js-simple-http-

benchmarks/

Ruby

Node

L I E S , D A M N L I E S , A N D B E N C H M A R K S• http://vertxproject.wordpress.com/2012/05/09/vert-x-vs-node-js-simple-http-

benchmarks/

Ruby

Node

Node 6 processes

Ruby

Ruby

Best Node

J U B I L E E - 2 N D FA S T E S T R U B Y S E R V E R

J U B I L E E - 2 N D FA S T E S T R U B Y S E R V E R

• http://www.madebymarket.com/blog/dev/ruby-web-benchmark-report.html

J U B I L E E - 2 N D FA S T E S T R U B Y S E R V E R

• http://www.madebymarket.com/blog/dev/ruby-web-benchmark-report.html

• Maximum speed benchmarks vs typical

J U B I L E E - 2 N D FA S T E S T R U B Y S E R V E R

• http://www.madebymarket.com/blog/dev/ruby-web-benchmark-report.html

• Maximum speed benchmarks vs typical

• JRuby clear leader across the board

J U B I L E E - 2 N D FA S T E S T R U B Y S E R V E R

• http://www.madebymarket.com/blog/dev/ruby-web-benchmark-report.html

• Maximum speed benchmarks vs typical

• JRuby clear leader across the board

• Almost as fast as golang

Golang hello world was 10,500 reqs/sec

3 ) E X PA N D E D E C O S Y S T E M

3 ) E X PA N D E D E C O S Y S T E M

• Rubygems

3 ) E X PA N D E D E C O S Y S T E M

• Rubygems

• Must run under JRuby

3 ) E X PA N D E D E C O S Y S T E M

• Rubygems

• Must run under JRuby

• Vertx modules (200 at time of writing)

3 ) E X PA N D E D E C O S Y S T E M

• Rubygems

• Must run under JRuby

• Vertx modules (200 at time of writing)

• Entire JVM ecosystem, languages, libraries

3 ) E X PA N D E D E C O S Y S T E M

• Rubygems

• Must run under JRuby

• Vertx modules (200 at time of writing)

• Entire JVM ecosystem, languages, libraries

• Call other JVM languages directly from JRuby

3 ) E X PA N D E D E C O S Y S T E M

• Rubygems

• Must run under JRuby

• Vertx modules (200 at time of writing)

• Entire JVM ecosystem, languages, libraries

• Call other JVM languages directly from JRuby

• Can run other JVM language verticles and communicate via Event Bus

4 ) B U I LT I N U P G R A D E / S C A L I N G PAT H

4 ) B U I LT I N U P G R A D E / S C A L I N G PAT H

• Designed for multiple verticles (async)

4 ) B U I LT I N U P G R A D E / S C A L I N G PAT H

• Designed for multiple verticles (async)

• Worker verticles (slow)

4 ) B U I LT I N U P G R A D E / S C A L I N G PAT H

• Designed for multiple verticles (async)

• Worker verticles (slow)

• Inter communication

4 ) B U I LT I N U P G R A D E / S C A L I N G PAT H

• Designed for multiple verticles (async)

• Worker verticles (slow)

• Inter communication

• Core APIs

4 ) B U I LT I N U P G R A D E / S C A L I N G PAT H

• Designed for multiple verticles (async)

• Worker verticles (slow)

• Inter communication

• Core APIs

• Event Bus

4 ) B U I LT I N U P G R A D E / S C A L I N G PAT H

• Designed for multiple verticles (async)

• Worker verticles (slow)

• Inter communication

• Core APIs

• Event Bus

• Shared Data

4 ) B U I LT I N U P G R A D E / S C A L I N G PAT H

• Designed for multiple verticles (async)

• Worker verticles (slow)

• Inter communication

• Core APIs

• Event Bus

• Shared Data

• Clustering

4 ) B U I LT I N U P G R A D E / S C A L I N G PAT H

• Designed for multiple verticles (async)

• Worker verticles (slow)

• Inter communication

• Core APIs

• Event Bus

• Shared Data

• Clustering

• High Availability

5 ) E A S Y W E B S O C K E T S S U P P O R T

5 ) E A S Y W E B S O C K E T S S U P P O R T

• SocketIO support

5 ) E A S Y W E B S O C K E T S S U P P O R T

• SocketIO support

• SockJS support

5 ) E A S Y W E B S O C K E T S S U P P O R T

• SocketIO support

• SockJS support

• ** Event Bus **

5 ) E A S Y W E B S O C K E T S S U P P O R T

• SocketIO support

• SockJS support

• ** Event Bus **

• Easy

5 ) E A S Y W E B S O C K E T S S U P P O R T

• SocketIO support

• SockJS support

• ** Event Bus **

• Easy

• Extends into the browser

6 ) R E U S E A L L Y O U R E X I S T I N G K N O W L E D G E /R E S O U R C E S

6 ) R E U S E A L L Y O U R E X I S T I N G K N O W L E D G E /R E S O U R C E S

• Ruby

6 ) R E U S E A L L Y O U R E X I S T I N G K N O W L E D G E /R E S O U R C E S

• Ruby

• Rack programming

6 ) R E U S E A L L Y O U R E X I S T I N G K N O W L E D G E /R E S O U R C E S

• Ruby

• Rack programming

• i.e. Rails, Sinatra, etc.

6 ) R E U S E A L L Y O U R E X I S T I N G K N O W L E D G E /R E S O U R C E S

• Ruby

• Rack programming

• i.e. Rails, Sinatra, etc.

• Gems

6 ) R E U S E A L L Y O U R E X I S T I N G K N O W L E D G E /R E S O U R C E S

• Ruby

• Rack programming

• i.e. Rails, Sinatra, etc.

• Gems

• Low barrier to entry for the Rubyist!

J U B I L E E C A N M A K E Y O U H A P P Y

J U B I L E E C A N M A K E Y O U H A P P Y

I N S TA L L AT I O N

$ gem install jubilee!

R U N N I N G W I T H R A C K

$ cd a-jruby-compatible-rack-app!# Start it, several options available!$ jubilee <options> !# If you don’t need jubilee options!$ rails s jubilee!$ rackup -s jubilee!# running as vertx module!$ vertx run config.ru -conf config.json !

W H AT A B O U T H E R O K U ?

W H AT A B O U T H E R O K U ?• http://funkworks.blogspot.com/2014/08/deploying-rails-41-app-served-by.html

W H AT A B O U T H E R O K U ?• http://funkworks.blogspot.com/2014/08/deploying-rails-41-app-served-by.html

ruby '2.0.0', engine: 'jruby', engine_version: '1.7.13'!gem 'jubilee', :platforms => [:jruby]!gem 'rails_12factor'

Gemfile

W H AT A B O U T H E R O K U ?• http://funkworks.blogspot.com/2014/08/deploying-rails-41-app-served-by.html

ruby '2.0.0', engine: 'jruby', engine_version: '1.7.13'!gem 'jubilee', :platforms => [:jruby]!gem 'rails_12factor'

web: jubilee --eventbus /eventbus -n 1 —e $RACK_ENV -p $PORT !

Gemfile

Procfile

W H AT A B O U T H E R O K U ?• http://funkworks.blogspot.com/2014/08/deploying-rails-41-app-served-by.html

ruby '2.0.0', engine: 'jruby', engine_version: '1.7.13'!gem 'jubilee', :platforms => [:jruby]!gem 'rails_12factor'

web: jubilee --eventbus /eventbus -n 1 —e $RACK_ENV -p $PORT !

heroku config:add JRUBY_OPTS="-J-Xmn128m -J-Xms768m -J-Xmx768m"!

Gemfile

Procfile

Set JRuby/JVM Opts

G E T T I N G T H E M E S S A G E A C R O S S

G E T T I N G T H E M E S S A G E A C R O S S

• Everyone has slides

G E T T I N G T H E M E S S A G E A C R O S S

• Everyone has slides

• Many have demos

G E T T I N G T H E M E S S A G E A C R O S S

• Everyone has slides

• Many have demos

• I want 1st hand interaction -

A N E X P E R I E N C E

A N E X P E R I E N C E

N O D E ’ S S W E E T S P O T

N O D E ’ S S W E E T S P O T

• Chat - The sample app that everyone makes

N O D E ’ S S W E E T S P O T

• Chat - The sample app that everyone makes

• How do I make a chat app a little more interesting?

N O D E ’ S S W E E T S P O T

• Chat - The sample app that everyone makes

• How do I make a chat app a little more interesting?

• How about a game with chat characterstics

M M O W H AT ?

M M O W H AT ?

• Rock, Paper, Scissors

M M O W H AT ?

• Rock, Paper, Scissors

• Really!

M M O W H AT ?

• Rock, Paper, Scissors

• Really!

• 4 kids, demanding job - World of Warcraft is out

E X P E R I E N C I N G J U B I L E E I N A C T I O N

E X P E R I E N C I N G J U B I L E E I N A C T I O N

• Everyone in the room sign on

E X P E R I E N C I N G J U B I L E E I N A C T I O N

• Everyone in the room sign on

• Play each other

E X P E R I E N C I N G J U B I L E E I N A C T I O N

• Everyone in the room sign on

• Play each other

• Have fun!

E X P E R I E N C I N G J U B I L E E I N A C T I O N

• Everyone in the room sign on

• Play each other

• Have fun!

• Then we talk

E X P E R I E N C I N G J U B I L E E I N A C T I O N

• Everyone in the room sign on

• Play each other

• Have fun!

• Then we talk

• EXPERIMENT WARNING: Intentionally running in 1 dyno, curious to see how it scales

E X P E R I E N C I N G J U B I L E E I N A C T I O N

• Everyone in the room sign on

• Play each other

• Have fun!

• Then we talk

• EXPERIMENT WARNING: Intentionally running in 1 dyno, curious to see how it scales

• Conference WIFI

E X P E R I E N C I N G J U B I L E E I N A C T I O N

• Everyone in the room sign on

• Play each other

• Have fun!

• Then we talk

• EXPERIMENT WARNING: Intentionally running in 1 dyno, curious to see how it scales

• Conference WIFI

• Sound effects file (bad decision?)

R O C K PA P E R S C I S S O R S M AY H E M

R P S M

R P S M

H T T P : / / B I T. LY / R P S M AY H E M!

P !

!

!

!

M

!

!

S R

W H AT T O D O

W H AT T O D O

• Go to http://bit.ly/rpsmayhem

W H AT T O D O

• Go to http://bit.ly/rpsmayhem

• Login with twitter

W H AT T O D O

• Go to http://bit.ly/rpsmayhem

• Login with twitter

• Android users click the “Play Sound” button to prime sound (HTML5 audio not quite there yet)

W H AT T O D O

• Go to http://bit.ly/rpsmayhem

• Login with twitter

• Android users click the “Play Sound” button to prime sound (HTML5 audio not quite there yet)

• Likely to be the most taxing on conference wifi, (experiment)

W H AT T O D O

• Go to http://bit.ly/rpsmayhem

• Login with twitter

• Android users click the “Play Sound” button to prime sound (HTML5 audio not quite there yet)

• Likely to be the most taxing on conference wifi, (experiment)

• Pick opponents and play

W H AT T O D O

• Go to http://bit.ly/rpsmayhem

• Login with twitter

• Android users click the “Play Sound” button to prime sound (HTML5 audio not quite there yet)

• Likely to be the most taxing on conference wifi, (experiment)

• Pick opponents and play

• Observe activity, player states

W H AT T O D O

• Go to http://bit.ly/rpsmayhem

• Login with twitter

• Android users click the “Play Sound” button to prime sound (HTML5 audio not quite there yet)

• Likely to be the most taxing on conference wifi, (experiment)

• Pick opponents and play

• Observe activity, player states

• If something’s off, refresh page, in progress matches will get rejoined

P L AY I T !

A P P B R E A K D O W N

R I G H T T O O L F O R T H E J O B

R I G H T T O O L F O R T H E J O B

• Rails

R I G H T T O O L F O R T H E J O B

• Rails

• Login - omniauth, devise

R I G H T T O O L F O R T H E J O B

• Rails

• Login - omniauth, devise

• Views - haml

R I G H T T O O L F O R T H E J O B

• Rails

• Login - omniauth, devise

• Views - haml

• DB - ActiveRecord, migrations

R I G H T T O O L F O R T H E J O B

• Rails

• Login - omniauth, devise

• Views - haml

• DB - ActiveRecord, migrations

• Jubilee/Vert.x

R I G H T T O O L F O R T H E J O B

• Rails

• Login - omniauth, devise

• Views - haml

• DB - ActiveRecord, migrations

• Jubilee/Vert.x

• Event Bus - websockets, concurrency, subsystem communciation

R I G H T T O O L F O R T H E J O B

• Rails

• Login - omniauth, devise

• Views - haml

• DB - ActiveRecord, migrations

• Jubilee/Vert.x

• Event Bus - websockets, concurrency, subsystem communciation

• Shared Data - quick shared memory

R I G H T T O O L F O R T H E J O B

• Rails

• Login - omniauth, devise

• Views - haml

• DB - ActiveRecord, migrations

• Jubilee/Vert.x

• Event Bus - websockets, concurrency, subsystem communciation

• Shared Data - quick shared memory

• Vertx::Timer - enforce challenge acceptance timeout

R I G H T T O O L F O R T H E J O B

• Rails

• Login - omniauth, devise

• Views - haml

• DB - ActiveRecord, migrations

• Jubilee/Vert.x

• Event Bus - websockets, concurrency, subsystem communciation

• Shared Data - quick shared memory

• Vertx::Timer - enforce challenge acceptance timeout

• Additional Verticle - Bot

R I G H T T O O L F O R T H E J O B

• Rails

• Login - omniauth, devise

• Views - haml

• DB - ActiveRecord, migrations

• Jubilee/Vert.x

• Event Bus - websockets, concurrency, subsystem communciation

• Shared Data - quick shared memory

• Vertx::Timer - enforce challenge acceptance timeout

• Additional Verticle - Bot

• Worker Verticle - TBI Leaderboard

A P P S U M M A R Y

A P P S U M M A R Y

• Rails to get to the game

A P P S U M M A R Y

• Rails to get to the game

• Jubilee/Vert.x to play the game

S C R E E N B Y S C R E E N

M A I N PA G E

M A I N PA G E

Main page is vanilla Rails Sign in

S I G N I N W I T H T W I T T E R

S I G N I N W I T H T W I T T E R

Omniauth gem makes it easy

C H AT L I K E F E AT U R E S O F T H E G A M E

C H AT L I K E F E AT U R E S O F T H E G A M E

You

C H AT L I K E F E AT U R E S O F T H E G A M E

YouLive Activity Stream

C H AT L I K E F E AT U R E S O F T H E G A M E

YouLive Activity Stream

Live presence and state

C H A L L E N G E A N O P P O N E N T

You can give up

C H A L L E N G E T I M E O U T

Jubilee/Vert.x Timer checks and cancels the

challenge

R E A LT I M E C H A L L E N G E

R E A LT I M E C H A L L E N G E

Connected to server and each other by EventBus

C H A L L E N G E T I M E O U T

C H A L L E N G E T I M E O U T

Jubilee/Vert.x Timer checks and cancels the

challenge

R E A LT I M E M M O G A M E P L AY

R E A LT I M E M M O G A M E P L AY

Connected to server and each other by EventBus,

uses SharedData for speed

R E A LT I M E M M O G A M E P L AY

Connected to server and each other by EventBus,

uses SharedData for speed

The bot is it’s own Verticle, playing via

EventBus

A R C H I T E C T U R E I N 1 D Y N O

R A I L S

E V E N T B U SB O T

S V R

S H A R E D D ATA

B R O W S E R C L I E N T

T I M E R S

A R C H I T E C T U R E I N 1 D Y N O

R A I L S

E V E N T B U SB O T

S V R

S H A R E D D ATA

B R O W S E R C L I E N T

T I M E R S

Normal Rails App

A R C H I T E C T U R E I N 1 D Y N O

R A I L S

E V E N T B U SB O T

S V R

S H A R E D D ATA

B R O W S E R C L I E N T

T I M E R S

Normal Rails App

Rabbit MQ or similar

A R C H I T E C T U R E I N 1 D Y N O

R A I L S

E V E N T B U SB O T

S V R

S H A R E D D ATA

B R O W S E R C L I E N T

T I M E R S

Normal Rails App

Server is EventBus handler, would be

another process to handle concurrency

Rabbit MQ or similar

A R C H I T E C T U R E I N 1 D Y N O

R A I L S

E V E N T B U SB O T

S V R

S H A R E D D ATA

B R O W S E R C L I E N T

T I M E R S

Normal Rails App

Server is EventBus handler, would be

another process to handle concurrency

Redis, Tokyo Cabinet, etc. Rabbit MQ or similar

A R C H I T E C T U R E I N 1 D Y N O

R A I L S

E V E N T B U SB O T

S V R

S H A R E D D ATA

B R O W S E R C L I E N T

T I M E R S

Normal Rails App

Server is EventBus handler, would be

another process to handle concurrency

Redis, Tokyo Cabinet, etc. Rabbit MQ or similar

Websocket server/push

A R C H I T E C T U R E I N 1 D Y N O

R A I L S

E V E N T B U SB O T

S V R

S H A R E D D ATA

B R O W S E R C L I E N T

T I M E R S

Normal Rails App

Bot Verticle would be another process

Server is EventBus handler, would be

another process to handle concurrency

Redis, Tokyo Cabinet, etc. Rabbit MQ or similar

Websocket server/push

A R C H I T E C T U R E I N 1 D Y N O

R A I L S

E V E N T B U SB O T

S V R

S H A R E D D ATA

B R O W S E R C L I E N T

T I M E R S

Normal Rails App

Bot Verticle would be another process

Server is EventBus handler, would be

another process to handle concurrency

Redis, Tokyo Cabinet, etc. Rabbit MQ or similar

Websocket server/push

Expire unanswered challenges Delayed job

D E S I G N E D T O W O R K T O G E T H E R

A S O P P O S E D T O D U C T TA P E D T O G E T H E R

D U C T TA P E

A P P C O D E S TAT S

A P P C O D E S TAT S

• Client code 497 LOC Opal (including whitespace and debug)

A P P C O D E S TAT S

• Client code 497 LOC Opal (including whitespace and debug)

• game.js.rb 444

A P P C O D E S TAT S

• Client code 497 LOC Opal (including whitespace and debug)

• game.js.rb 444

• event_bus.rb 52

A P P C O D E S TAT S

• Client code 497 LOC Opal (including whitespace and debug)

• game.js.rb 444

• event_bus.rb 52

• Server code: vertx initializer 50 LOC including whitespace and comments

C O D E

C O D E

• Rails code - typical stuff you’re already doing - don’t need to see

C O D E

• Rails code - typical stuff you’re already doing - don’t need to see

• Client Game code - similar to what you might do browser side - don’t need to see

C O D E

• Rails code - typical stuff you’re already doing - don’t need to see

• Client Game code - similar to what you might do browser side - don’t need to see

• Jubilee Code - you’ll want to see

C O D E

• Rails code - typical stuff you’re already doing - don’t need to see

• Client Game code - similar to what you might do browser side - don’t need to see

• Jubilee Code - you’ll want to see

• EventBus communication code - the heart of a Jubilee/Vert.x app

C O D E

• Rails code - typical stuff you’re already doing - don’t need to see

• Client Game code - similar to what you might do browser side - don’t need to see

• Jubilee Code - you’ll want to see

• EventBus communication code - the heart of a Jubilee/Vert.x app

• Deploying another verticle, Bot, TBI Leaderboard

C O D E

• Rails code - typical stuff you’re already doing - don’t need to see

• Client Game code - similar to what you might do browser side - don’t need to see

• Jubilee Code - you’ll want to see

• EventBus communication code - the heart of a Jubilee/Vert.x app

• Deploying another verticle, Bot, TBI Leaderboard

• Shared Data

C O D E

• Rails code - typical stuff you’re already doing - don’t need to see

• Client Game code - similar to what you might do browser side - don’t need to see

• Jubilee Code - you’ll want to see

• EventBus communication code - the heart of a Jubilee/Vert.x app

• Deploying another verticle, Bot, TBI Leaderboard

• Shared Data

• Timer

E V E N T B U S S E T U P - R A I L Sbegin! require 'vertx'! def to_array(shared_set)! ret = []! shared_set.each{ |item| ret << item}! ret! end!! Vertx::EventBus.register_handler('logout') do |message|! user_id = message.body! puts "logging out #{user_id}"! Vertx::SharedData.get_set(:users).delete(user_id)! Vertx::EventBus.publish("user_logout", user_id)! end!! # register the user and return the previous users! Vertx::EventBus.register_handler('login') do |message|! user_id = message.body! users = Vertx::SharedData.get_set(:users).add(user_id)! user_records = User.find(to_array(users)).to_json! message.reply(users: to_array(users))! user = User.find user_id! Vertx::EventBus.publish("new_user", user.to_json)! end!end

E V E N T B U S S E T U P - R A I L Sbegin! require 'vertx'! def to_array(shared_set)! ret = []! shared_set.each{ |item| ret << item}! ret! end!! Vertx::EventBus.register_handler('logout') do |message|! user_id = message.body! puts "logging out #{user_id}"! Vertx::SharedData.get_set(:users).delete(user_id)! Vertx::EventBus.publish("user_logout", user_id)! end!! # register the user and return the previous users! Vertx::EventBus.register_handler('login') do |message|! user_id = message.body! users = Vertx::SharedData.get_set(:users).add(user_id)! user_records = User.find(to_array(users)).to_json! message.reply(users: to_array(users))! user = User.find user_id! Vertx::EventBus.publish("new_user", user.to_json)! end!end

E V E N T B U S S E T U P - R A I L Sbegin! require 'vertx'! def to_array(shared_set)! ret = []! shared_set.each{ |item| ret << item}! ret! end!! Vertx::EventBus.register_handler('logout') do |message|! user_id = message.body! puts "logging out #{user_id}"! Vertx::SharedData.get_set(:users).delete(user_id)! Vertx::EventBus.publish("user_logout", user_id)! end!! # register the user and return the previous users! Vertx::EventBus.register_handler('login') do |message|! user_id = message.body! users = Vertx::SharedData.get_set(:users).add(user_id)! user_records = User.find(to_array(users)).to_json! message.reply(users: to_array(users))! user = User.find user_id! Vertx::EventBus.publish("new_user", user.to_json)! end!end

E V E N T B U S S E T U P - R A I L Sbegin! require 'vertx'! def to_array(shared_set)! ret = []! shared_set.each{ |item| ret << item}! ret! end!! Vertx::EventBus.register_handler('logout') do |message|! user_id = message.body! puts "logging out #{user_id}"! Vertx::SharedData.get_set(:users).delete(user_id)! Vertx::EventBus.publish("user_logout", user_id)! end!! # register the user and return the previous users! Vertx::EventBus.register_handler('login') do |message|! user_id = message.body! users = Vertx::SharedData.get_set(:users).add(user_id)! user_records = User.find(to_array(users)).to_json! message.reply(users: to_array(users))! user = User.find user_id! Vertx::EventBus.publish("new_user", user.to_json)! end!end

E V E N T B U S S E T U P - R A I L Sbegin! require 'vertx'! def to_array(shared_set)! ret = []! shared_set.each{ |item| ret << item}! ret! end!! Vertx::EventBus.register_handler('logout') do |message|! user_id = message.body! puts "logging out #{user_id}"! Vertx::SharedData.get_set(:users).delete(user_id)! Vertx::EventBus.publish("user_logout", user_id)! end!! # register the user and return the previous users! Vertx::EventBus.register_handler('login') do |message|! user_id = message.body! users = Vertx::SharedData.get_set(:users).add(user_id)! user_records = User.find(to_array(users)).to_json! message.reply(users: to_array(users))! user = User.find user_id! Vertx::EventBus.publish("new_user", user.to_json)! end!end

E V E N T B U S S E T U P - R A I L Sbegin! require 'vertx'! def to_array(shared_set)! ret = []! shared_set.each{ |item| ret << item}! ret! end!! Vertx::EventBus.register_handler('logout') do |message|! user_id = message.body! puts "logging out #{user_id}"! Vertx::SharedData.get_set(:users).delete(user_id)! Vertx::EventBus.publish("user_logout", user_id)! end!! # register the user and return the previous users! Vertx::EventBus.register_handler('login') do |message|! user_id = message.body! users = Vertx::SharedData.get_set(:users).add(user_id)! user_records = User.find(to_array(users)).to_json! message.reply(users: to_array(users))! user = User.find user_id! Vertx::EventBus.publish("new_user", user.to_json)! end!end

S E R V E R C O N T I N U E D

begin! Vertx::EventBus.register_handler('game') do |message|! server = Server.new(Vertx::EventBus, Vertx)! cmd_hash = message.body["map"]! case cmd_hash["cmd"]! when "new_game"! server.new_game(cmd_hash["challenge_id"], cmd_hash["challenger_id"], cmd_hash["challenged_id"])! when "move"! server.move(cmd_hash["game_id"], cmd_hash["user_id"], cmd_hash["move"])! when "challenge_accepted"! server.challenge_accepted(cmd_hash["challenge_id"], cmd_hash["challenger_id"], cmd_hash["challenged_id"])! when "give_up_challenge"! server.give_up_challenge(cmd_hash["challenged_id"], cmd_hash["challenger_id"])! else! puts("Unhandled cmd: #{cmd_hash.inspect}")! end! end! Vertx.deploy_verticle("bot.rb")!rescue LoadError! puts "Vertx is NOT defined - no loading of vertx initializer"!end

S E R V E R C O N T I N U E D

begin! Vertx::EventBus.register_handler('game') do |message|! server = Server.new(Vertx::EventBus, Vertx)! cmd_hash = message.body["map"]! case cmd_hash["cmd"]! when "new_game"! server.new_game(cmd_hash["challenge_id"], cmd_hash["challenger_id"], cmd_hash["challenged_id"])! when "move"! server.move(cmd_hash["game_id"], cmd_hash["user_id"], cmd_hash["move"])! when "challenge_accepted"! server.challenge_accepted(cmd_hash["challenge_id"], cmd_hash["challenger_id"], cmd_hash["challenged_id"])! when "give_up_challenge"! server.give_up_challenge(cmd_hash["challenged_id"], cmd_hash["challenger_id"])! else! puts("Unhandled cmd: #{cmd_hash.inspect}")! end! end! Vertx.deploy_verticle("bot.rb")!rescue LoadError! puts "Vertx is NOT defined - no loading of vertx initializer"!end

S E R V E R C O N T I N U E D

begin! Vertx::EventBus.register_handler('game') do |message|! server = Server.new(Vertx::EventBus, Vertx)! cmd_hash = message.body["map"]! case cmd_hash["cmd"]! when "new_game"! server.new_game(cmd_hash["challenge_id"], cmd_hash["challenger_id"], cmd_hash["challenged_id"])! when "move"! server.move(cmd_hash["game_id"], cmd_hash["user_id"], cmd_hash["move"])! when "challenge_accepted"! server.challenge_accepted(cmd_hash["challenge_id"], cmd_hash["challenger_id"], cmd_hash["challenged_id"])! when "give_up_challenge"! server.give_up_challenge(cmd_hash["challenged_id"], cmd_hash["challenger_id"])! else! puts("Unhandled cmd: #{cmd_hash.inspect}")! end! end! Vertx.deploy_verticle("bot.rb")!rescue LoadError! puts "Vertx is NOT defined - no loading of vertx initializer"!end

C L I E N T S I D E E V E N T B U S S E T U P ( O PA L )

def setup_eventbus! @event_bus = EventBus.new! @event_bus.onopen {! @event_bus.send_msg(:login, @uid)! @event_bus.register_handler(:new_user) do |data|! json = JSON.parse(data)! @player_info[json[:id]] = { name: json[:name], image: json[:image]}! render_potential_victim(json) unless json[:id].to_i == @uid.to_i! append_activity("#{json['name']} joined")! end

C L I E N T S I D E E V E N T B U S S E T U P ( O PA L )

def setup_eventbus! @event_bus = EventBus.new! @event_bus.onopen {! @event_bus.send_msg(:login, @uid)! @event_bus.register_handler(:new_user) do |data|! json = JSON.parse(data)! @player_info[json[:id]] = { name: json[:name], image: json[:image]}! render_potential_victim(json) unless json[:id].to_i == @uid.to_i! append_activity("#{json['name']} joined")! end

C L I E N T S I D E E V E N T B U S S E T U P ( O PA L )

def setup_eventbus! @event_bus = EventBus.new! @event_bus.onopen {! @event_bus.send_msg(:login, @uid)! @event_bus.register_handler(:new_user) do |data|! json = JSON.parse(data)! @player_info[json[:id]] = { name: json[:name], image: json[:image]}! render_potential_victim(json) unless json[:id].to_i == @uid.to_i! append_activity("#{json['name']} joined")! end

C L I E N T S I D E E V E N T B U S S E T U P ( O PA L )

def setup_eventbus! @event_bus = EventBus.new! @event_bus.onopen {! @event_bus.send_msg(:login, @uid)! @event_bus.register_handler(:new_user) do |data|! json = JSON.parse(data)! @player_info[json[:id]] = { name: json[:name], image: json[:image]}! render_potential_victim(json) unless json[:id].to_i == @uid.to_i! append_activity("#{json['name']} joined")! end

C L I E N T C O N T I N U E D @event_bus.register_handler(@uid) do |data|! cmd_hash = Native(data)! case cmd_hash["cmd"]! when "challenge"! show_challenge(cmd_hash)! when "new_game"! new_game(cmd_hash["challenger_id"], cmd_hash["challenged_id"], cmd_hash["game_id"])! when "move"! process_move(cmd_hash)! when "give_up_challenge"! give_up_challenge(cmd_hash)! when "challenge_aborted"! challenger_name = @player_info[cmd_hash["challenged_id"]][:name]! hide_overlay! swal("You missed a challenge from #{challenger_name}")! when "user_details"! json = @player_info[@uid].merge({id: @uid}).to_json! puts "Sending user_details #{json}"! replier.call(json)! when "not_available"! hide_overlay! swal "#{@player_info[@desired_challenged_id][:name]} is not available to play"! else! puts "can't handle "! end! end!end # split in half

def cont! @event_bus.register_handler(:activity) do |data|! append_activity(data)! end! @event_bus.register_handler(:player_state) do |data|! `console.log(data); `! state_hash = Native(data)! set_player_states(state_hash)! end! @event_bus.register_handler(:user_logout) do |data|! user_id = data! puts "logging out #{user_id}"! append_activity("#{@player_info[user_id]['name']} left")! Element.find("##{user_id}").hide! end! }!end!

B O T C O D E@handler = Vertx::EventBus.register_handler(BOT_ID) do |message|! cmd_hash = message.body! puts "\nBOT handling #{cmd_hash['cmd']}"! case cmd_hash["cmd"]! when "challenge"! Vertx::EventBus.send("game",! { cmd: "challenge_accepted",! challenge_id: cmd_hash["challenge_id"],! challenger_id: cmd_hash["challenger_id"],! challenged_id: BOT_ID! }! )! when "move"! process_move(cmd_hash)! when "give_up_challenge", "challenge_aborted", "not_available", "challenge_accepted"! # NO OP! else! puts "\nBOT can't handle #{cmd_hash.inspect}"! p cmd_hash! end!!end!!def vertx_stop! puts "Must exterminate self!"! Vertx::EventBus.unregister_handler( BOT_ID, @handler)!end

B O T C O D E@handler = Vertx::EventBus.register_handler(BOT_ID) do |message|! cmd_hash = message.body! puts "\nBOT handling #{cmd_hash['cmd']}"! case cmd_hash["cmd"]! when "challenge"! Vertx::EventBus.send("game",! { cmd: "challenge_accepted",! challenge_id: cmd_hash["challenge_id"],! challenger_id: cmd_hash["challenger_id"],! challenged_id: BOT_ID! }! )! when "move"! process_move(cmd_hash)! when "give_up_challenge", "challenge_aborted", "not_available", "challenge_accepted"! # NO OP! else! puts "\nBOT can't handle #{cmd_hash.inspect}"! p cmd_hash! end!!end!!def vertx_stop! puts "Must exterminate self!"! Vertx::EventBus.unregister_handler( BOT_ID, @handler)!end

B O T C O D E@handler = Vertx::EventBus.register_handler(BOT_ID) do |message|! cmd_hash = message.body! puts "\nBOT handling #{cmd_hash['cmd']}"! case cmd_hash["cmd"]! when "challenge"! Vertx::EventBus.send("game",! { cmd: "challenge_accepted",! challenge_id: cmd_hash["challenge_id"],! challenger_id: cmd_hash["challenger_id"],! challenged_id: BOT_ID! }! )! when "move"! process_move(cmd_hash)! when "give_up_challenge", "challenge_aborted", "not_available", "challenge_accepted"! # NO OP! else! puts "\nBOT can't handle #{cmd_hash.inspect}"! p cmd_hash! end!!end!!def vertx_stop! puts "Must exterminate self!"! Vertx::EventBus.unregister_handler( BOT_ID, @handler)!end

B O T C O D E@handler = Vertx::EventBus.register_handler(BOT_ID) do |message|! cmd_hash = message.body! puts "\nBOT handling #{cmd_hash['cmd']}"! case cmd_hash["cmd"]! when "challenge"! Vertx::EventBus.send("game",! { cmd: "challenge_accepted",! challenge_id: cmd_hash["challenge_id"],! challenger_id: cmd_hash["challenger_id"],! challenged_id: BOT_ID! }! )! when "move"! process_move(cmd_hash)! when "give_up_challenge", "challenge_aborted", "not_available", "challenge_accepted"! # NO OP! else! puts "\nBOT can't handle #{cmd_hash.inspect}"! p cmd_hash! end!!end!!def vertx_stop! puts "Must exterminate self!"! Vertx::EventBus.unregister_handler( BOT_ID, @handler)!end

S E R V E R T I M E R C O D E

# timer when challenged! timer_id = @container.set_timer(10000) do |timer_id|! check_accepted?(challenge_id, challenger_id, challenged_id)! end! timer_map = Vertx::SharedData.get_hash(:timers)! timer_map[challenge_id] = timer_id!!

# clear the timer if user aborts his challenge! timer_map = Vertx::SharedData.get_hash(:timers)! timer_id = timer_map[challenge_id]! if timer_id! Vertx.cancel_timer timer_id! timer_map.delete challenge_id! end

S E R V E R T I M E R C O D E

# timer when challenged! timer_id = @container.set_timer(10000) do |timer_id|! check_accepted?(challenge_id, challenger_id, challenged_id)! end! timer_map = Vertx::SharedData.get_hash(:timers)! timer_map[challenge_id] = timer_id!!

# clear the timer if user aborts his challenge! timer_map = Vertx::SharedData.get_hash(:timers)! timer_id = timer_map[challenge_id]! if timer_id! Vertx.cancel_timer timer_id! timer_map.delete challenge_id! end

S E R V E R T I M E R C O D E

# timer when challenged! timer_id = @container.set_timer(10000) do |timer_id|! check_accepted?(challenge_id, challenger_id, challenged_id)! end! timer_map = Vertx::SharedData.get_hash(:timers)! timer_map[challenge_id] = timer_id!!

# clear the timer if user aborts his challenge! timer_map = Vertx::SharedData.get_hash(:timers)! timer_id = timer_map[challenge_id]! if timer_id! Vertx.cancel_timer timer_id! timer_map.delete challenge_id! end

S E R V E R T I M E R C O D E

# timer when challenged! timer_id = @container.set_timer(10000) do |timer_id|! check_accepted?(challenge_id, challenger_id, challenged_id)! end! timer_map = Vertx::SharedData.get_hash(:timers)! timer_map[challenge_id] = timer_id!!

# clear the timer if user aborts his challenge! timer_map = Vertx::SharedData.get_hash(:timers)! timer_id = timer_map[challenge_id]! if timer_id! Vertx.cancel_timer timer_id! timer_map.delete challenge_id! end

S E R V E R T I M E R C O D E

# timer when challenged! timer_id = @container.set_timer(10000) do |timer_id|! check_accepted?(challenge_id, challenger_id, challenged_id)! end! timer_map = Vertx::SharedData.get_hash(:timers)! timer_map[challenge_id] = timer_id!!

# clear the timer if user aborts his challenge! timer_map = Vertx::SharedData.get_hash(:timers)! timer_id = timer_map[challenge_id]! if timer_id! Vertx.cancel_timer timer_id! timer_map.delete challenge_id! end

S E R V E R T I M E R C O D E

# timer when challenged! timer_id = @container.set_timer(10000) do |timer_id|! check_accepted?(challenge_id, challenger_id, challenged_id)! end! timer_map = Vertx::SharedData.get_hash(:timers)! timer_map[challenge_id] = timer_id!!

# clear the timer if user aborts his challenge! timer_map = Vertx::SharedData.get_hash(:timers)! timer_id = timer_map[challenge_id]! if timer_id! Vertx.cancel_timer timer_id! timer_map.delete challenge_id! end

J U B I L E E C O N S I D E R AT I O N S I N R A I L S

J U B I L E E C O N S I D E R AT I O N S I N R A I L S

• Setup server side EventBus in Rails initializer

J U B I L E E C O N S I D E R AT I O N S I N R A I L S

• Setup server side EventBus in Rails initializer

• Done in initializer so it is done for whole Rails app

J U B I L E E C O N S I D E R AT I O N S I N R A I L S

• Setup server side EventBus in Rails initializer

• Done in initializer so it is done for whole Rails app

• Wrap vertx initialization in begin rescue so Rake tasks (not running vert.x server) will run

D R A W B A C K S

D R A W B A C K S

• JRuby still 2nd class citizen, sometime have gem trouble or hard to get the config right

D R A W B A C K S

• JRuby still 2nd class citizen, sometime have gem trouble or hard to get the config right

• Debugging asynchronous multi agent systems still hard regardless

D R A W B A C K S

• JRuby still 2nd class citizen, sometime have gem trouble or hard to get the config right

• Debugging asynchronous multi agent systems still hard regardless

• Fine control will require vertx style deploy instead of Rails friendly jubilee

D R A W B A C K S

• JRuby still 2nd class citizen, sometime have gem trouble or hard to get the config right

• Debugging asynchronous multi agent systems still hard regardless

• Fine control will require vertx style deploy instead of Rails friendly jubilee

• Error messages can get swallowed inside of Event Handlers

D R A W B A C K S

• JRuby still 2nd class citizen, sometime have gem trouble or hard to get the config right

• Debugging asynchronous multi agent systems still hard regardless

• Fine control will require vertx style deploy instead of Rails friendly jubilee

• Error messages can get swallowed inside of Event Handlers

• Haven’t found the right place so that Jubilee/Vertx code auto reloads on Rails completely consistently

O N E M O R E T H I N G

O N E M O R E T H I N G

• Opal (Ruby in the browser) front end == All Ruby Stack

O N E M O R E T H I N G

• Opal (Ruby in the browser) front end == All Ruby Stack

• The same language on front end/back end advantage that Node touts is nice!

O N E M O R E T H I N G

• Opal (Ruby in the browser) front end == All Ruby Stack

• The same language on front end/back end advantage that Node touts is nice!

• This could be it’s own talk

O N E M O R E T H I N G

• Opal (Ruby in the browser) front end == All Ruby Stack

• The same language on front end/back end advantage that Node touts is nice!

• This could be it’s own talk

• I already did that (RubyConf 2013 https://vimeo.com/82573680 ) So I won’t do it here

R U B Y I N T H E B R O W S E R M A K E S M E H A P P Y

R U B Y I N T H E B R O W S E R M A K E S M E H A P P Y

T H A N K S

• Matz - Ruby

• DHH - Rails and jobs

• Charles Nutter, Tom Enebo - JRuby

• Tim Fox & Vert.x team - Vert.x

• Isaiah Peng - Jubilee

• Adam Beynon, Elia Schito, Meh’ - Opal

• You for listening

A D V I C E T O R U B Y I S T S

A D V I C E T O R U B Y I S T S

• Stay happy, you can still do most of your stuff in Ruby via Jubilee

A D V I C E T O R U B Y I S T S

• Stay happy, you can still do most of your stuff in Ruby via Jubilee

• Stay happy, you can grow/scale in Ruby via Jubilee

A D V I C E T O R U B Y I S T S

• Stay happy, you can still do most of your stuff in Ruby via Jubilee

• Stay happy, you can grow/scale in Ruby via Jubilee

• Don’t worry, Be Happy