SlideShare a Scribd company logo
1 of 25
Download to read offline
Scaling with Scala: 
Refactoring a Back-end 
Service into the Mobile Age 
Dragos Manolescu (@hysteresis),Whitepages 
dmanolescu at whitepages com
About Whitepages 
• Top web and mobile site for finding phones, people 
and locations 
• 50M unique users per month 
• 35M search queries per day 
• 70 engineers, mostly in Seattle
Background 
• Ruby backend services 
• Shifting to Scala to accommodate growth 
• Technologies: 
• spray.io (client, server) 
• Thrift and Scrooge 
• Coda Hale metrics 
• Typesafe Webinar: http://j.mp/Y6gH05
Worker Backend Service 
AMQ Worker AMQ 
N1 
N3 
N2 
AMQ 
AMQ 
Riak Cluster 
JSON 
JSON 
JSON 
JSON 
Compressed binary Thrift
Sidebar: Scala Async 
Programming Model 
• Future-based 
• Future[T] monad 
• Composition w/ the collection-like API (map, etc.) 
• Actor-based 
• Eliminates locks and thread management 
• Resiliency through supervision (Erlang/OTP)
Future Composition 
def retrieveDataAndMaterialize(req: MaterializationRequest, resolutions: 
ResolutionList, jobStatus: JobStatus): Future[CreateMaterializationResult] = { 
/* snip */ 
! 
val dasFactsF = getContactListFor(dasBucketPrefix) 
val deviceFactsF = getContactListFor(deviceBucketPrefix) 
val fbFactsF = getContactListFor(facebookBucketPrefix) 
val twFactsF = getContactListFor(twitterBucketPrefix) 
val lnFactsF = getContactListFor(linkedinBucketPrefix) 
! 
val materializationResultF = 
for { 
mlHolderOpt <- mlHolderOptF 
rflHolderOpt <- rflHolderOptF 
dasFacts <- dasFactsF 
deviceFacts <- deviceFactsF 
fbFacts <- fbFactsF 
twFacts <- twFactsF 
lnFacts <- lnFactsF 
} yield 
materialize(req, resolutions, jobStatus, mlHolderOpt, rflHolderOpt, 
dasFacts, deviceFacts, fbFacts, twFacts, lnFacts) 
materializationResultF.flatMap(f => f ) 
}
Sidebar: Akka Actor Model 
Actor 
Parent 
Mailbox Behavior 
Child 
Child 
M M M 
Actor 
Mailbox Behavior 
Messages
Messaging to Actors 
private def connectedBehavior(consumer: MessageConsumer): Receive = { 
case PullNextMessage => 
Option(consumer.receiveNoWait()) match { 
case Some(m) => 
monitor ! SignalMaterializationRequestReceived(m.getJMSRedelivered) 
self ! ProcessMessage(m) 
case None if incomingRequests.isEmpty => 
context.system.scheduler.scheduleOnce(wakeupInterval, self, PullNextMessage) 
case None if incomingRequests.size <= prefetch => 
acknowledgeSessionMessages() 
case _ => /* nop */ 
}
Sidebar: Monitoring w/ 
CodaHale metrics and Graphite
Sidebar: ActiveMQ, Camel 
and Akka 
• Apache ActiveMQ: message broker 
• JMS, AMQP, MQTT, … 
• Durable messaging, transactions 
• “The main use case for ActiveMQ is migrating off ActiveMQ” 
• Apache Camel: messaging w/ glue and routing 
• Wide range of endpoints (file, JMS, JDBC, XMPP) 
• Enterprise Integration patterns 
• Akka-Camel: actors w/ Camel endpoints
Sidebar: ActiveMQ, Camel 
and Akka (cont.) 
• Conflicting assumptions? 
• Guaranteed delivery 
• Delivery semantics 
• JMS prefetch and CLIENT_ACKNOWLEDGE 
• Pragmatic architectural decisions (Lucy Berlin, 
When Objects Collide, OOPSLA 1990)
Futures and Actors 
/* inside actor code */ 
def acknowledgeSessionMessages(): Unit = { 
Future.sequence(resultsF) 
.map { results => AcknowledgeSession} 
.recover { case t: Throwable => 
RecoverSession(t)} 
.pipeTo(self) 
} 
! 
override def receive: Receive { 
case AcknowledgeSession => // 
case RecoverSession(t) => // 
// 
}
Supervision:Error Kernel 
AmqClient 
start 
stop 
registerQueueListener 
unregisterQueueListener 
createQueueSender 
deleteQueueSender 
AmqSupervisor 
consumers 
closingConsumers 
senders 
closingSenders 
child [become] 
AmqActor 
Actor 
connection [become] 
ConsumerActor 
session 
processMessage 
Actor 
AmqSender 
ProducerActor 
session 
Actor 
JMS.MessageProducer 
sendTextMessage() 
disconnectConsumers 
disconnectSenders 
Actor 
<<parent-of>> 
<<parent-of>> 
<<parent-of>>
Results
2 Scala instances 
290 Ruby instances
Not so fast (no pun 
intended)
Performance Tuning
Riak Client 
object ConverterBase extends ClassSupport { 
! 
def bytesToRiakObject(key: String, bucket: String, vclock: VClock, bytes: Array[Byte]): IRiakObject = { 
val blob = Snappy.compress(bytes) 
monitor ! BashoValueSize(blob.length, BashoPutOperation) 
RiakObjectBuilder.newBuilder(bucket, key) 
.withValue(blob).withVClock(vclock) 
.withContentType(BashoMobileClient.contentType) 
.withUsermeta(BashoMobileClient.userMeta) 
.build() 
} 
! 
def riakObjectToBytes(riakObject: IRiakObject) = { 
val thriftBytes = Snappy.uncompress(riakObject.getValue) 
Thrift.deserializeThrift(thriftBytes, ThriftCompactProtocol) 
} 
} 
! 
abstract class ConverterBase[T <: ThriftStruct](key: String, bucket: String) extends Converter[StoredObjectHolder[T]] { 
! 
override def fromDomain(valueHolder: StoredObjectHolder[T], vclock: VClock): IRiakObject = 
ConverterBase.bytesToRiakObject(valueHolder.key, bucket, vclock, 
Thrift.serializeThrift(valueHolder.value.get, ThriftCompactProtocol)) 
! 
override def toDomain(riakObject: IRiakObject): StoredObjectHolder[T] = { 
if (riakObject == null) new StoredObjectHolder[T](key) 
else StoredObjectHolder[T](riakObject.getKey, Some(riakObject.getVClock), 
Some(makeNew(ConverterBase.riakObjectToBytes(riakObject)))) 
} 
! 
def makeNew(protocol: TProtocol): T 
}
JVM Serialization
Snappy or LZ4? Micro-benchmarking 
with JMH
Throughput Measurements
Compression Measurements
Summary 
• Shifting from Ruby to Scala 
• Scala async programing model 
• JVM optimizations 
• Results: 
• Increased throughput 
• Better hardware utilization 
• Lower operating cost 
• Seamless integration with Java ecosystem
Thank you! 
(we are hiring)
Resources 
• Typesafe Webinar w/ Whitepages: http://j.mp/Y6gH05 
• JVM Serializer Benchmarks: http://j.mp/1BBYdky 
• YourKit Java profiler: http://j.mp/10mFu17 
• JMH: http://j.mp/1BC5Bwv 
• When Objects Collide: http://j.mp/1vBiPsz 
• Coda Hale metrics: http://j.mp/1vyl9j1

More Related Content

What's hot

SquiDB: a SQLite layer for Android - Jonathan Koren, Yahoo!
SquiDB: a SQLite layer for Android - Jonathan Koren, Yahoo!SquiDB: a SQLite layer for Android - Jonathan Koren, Yahoo!
SquiDB: a SQLite layer for Android - Jonathan Koren, Yahoo!DroidConTLV
 
Why actor-based systems are the best for microservices
Why actor-based systems are the best for microservicesWhy actor-based systems are the best for microservices
Why actor-based systems are the best for microservicesYaroslav Tkachenko
 
Apache Samza 1.0 - What's New, What's Next
Apache Samza 1.0 - What's New, What's NextApache Samza 1.0 - What's New, What's Next
Apache Samza 1.0 - What's New, What's NextPrateek Maheshwari
 
Durable functions 2.0 (2019-10-10)
Durable functions 2.0 (2019-10-10)Durable functions 2.0 (2019-10-10)
Durable functions 2.0 (2019-10-10)Paco de la Cruz
 
Clean Architecture on Android
Clean Architecture on AndroidClean Architecture on Android
Clean Architecture on AndroidTianming Xu
 
PromQL Deep Dive - The Prometheus Query Language
PromQL Deep Dive - The Prometheus Query Language PromQL Deep Dive - The Prometheus Query Language
PromQL Deep Dive - The Prometheus Query Language Weaveworks
 
SynapseIndia dotnet development ajax client library
SynapseIndia dotnet development ajax client librarySynapseIndia dotnet development ajax client library
SynapseIndia dotnet development ajax client librarySynapseindiappsdevelopment
 
Introduction to Spring MVC
Introduction to Spring MVCIntroduction to Spring MVC
Introduction to Spring MVCRichard Paul
 
Esri Dev Summit 2009 Rest and Mvc Final
Esri Dev Summit 2009 Rest and Mvc FinalEsri Dev Summit 2009 Rest and Mvc Final
Esri Dev Summit 2009 Rest and Mvc Finalguestcd4688
 
Build an App with Blindfold - Britt Barak
Build an App with Blindfold - Britt Barak Build an App with Blindfold - Britt Barak
Build an App with Blindfold - Britt Barak DroidConTLV
 
Introduction to RxJS
Introduction to RxJSIntroduction to RxJS
Introduction to RxJSAbul Hasan
 
Engineering Wunderlist for Android - Ceasr Valiente, 6Wunderkinder
Engineering Wunderlist for Android - Ceasr Valiente, 6WunderkinderEngineering Wunderlist for Android - Ceasr Valiente, 6Wunderkinder
Engineering Wunderlist for Android - Ceasr Valiente, 6WunderkinderDroidConTLV
 
Azure Durable Functions (2019-04-27)
Azure Durable Functions (2019-04-27)Azure Durable Functions (2019-04-27)
Azure Durable Functions (2019-04-27)Paco de la Cruz
 
Introduction to React JS for beginners
Introduction to React JS for beginners Introduction to React JS for beginners
Introduction to React JS for beginners Varun Raj
 
8\9 SSIS 2008R2_Training - Debugging_Package
8\9 SSIS 2008R2_Training - Debugging_Package8\9 SSIS 2008R2_Training - Debugging_Package
8\9 SSIS 2008R2_Training - Debugging_PackagePramod Singla
 

What's hot (20)

SquiDB: a SQLite layer for Android - Jonathan Koren, Yahoo!
SquiDB: a SQLite layer for Android - Jonathan Koren, Yahoo!SquiDB: a SQLite layer for Android - Jonathan Koren, Yahoo!
SquiDB: a SQLite layer for Android - Jonathan Koren, Yahoo!
 
Why actor-based systems are the best for microservices
Why actor-based systems are the best for microservicesWhy actor-based systems are the best for microservices
Why actor-based systems are the best for microservices
 
Apache Samza 1.0 - What's New, What's Next
Apache Samza 1.0 - What's New, What's NextApache Samza 1.0 - What's New, What's Next
Apache Samza 1.0 - What's New, What's Next
 
Durable functions 2.0 (2019-10-10)
Durable functions 2.0 (2019-10-10)Durable functions 2.0 (2019-10-10)
Durable functions 2.0 (2019-10-10)
 
Clean Architecture on Android
Clean Architecture on AndroidClean Architecture on Android
Clean Architecture on Android
 
PromQL Deep Dive - The Prometheus Query Language
PromQL Deep Dive - The Prometheus Query Language PromQL Deep Dive - The Prometheus Query Language
PromQL Deep Dive - The Prometheus Query Language
 
SynapseIndia dotnet development ajax client library
SynapseIndia dotnet development ajax client librarySynapseIndia dotnet development ajax client library
SynapseIndia dotnet development ajax client library
 
Introduction to Spring MVC
Introduction to Spring MVCIntroduction to Spring MVC
Introduction to Spring MVC
 
Esri Dev Summit 2009 Rest and Mvc Final
Esri Dev Summit 2009 Rest and Mvc FinalEsri Dev Summit 2009 Rest and Mvc Final
Esri Dev Summit 2009 Rest and Mvc Final
 
Lecture 2
Lecture 2Lecture 2
Lecture 2
 
JavaCro'14 - Building interactive web applications with Vaadin – Peter Lehto
JavaCro'14 - Building interactive web applications with Vaadin – Peter LehtoJavaCro'14 - Building interactive web applications with Vaadin – Peter Lehto
JavaCro'14 - Building interactive web applications with Vaadin – Peter Lehto
 
Gatling
Gatling Gatling
Gatling
 
Build an App with Blindfold - Britt Barak
Build an App with Blindfold - Britt Barak Build an App with Blindfold - Britt Barak
Build an App with Blindfold - Britt Barak
 
Introduction to RxJS
Introduction to RxJSIntroduction to RxJS
Introduction to RxJS
 
Gatling
GatlingGatling
Gatling
 
Engineering Wunderlist for Android - Ceasr Valiente, 6Wunderkinder
Engineering Wunderlist for Android - Ceasr Valiente, 6WunderkinderEngineering Wunderlist for Android - Ceasr Valiente, 6Wunderkinder
Engineering Wunderlist for Android - Ceasr Valiente, 6Wunderkinder
 
Azure Durable Functions (2019-04-27)
Azure Durable Functions (2019-04-27)Azure Durable Functions (2019-04-27)
Azure Durable Functions (2019-04-27)
 
Introduction to React JS for beginners
Introduction to React JS for beginners Introduction to React JS for beginners
Introduction to React JS for beginners
 
Intro to React
Intro to ReactIntro to React
Intro to React
 
8\9 SSIS 2008R2_Training - Debugging_Package
8\9 SSIS 2008R2_Training - Debugging_Package8\9 SSIS 2008R2_Training - Debugging_Package
8\9 SSIS 2008R2_Training - Debugging_Package
 

Similar to Scaling with Scala: refactoring a back-end service into the mobile age

Akka Microservices Architecture And Design
Akka Microservices Architecture And DesignAkka Microservices Architecture And Design
Akka Microservices Architecture And DesignYaroslav Tkachenko
 
Actors or Not: Async Event Architectures
Actors or Not: Async Event ArchitecturesActors or Not: Async Event Architectures
Actors or Not: Async Event ArchitecturesYaroslav Tkachenko
 
Ajax tutorial
Ajax tutorialAjax tutorial
Ajax tutorialKat Roque
 
Hybrid Apps (Native + Web) via QtWebKit
Hybrid Apps (Native + Web) via QtWebKitHybrid Apps (Native + Web) via QtWebKit
Hybrid Apps (Native + Web) via QtWebKitAriya Hidayat
 
Kick your database_to_the_curb_reston_08_27_19
Kick your database_to_the_curb_reston_08_27_19Kick your database_to_the_curb_reston_08_27_19
Kick your database_to_the_curb_reston_08_27_19confluent
 
Comet with node.js and V8
Comet with node.js and V8Comet with node.js and V8
Comet with node.js and V8amix3k
 
GTS Episode 1: Reactive programming in the wild
GTS Episode 1: Reactive programming in the wildGTS Episode 1: Reactive programming in the wild
GTS Episode 1: Reactive programming in the wildOmer Iqbal
 
Unleashing your Kafka Streams Application Metrics!
Unleashing your Kafka Streams Application Metrics!Unleashing your Kafka Streams Application Metrics!
Unleashing your Kafka Streams Application Metrics!HostedbyConfluent
 
Hybrid Apps (Native + Web) using WebKit
Hybrid Apps (Native + Web) using WebKitHybrid Apps (Native + Web) using WebKit
Hybrid Apps (Native + Web) using WebKitAriya Hidayat
 
Hybrid Apps (Native + Web) using WebKit
Hybrid Apps (Native + Web) using WebKitHybrid Apps (Native + Web) using WebKit
Hybrid Apps (Native + Web) using WebKitAriya Hidayat
 
Decompose the monolith into AWS Step Functions
Decompose the monolith into AWS Step FunctionsDecompose the monolith into AWS Step Functions
Decompose the monolith into AWS Step FunctionsbeSharp
 
Building Eventing Systems for Microservice Architecture
Building Eventing Systems for Microservice Architecture  Building Eventing Systems for Microservice Architecture
Building Eventing Systems for Microservice Architecture Yaroslav Tkachenko
 
«ReactiveCocoa и MVVM» — Николай Касьянов, SoftWear
«ReactiveCocoa и MVVM» — Николай Касьянов, SoftWear«ReactiveCocoa и MVVM» — Николай Касьянов, SoftWear
«ReactiveCocoa и MVVM» — Николай Касьянов, SoftWeare-Legion
 
Timeline Service v.2 (Hadoop Summit 2016)
Timeline Service v.2 (Hadoop Summit 2016)Timeline Service v.2 (Hadoop Summit 2016)
Timeline Service v.2 (Hadoop Summit 2016)Sangjin Lee
 
Timeline service V2 at the Hadoop Summit SJ 2016
Timeline service V2 at the Hadoop Summit SJ 2016Timeline service V2 at the Hadoop Summit SJ 2016
Timeline service V2 at the Hadoop Summit SJ 2016Vrushali Channapattan
 
Make your gui shine with ajax solr
Make your gui shine with ajax solrMake your gui shine with ajax solr
Make your gui shine with ajax solrlucenerevolution
 
4Developers 2018: Real-time capabilities in ASP.NET Core web applications (To...
4Developers 2018: Real-time capabilities in ASP.NET Core web applications (To...4Developers 2018: Real-time capabilities in ASP.NET Core web applications (To...
4Developers 2018: Real-time capabilities in ASP.NET Core web applications (To...PROIDEA
 
Building Stateful Microservices With Akka
Building Stateful Microservices With AkkaBuilding Stateful Microservices With Akka
Building Stateful Microservices With AkkaYaroslav Tkachenko
 

Similar to Scaling with Scala: refactoring a back-end service into the mobile age (20)

Akka Microservices Architecture And Design
Akka Microservices Architecture And DesignAkka Microservices Architecture And Design
Akka Microservices Architecture And Design
 
Actors or Not: Async Event Architectures
Actors or Not: Async Event ArchitecturesActors or Not: Async Event Architectures
Actors or Not: Async Event Architectures
 
Reactive cocoa
Reactive cocoaReactive cocoa
Reactive cocoa
 
Ajax tutorial
Ajax tutorialAjax tutorial
Ajax tutorial
 
Hybrid Apps (Native + Web) via QtWebKit
Hybrid Apps (Native + Web) via QtWebKitHybrid Apps (Native + Web) via QtWebKit
Hybrid Apps (Native + Web) via QtWebKit
 
Kick your database_to_the_curb_reston_08_27_19
Kick your database_to_the_curb_reston_08_27_19Kick your database_to_the_curb_reston_08_27_19
Kick your database_to_the_curb_reston_08_27_19
 
Comet with node.js and V8
Comet with node.js and V8Comet with node.js and V8
Comet with node.js and V8
 
GTS Episode 1: Reactive programming in the wild
GTS Episode 1: Reactive programming in the wildGTS Episode 1: Reactive programming in the wild
GTS Episode 1: Reactive programming in the wild
 
Unleashing your Kafka Streams Application Metrics!
Unleashing your Kafka Streams Application Metrics!Unleashing your Kafka Streams Application Metrics!
Unleashing your Kafka Streams Application Metrics!
 
Hybrid Apps (Native + Web) using WebKit
Hybrid Apps (Native + Web) using WebKitHybrid Apps (Native + Web) using WebKit
Hybrid Apps (Native + Web) using WebKit
 
Hybrid Apps (Native + Web) using WebKit
Hybrid Apps (Native + Web) using WebKitHybrid Apps (Native + Web) using WebKit
Hybrid Apps (Native + Web) using WebKit
 
Decompose the monolith into AWS Step Functions
Decompose the monolith into AWS Step FunctionsDecompose the monolith into AWS Step Functions
Decompose the monolith into AWS Step Functions
 
Data Pipeline at Tapad
Data Pipeline at TapadData Pipeline at Tapad
Data Pipeline at Tapad
 
Building Eventing Systems for Microservice Architecture
Building Eventing Systems for Microservice Architecture  Building Eventing Systems for Microservice Architecture
Building Eventing Systems for Microservice Architecture
 
«ReactiveCocoa и MVVM» — Николай Касьянов, SoftWear
«ReactiveCocoa и MVVM» — Николай Касьянов, SoftWear«ReactiveCocoa и MVVM» — Николай Касьянов, SoftWear
«ReactiveCocoa и MVVM» — Николай Касьянов, SoftWear
 
Timeline Service v.2 (Hadoop Summit 2016)
Timeline Service v.2 (Hadoop Summit 2016)Timeline Service v.2 (Hadoop Summit 2016)
Timeline Service v.2 (Hadoop Summit 2016)
 
Timeline service V2 at the Hadoop Summit SJ 2016
Timeline service V2 at the Hadoop Summit SJ 2016Timeline service V2 at the Hadoop Summit SJ 2016
Timeline service V2 at the Hadoop Summit SJ 2016
 
Make your gui shine with ajax solr
Make your gui shine with ajax solrMake your gui shine with ajax solr
Make your gui shine with ajax solr
 
4Developers 2018: Real-time capabilities in ASP.NET Core web applications (To...
4Developers 2018: Real-time capabilities in ASP.NET Core web applications (To...4Developers 2018: Real-time capabilities in ASP.NET Core web applications (To...
4Developers 2018: Real-time capabilities in ASP.NET Core web applications (To...
 
Building Stateful Microservices With Akka
Building Stateful Microservices With AkkaBuilding Stateful Microservices With Akka
Building Stateful Microservices With Akka
 

Recently uploaded

Dev Dives: Streamline document processing with UiPath Studio Web
Dev Dives: Streamline document processing with UiPath Studio WebDev Dives: Streamline document processing with UiPath Studio Web
Dev Dives: Streamline document processing with UiPath Studio WebUiPathCommunity
 
TrustArc Webinar - How to Build Consumer Trust Through Data Privacy
TrustArc Webinar - How to Build Consumer Trust Through Data PrivacyTrustArc Webinar - How to Build Consumer Trust Through Data Privacy
TrustArc Webinar - How to Build Consumer Trust Through Data PrivacyTrustArc
 
TeamStation AI System Report LATAM IT Salaries 2024
TeamStation AI System Report LATAM IT Salaries 2024TeamStation AI System Report LATAM IT Salaries 2024
TeamStation AI System Report LATAM IT Salaries 2024Lonnie McRorey
 
DevoxxFR 2024 Reproducible Builds with Apache Maven
DevoxxFR 2024 Reproducible Builds with Apache MavenDevoxxFR 2024 Reproducible Builds with Apache Maven
DevoxxFR 2024 Reproducible Builds with Apache MavenHervé Boutemy
 
A Deep Dive on Passkeys: FIDO Paris Seminar.pptx
A Deep Dive on Passkeys: FIDO Paris Seminar.pptxA Deep Dive on Passkeys: FIDO Paris Seminar.pptx
A Deep Dive on Passkeys: FIDO Paris Seminar.pptxLoriGlavin3
 
Are Multi-Cloud and Serverless Good or Bad?
Are Multi-Cloud and Serverless Good or Bad?Are Multi-Cloud and Serverless Good or Bad?
Are Multi-Cloud and Serverless Good or Bad?Mattias Andersson
 
Generative AI for Technical Writer or Information Developers
Generative AI for Technical Writer or Information DevelopersGenerative AI for Technical Writer or Information Developers
Generative AI for Technical Writer or Information DevelopersRaghuram Pandurangan
 
New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024BookNet Canada
 
SALESFORCE EDUCATION CLOUD | FEXLE SERVICES
SALESFORCE EDUCATION CLOUD | FEXLE SERVICESSALESFORCE EDUCATION CLOUD | FEXLE SERVICES
SALESFORCE EDUCATION CLOUD | FEXLE SERVICESmohitsingh558521
 
Passkey Providers and Enabling Portability: FIDO Paris Seminar.pptx
Passkey Providers and Enabling Portability: FIDO Paris Seminar.pptxPasskey Providers and Enabling Portability: FIDO Paris Seminar.pptx
Passkey Providers and Enabling Portability: FIDO Paris Seminar.pptxLoriGlavin3
 
unit 4 immunoblotting technique complete.pptx
unit 4 immunoblotting technique complete.pptxunit 4 immunoblotting technique complete.pptx
unit 4 immunoblotting technique complete.pptxBkGupta21
 
From Family Reminiscence to Scholarly Archive .
From Family Reminiscence to Scholarly Archive .From Family Reminiscence to Scholarly Archive .
From Family Reminiscence to Scholarly Archive .Alan Dix
 
SIP trunking in Janus @ Kamailio World 2024
SIP trunking in Janus @ Kamailio World 2024SIP trunking in Janus @ Kamailio World 2024
SIP trunking in Janus @ Kamailio World 2024Lorenzo Miniero
 
New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024BookNet Canada
 
SAP Build Work Zone - Overview L2-L3.pptx
SAP Build Work Zone - Overview L2-L3.pptxSAP Build Work Zone - Overview L2-L3.pptx
SAP Build Work Zone - Overview L2-L3.pptxNavinnSomaal
 
Connect Wave/ connectwave Pitch Deck Presentation
Connect Wave/ connectwave Pitch Deck PresentationConnect Wave/ connectwave Pitch Deck Presentation
Connect Wave/ connectwave Pitch Deck PresentationSlibray Presentation
 
What's New in Teams Calling, Meetings and Devices March 2024
What's New in Teams Calling, Meetings and Devices March 2024What's New in Teams Calling, Meetings and Devices March 2024
What's New in Teams Calling, Meetings and Devices March 2024Stephanie Beckett
 
Commit 2024 - Secret Management made easy
Commit 2024 - Secret Management made easyCommit 2024 - Secret Management made easy
Commit 2024 - Secret Management made easyAlfredo García Lavilla
 
"ML in Production",Oleksandr Bagan
"ML in Production",Oleksandr Bagan"ML in Production",Oleksandr Bagan
"ML in Production",Oleksandr BaganFwdays
 

Recently uploaded (20)

DMCC Future of Trade Web3 - Special Edition
DMCC Future of Trade Web3 - Special EditionDMCC Future of Trade Web3 - Special Edition
DMCC Future of Trade Web3 - Special Edition
 
Dev Dives: Streamline document processing with UiPath Studio Web
Dev Dives: Streamline document processing with UiPath Studio WebDev Dives: Streamline document processing with UiPath Studio Web
Dev Dives: Streamline document processing with UiPath Studio Web
 
TrustArc Webinar - How to Build Consumer Trust Through Data Privacy
TrustArc Webinar - How to Build Consumer Trust Through Data PrivacyTrustArc Webinar - How to Build Consumer Trust Through Data Privacy
TrustArc Webinar - How to Build Consumer Trust Through Data Privacy
 
TeamStation AI System Report LATAM IT Salaries 2024
TeamStation AI System Report LATAM IT Salaries 2024TeamStation AI System Report LATAM IT Salaries 2024
TeamStation AI System Report LATAM IT Salaries 2024
 
DevoxxFR 2024 Reproducible Builds with Apache Maven
DevoxxFR 2024 Reproducible Builds with Apache MavenDevoxxFR 2024 Reproducible Builds with Apache Maven
DevoxxFR 2024 Reproducible Builds with Apache Maven
 
A Deep Dive on Passkeys: FIDO Paris Seminar.pptx
A Deep Dive on Passkeys: FIDO Paris Seminar.pptxA Deep Dive on Passkeys: FIDO Paris Seminar.pptx
A Deep Dive on Passkeys: FIDO Paris Seminar.pptx
 
Are Multi-Cloud and Serverless Good or Bad?
Are Multi-Cloud and Serverless Good or Bad?Are Multi-Cloud and Serverless Good or Bad?
Are Multi-Cloud and Serverless Good or Bad?
 
Generative AI for Technical Writer or Information Developers
Generative AI for Technical Writer or Information DevelopersGenerative AI for Technical Writer or Information Developers
Generative AI for Technical Writer or Information Developers
 
New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
 
SALESFORCE EDUCATION CLOUD | FEXLE SERVICES
SALESFORCE EDUCATION CLOUD | FEXLE SERVICESSALESFORCE EDUCATION CLOUD | FEXLE SERVICES
SALESFORCE EDUCATION CLOUD | FEXLE SERVICES
 
Passkey Providers and Enabling Portability: FIDO Paris Seminar.pptx
Passkey Providers and Enabling Portability: FIDO Paris Seminar.pptxPasskey Providers and Enabling Portability: FIDO Paris Seminar.pptx
Passkey Providers and Enabling Portability: FIDO Paris Seminar.pptx
 
unit 4 immunoblotting technique complete.pptx
unit 4 immunoblotting technique complete.pptxunit 4 immunoblotting technique complete.pptx
unit 4 immunoblotting technique complete.pptx
 
From Family Reminiscence to Scholarly Archive .
From Family Reminiscence to Scholarly Archive .From Family Reminiscence to Scholarly Archive .
From Family Reminiscence to Scholarly Archive .
 
SIP trunking in Janus @ Kamailio World 2024
SIP trunking in Janus @ Kamailio World 2024SIP trunking in Janus @ Kamailio World 2024
SIP trunking in Janus @ Kamailio World 2024
 
New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
 
SAP Build Work Zone - Overview L2-L3.pptx
SAP Build Work Zone - Overview L2-L3.pptxSAP Build Work Zone - Overview L2-L3.pptx
SAP Build Work Zone - Overview L2-L3.pptx
 
Connect Wave/ connectwave Pitch Deck Presentation
Connect Wave/ connectwave Pitch Deck PresentationConnect Wave/ connectwave Pitch Deck Presentation
Connect Wave/ connectwave Pitch Deck Presentation
 
What's New in Teams Calling, Meetings and Devices March 2024
What's New in Teams Calling, Meetings and Devices March 2024What's New in Teams Calling, Meetings and Devices March 2024
What's New in Teams Calling, Meetings and Devices March 2024
 
Commit 2024 - Secret Management made easy
Commit 2024 - Secret Management made easyCommit 2024 - Secret Management made easy
Commit 2024 - Secret Management made easy
 
"ML in Production",Oleksandr Bagan
"ML in Production",Oleksandr Bagan"ML in Production",Oleksandr Bagan
"ML in Production",Oleksandr Bagan
 

Scaling with Scala: refactoring a back-end service into the mobile age

  • 1. Scaling with Scala: Refactoring a Back-end Service into the Mobile Age Dragos Manolescu (@hysteresis),Whitepages dmanolescu at whitepages com
  • 2. About Whitepages • Top web and mobile site for finding phones, people and locations • 50M unique users per month • 35M search queries per day • 70 engineers, mostly in Seattle
  • 3. Background • Ruby backend services • Shifting to Scala to accommodate growth • Technologies: • spray.io (client, server) • Thrift and Scrooge • Coda Hale metrics • Typesafe Webinar: http://j.mp/Y6gH05
  • 4. Worker Backend Service AMQ Worker AMQ N1 N3 N2 AMQ AMQ Riak Cluster JSON JSON JSON JSON Compressed binary Thrift
  • 5. Sidebar: Scala Async Programming Model • Future-based • Future[T] monad • Composition w/ the collection-like API (map, etc.) • Actor-based • Eliminates locks and thread management • Resiliency through supervision (Erlang/OTP)
  • 6. Future Composition def retrieveDataAndMaterialize(req: MaterializationRequest, resolutions: ResolutionList, jobStatus: JobStatus): Future[CreateMaterializationResult] = { /* snip */ ! val dasFactsF = getContactListFor(dasBucketPrefix) val deviceFactsF = getContactListFor(deviceBucketPrefix) val fbFactsF = getContactListFor(facebookBucketPrefix) val twFactsF = getContactListFor(twitterBucketPrefix) val lnFactsF = getContactListFor(linkedinBucketPrefix) ! val materializationResultF = for { mlHolderOpt <- mlHolderOptF rflHolderOpt <- rflHolderOptF dasFacts <- dasFactsF deviceFacts <- deviceFactsF fbFacts <- fbFactsF twFacts <- twFactsF lnFacts <- lnFactsF } yield materialize(req, resolutions, jobStatus, mlHolderOpt, rflHolderOpt, dasFacts, deviceFacts, fbFacts, twFacts, lnFacts) materializationResultF.flatMap(f => f ) }
  • 7. Sidebar: Akka Actor Model Actor Parent Mailbox Behavior Child Child M M M Actor Mailbox Behavior Messages
  • 8. Messaging to Actors private def connectedBehavior(consumer: MessageConsumer): Receive = { case PullNextMessage => Option(consumer.receiveNoWait()) match { case Some(m) => monitor ! SignalMaterializationRequestReceived(m.getJMSRedelivered) self ! ProcessMessage(m) case None if incomingRequests.isEmpty => context.system.scheduler.scheduleOnce(wakeupInterval, self, PullNextMessage) case None if incomingRequests.size <= prefetch => acknowledgeSessionMessages() case _ => /* nop */ }
  • 9. Sidebar: Monitoring w/ CodaHale metrics and Graphite
  • 10. Sidebar: ActiveMQ, Camel and Akka • Apache ActiveMQ: message broker • JMS, AMQP, MQTT, … • Durable messaging, transactions • “The main use case for ActiveMQ is migrating off ActiveMQ” • Apache Camel: messaging w/ glue and routing • Wide range of endpoints (file, JMS, JDBC, XMPP) • Enterprise Integration patterns • Akka-Camel: actors w/ Camel endpoints
  • 11. Sidebar: ActiveMQ, Camel and Akka (cont.) • Conflicting assumptions? • Guaranteed delivery • Delivery semantics • JMS prefetch and CLIENT_ACKNOWLEDGE • Pragmatic architectural decisions (Lucy Berlin, When Objects Collide, OOPSLA 1990)
  • 12. Futures and Actors /* inside actor code */ def acknowledgeSessionMessages(): Unit = { Future.sequence(resultsF) .map { results => AcknowledgeSession} .recover { case t: Throwable => RecoverSession(t)} .pipeTo(self) } ! override def receive: Receive { case AcknowledgeSession => // case RecoverSession(t) => // // }
  • 13. Supervision:Error Kernel AmqClient start stop registerQueueListener unregisterQueueListener createQueueSender deleteQueueSender AmqSupervisor consumers closingConsumers senders closingSenders child [become] AmqActor Actor connection [become] ConsumerActor session processMessage Actor AmqSender ProducerActor session Actor JMS.MessageProducer sendTextMessage() disconnectConsumers disconnectSenders Actor <<parent-of>> <<parent-of>> <<parent-of>>
  • 15. 2 Scala instances 290 Ruby instances
  • 16. Not so fast (no pun intended)
  • 18. Riak Client object ConverterBase extends ClassSupport { ! def bytesToRiakObject(key: String, bucket: String, vclock: VClock, bytes: Array[Byte]): IRiakObject = { val blob = Snappy.compress(bytes) monitor ! BashoValueSize(blob.length, BashoPutOperation) RiakObjectBuilder.newBuilder(bucket, key) .withValue(blob).withVClock(vclock) .withContentType(BashoMobileClient.contentType) .withUsermeta(BashoMobileClient.userMeta) .build() } ! def riakObjectToBytes(riakObject: IRiakObject) = { val thriftBytes = Snappy.uncompress(riakObject.getValue) Thrift.deserializeThrift(thriftBytes, ThriftCompactProtocol) } } ! abstract class ConverterBase[T <: ThriftStruct](key: String, bucket: String) extends Converter[StoredObjectHolder[T]] { ! override def fromDomain(valueHolder: StoredObjectHolder[T], vclock: VClock): IRiakObject = ConverterBase.bytesToRiakObject(valueHolder.key, bucket, vclock, Thrift.serializeThrift(valueHolder.value.get, ThriftCompactProtocol)) ! override def toDomain(riakObject: IRiakObject): StoredObjectHolder[T] = { if (riakObject == null) new StoredObjectHolder[T](key) else StoredObjectHolder[T](riakObject.getKey, Some(riakObject.getVClock), Some(makeNew(ConverterBase.riakObjectToBytes(riakObject)))) } ! def makeNew(protocol: TProtocol): T }
  • 20. Snappy or LZ4? Micro-benchmarking with JMH
  • 23. Summary • Shifting from Ruby to Scala • Scala async programing model • JVM optimizations • Results: • Increased throughput • Better hardware utilization • Lower operating cost • Seamless integration with Java ecosystem
  • 24. Thank you! (we are hiring)
  • 25. Resources • Typesafe Webinar w/ Whitepages: http://j.mp/Y6gH05 • JVM Serializer Benchmarks: http://j.mp/1BBYdky • YourKit Java profiler: http://j.mp/10mFu17 • JMH: http://j.mp/1BC5Bwv • When Objects Collide: http://j.mp/1vBiPsz • Coda Hale metrics: http://j.mp/1vyl9j1