having fun with play! 2, akka and websockets · @nytdevs | developers.nytimes.com play! 2, akka and...

20
@NYTDevs | developers.nytimes.com Play! 2, Akka and WebSockets Having fun with Victor Siu-Leung Chan NE Scala Symposium 2014

Upload: others

Post on 23-Jul-2020

13 views

Category:

Documents


0 download

TRANSCRIPT

Page 1: Having fun with Play! 2, Akka and WebSockets · @NYTDevs | developers.nytimes.com Play! 2, Akka and WebSockets Having fun with Victor Siu-Leung Chan NE Scala Symposium 2014

@NYTDevs | developers.nytimes.com

Play! 2, Akka and WebSockets

Having fun with

Victor Siu-Leung Chan NE Scala Symposium 2014

Page 2: Having fun with Play! 2, Akka and WebSockets · @NYTDevs | developers.nytimes.com Play! 2, Akka and WebSockets Having fun with Victor Siu-Leung Chan NE Scala Symposium 2014

@NYTDevs | developers.nytimes.com

NYT CMS to deliver news & articles Blackbeard

5 ~ 10 editors per article 300 ~ 400 articles per day

High interaction among users Single-page web application

Page 3: Having fun with Play! 2, Akka and WebSockets · @NYTDevs | developers.nytimes.com Play! 2, Akka and WebSockets Having fun with Victor Siu-Leung Chan NE Scala Symposium 2014

@NYTDevs | developers.nytimes.com

Scala 2.10.0

Play! 2.1.5 Akka 2.2.0

Backend Framework:

SBT 0.12.2

Page 4: Having fun with Play! 2, Akka and WebSockets · @NYTDevs | developers.nytimes.com Play! 2, Akka and WebSockets Having fun with Victor Siu-Leung Chan NE Scala Symposium 2014

@NYTDevs | developers.nytimes.com

Master Node (Singleton Actor) receive = { case MSG_SUBSCRIBE => //… case MSG_UNSUBSCRIBE => //...

Page 5: Having fun with Play! 2, Akka and WebSockets · @NYTDevs | developers.nytimes.com Play! 2, Akka and WebSockets Having fun with Victor Siu-Leung Chan NE Scala Symposium 2014

@NYTDevs | developers.nytimes.com

Master Node (Singleton Actor) receive = { case MSG_SUBSCRIBE => //… case MSG_UNSUBSCRIBE => //...

Singleton object of WebSocket endpoint object MasterNode { /* Get the singleton master actor */ lazy val master: ActorRef = { val masterActor = Akka.system.actorOf(Props[MasterNode], name = "masterNode") masterActor } }

Page 6: Having fun with Play! 2, Akka and WebSockets · @NYTDevs | developers.nytimes.com Play! 2, Akka and WebSockets Having fun with Victor Siu-Leung Chan NE Scala Symposium 2014

@NYTDevs | developers.nytimes.com

Master Node (Singleton Actor) receive = { case MSG_SUBSCRIBE => //… case MSG_UNSUBSCRIBE => //...

Yoda

Leaf Node (Yoda)

val Iteratee val Enumerator

* Create a child actor node

Page 7: Having fun with Play! 2, Akka and WebSockets · @NYTDevs | developers.nytimes.com Play! 2, Akka and WebSockets Having fun with Victor Siu-Leung Chan NE Scala Symposium 2014

@NYTDevs | developers.nytimes.com

Master Node (Singleton Actor) receive = { case MSG_SUBSCRIBE => //… case MSG_UNSUBSCRIBE => //...

Yoda

Leaf Node (Yoda)

val Iteratee val Enumerator

Iteratees and Enumerator val in: Iteratee[JsValue, _] = Iteratee.foreach[JsValue] { msg => context.parent ! Msg } val (outEnum, outChannel): (Enumerator[JsValue], Concurrent.Channel[JsValue]) = Concurrent.broadcast[JsValue]

Page 8: Having fun with Play! 2, Akka and WebSockets · @NYTDevs | developers.nytimes.com Play! 2, Akka and WebSockets Having fun with Victor Siu-Leung Chan NE Scala Symposium 2014

@NYTDevs | developers.nytimes.com

Master Node (Singleton Actor)

Yoda

Leaf Node (Yoda)

val Iteratee val Enumerator

Yoda

receive = { case MSG_SUBSCRIBE => //… case MSG_UNSUBSCRIBE => //...

Page 9: Having fun with Play! 2, Akka and WebSockets · @NYTDevs | developers.nytimes.com Play! 2, Akka and WebSockets Having fun with Victor Siu-Leung Chan NE Scala Symposium 2014

@NYTDevs | developers.nytimes.com

Master Node (Singleton Actor)

Yoda

Leaf Node (Yoda)

val Iteratee val Enumerator

Yoda

Darth Vader

Leaf Node (Darth Vader)

val Iteratee val Enumerator

* Create another child actor node

receive = { case MSG_SUBSCRIBE => //… case MSG_UNSUBSCRIBE => //...

Page 10: Having fun with Play! 2, Akka and WebSockets · @NYTDevs | developers.nytimes.com Play! 2, Akka and WebSockets Having fun with Victor Siu-Leung Chan NE Scala Symposium 2014

@NYTDevs | developers.nytimes.com

Master Node (Singleton Actor)

Yoda

Leaf Node (Yoda)

val Iteratee val Enumerator

Yoda

Darth Vader

Leaf Node (Darth Vader)

val Iteratee val Enumerator

receive = { case MSG_SUBSCRIBE => //… case MSG_UNSUBSCRIBE => //...

BroadCaster

If … else …

Controller/ External CMS (ActiveMQ)

Page 11: Having fun with Play! 2, Akka and WebSockets · @NYTDevs | developers.nytimes.com Play! 2, Akka and WebSockets Having fun with Victor Siu-Leung Chan NE Scala Symposium 2014

@NYTDevs | developers.nytimes.com

Master Node (Singleton Actor)

Yoda

Leaf Node (Yoda)

val Iteratee val Enumerator

Yoda

Darth Vader

Leaf Node (Darth Vader)

val Iteratee val Enumerator

receive = { case MSG_SUBSCRIBE => //… case MSG_UNSUBSCRIBE => //...

BroadCaster

If … else …

Controller/ External CMS (ActiveMQ)

node ! PiosonPill

Page 12: Having fun with Play! 2, Akka and WebSockets · @NYTDevs | developers.nytimes.com Play! 2, Akka and WebSockets Having fun with Victor Siu-Leung Chan NE Scala Symposium 2014

@NYTDevs | developers.nytimes.com

Design Pattern

Lazy initialization

Singleton Chain of responsibility

decorator Adapter

Cake pattern

Self-type annotation

Domain Driven Design (DDD)

Factory

Command

Strategy

Page 13: Having fun with Play! 2, Akka and WebSockets · @NYTDevs | developers.nytimes.com Play! 2, Akka and WebSockets Having fun with Victor Siu-Leung Chan NE Scala Symposium 2014

@NYTDevs | developers.nytimes.com

Sharp learning curve

Result

Quick development cycle. Agile

User satisfaction J

Page 14: Having fun with Play! 2, Akka and WebSockets · @NYTDevs | developers.nytimes.com Play! 2, Akka and WebSockets Having fun with Victor Siu-Leung Chan NE Scala Symposium 2014

@NYTDevs | developers.nytimes.com

Filters for every HTTP request What we’ve learned

object AuthFilter extends Filter with Secured { override def apply(next: RequestHeader => Result)(rh: RequestHeader): Result = { if (authRequired(rh)) { checkAuthentication(next)(rh) } else next(rh) }

Page 15: Having fun with Play! 2, Akka and WebSockets · @NYTDevs | developers.nytimes.com Play! 2, Akka and WebSockets Having fun with Victor Siu-Leung Chan NE Scala Symposium 2014

@NYTDevs | developers.nytimes.com

Qualify private method, easier to test What we’ve learned

package blackbeard.controllers private[controllers] def workflowHelper = { … } //private to the package ========================================= object ArticleControllerSpec extends Specification { //in testing package “private helper function” should { “be accessed” in { workflowHelper

Page 16: Having fun with Play! 2, Akka and WebSockets · @NYTDevs | developers.nytimes.com Play! 2, Akka and WebSockets Having fun with Victor Siu-Leung Chan NE Scala Symposium 2014

@NYTDevs | developers.nytimes.com

Define custom write for serializable object What we’ve learned

implicit val articleWrites = Json.writes[Article] def articleMinWrites = new Writes[Article] { def writes(a: Article): JsValue = { //get only the core fields …. Json.toJson(article)(articleMinWrites)

Page 17: Having fun with Play! 2, Akka and WebSockets · @NYTDevs | developers.nytimes.com Play! 2, Akka and WebSockets Having fun with Victor Siu-Leung Chan NE Scala Symposium 2014

@NYTDevs | developers.nytimes.com

Restful Call over WebSocket message to command

What we’ve learned

Good for frontend framework

Use Play JSON validation API

Keep actor logic as simple as possible

Page 18: Having fun with Play! 2, Akka and WebSockets · @NYTDevs | developers.nytimes.com Play! 2, Akka and WebSockets Having fun with Victor Siu-Leung Chan NE Scala Symposium 2014

@NYTDevs | developers.nytimes.com

Beware of using Future within Actor receive - sender is not there!

What we’ve learned

protected def handleQueryMsg: Receive = { case MSG_QUERY(js) => val f = Future {...} f map { result => sender ! MSG_RESULT(result) } // Dead letters!!!

Page 19: Having fun with Play! 2, Akka and WebSockets · @NYTDevs | developers.nytimes.com Play! 2, Akka and WebSockets Having fun with Victor Siu-Leung Chan NE Scala Symposium 2014

@NYTDevs | developers.nytimes.com

Using Future, instead of actors (execution context)

What we’ve learned

implicit val ec: ExecutionContext = ExecutionContext.fromExecutor(Executors.newCachedThreadPool()) Future { …. /* some expensive work */ } //Running in ec!

Page 20: Having fun with Play! 2, Akka and WebSockets · @NYTDevs | developers.nytimes.com Play! 2, Akka and WebSockets Having fun with Victor Siu-Leung Chan NE Scala Symposium 2014

@NYTDevs | developers.nytimes.com

Thank you!

[email protected]

Question?

http://open.blogs.nytimes.com/