SlideShare a Scribd company logo
SCALA
@
SMARTNEWS
High Performance Ad Server with Finagle	

@taketon_
Who?
• @taketon_
• Ph.D in Psychology(Vision)
• TypeSafe and Beer Lover
SmartNews
• Mobile News App, which uses machine learning algorithms

to discover and aggregate news
• 10 million DL globally
Chikyukun
Ad
• Started Ad delivery(only in Japan) from 2014/Dec
• Policy: Ads as Content
Team members
Ad Server
• Implemented within about 2 months
Scala(finagle)@SmartNews_English
Finagle
• OSS RPC Framework by Twitter, Inc.
• Using Future like Akka
• Wrapper of Netty
• "Server as a function"
Finagle
• We use Finagle for Movie Ad Server
• avg. 20ms latency / Max 2000qps
Pros
• easy to build server
• High Performance (backed by Netty)
• Async Handling by Future type
• shared model by thrift IDL
• provides metrics via twitter-server and Tracer
Cons
• slightly slow to update (e.g. upgrade to Scala 2.11)
• (waiting for finagle-redis update)
• Different Behavior between twitter.util.Future and
scala.concurrent.Future (pop-quiz)
• limited documentation
• not a good fit with NewRelic (instead, use Tracer)
How to implement

Ad Server
Handling Async
• Type as a document
• Future indicates IO call
• Procedures in AdServer
• Request -> JSON parse -> Data load ->
Campaign Filtering -> Response
Server as a function
• Server : Request => Response
!
class Service[-Req, +Rep] extends (Req => Future[Rep])
Ad Service
• Launches ListeningServer(backed by Netty)
on `:port`
!
class AdService extends Service[Request, Response] {
override def apply(request: Request): Future[Response] = {
// hogehoge
}
}
val server = Http.serve(":port", new AdService())
Await.result(server)
* caution: This code needs transformation of Request to HttpRequest

(also Response)
JSON Parse
• Jackson Streaming API
• AdRequest is defined in .thrift file
!
trait JsonParser {
def read(request: Request):Option[AdRequest]
}
Data Load
• Future type indicates the function causes
heavy IO task
!
trait ContextLoader {
def load(): Future[CampaignContext]
}
Data Load
• Campaign Master Info is stored in MySQL,
and be cached on JVM memories.
• Use AtomicReference to ConcurrentHashMap
as cache
!
trait ContextLoader {
def load(): Future[CampaignContext]
}
Campaign Filtering
• Filtering campaigns based on Context and
Request
!
trait CampaignFilter {
def filter(
request: AdRequest,
ctx: CampaignContext
): Option[AdResponse]
}
Future Chain
• add callback to the function with flatMap
• callback will receive the result of former
Future function, then returns new Future
!
def flatMap[B](f: A => Future[B]): Future[B]
Future Chain (flatMap)
!
def apply(request: Request): Future[Response] = {
val adReqOpt: Option[AdRequest] = JSONParser.read(request)
val fAdResOpt: Future[Option[AdResponse]] = adReqOpt.map { adReq =>
val fCtx: Future[CampaignContext] = ContextLoader.load()
fCtx.map { ctx =>
CampaignFilter.filter(adReq, ctx)
}
}.getOrElse {
Future.value(None)
}
!
Future Chain (flatMap)
!
fAdResOpt.flatMap { adResOpt =>
adResOpt.map { adRes =>
val fSessionKeyOpt = RedisService.getKey()
fSessionKeyOpt.flatMap { sessionKeyOpt =>
sessionKeyOpt.map { sessionKey =>
Future.value(mkResponse(adRes, sessionKey))
}.getOrElse {
Future.value(Response(NO_CONTENT))
}
}
}.getOrElse {
Future.value(Response(NO_CONTENT))
}
}
}
Future Chain (optionT)
• optionT[A]: Future[Option[A]] => OptionT[Future, A]
• need to make Future as instance of Monad (gist)
!
def apply(request: Request): Future[Response] = {
(for {
adReq <- optionT(JSONParser.read(request).point[Future])
ctx <- LocalCache.load().liftM[OptionT]
adRes <- optionT(CampaignFilter.filter(adReq, ctx).point[Future])
sessionKey <- optionT(RedisService.getKey())
} yield mkResponse(adRes, sessionKey)).run.map {
_.getOrElse(Response(NO_CONTENT))
}
}
!
Filter
• Set filter for application-agnostic behavior, like
timeout
class HttpTimeoutFilter (
val timeOutMs: Int
) extends TimeoutFilter[Request, Response](
timeOutMs.milliseconds,
new GlobalRequestTimeoutException(timeOutMs.milliseconds),
DefaultTimer.twitter){
}
!
Http.serve(":port", new HttpTimeoutFilter(100) andThen AdService)
!
Routing
val muxer = new HttpMuxer()
.withHandler("/ad", new AdService())
!
val server = Http.server(":port", muxer)
Await.result(server)
Tips for Performance
• Basically the server will not be CPU-bound
• Wrap IO-bound process by Future
Tips for Performance
• The cost for creating instances for Future or
Option can be ignored
• For constructing List, use mutable data structure
(e.g. ArrayBuffer) and finally call toList
• For transforming List, use Iterator and finally call
toList
• Practice for Performance tuning in Scala (Japanese)
Summary
• Finagle will be a good fit for Ad Server
• We used mutable for data construction
• However, no need for sensitive for tuning
• (́-`).。oO(Hope Finagle will become more popular)

More Related Content

PPTX
Distributed Kafka Architecture Taboola Scale
Apache Kafka TLV
 
PPTX
Ceilo componentization diagrams
Fabio Giannetti
 
PDF
Uber Business Metrics Generation and Management Through Apache Flink
Wenrui Meng
 
PDF
Ceilometer presentation ods havana final - published
eNovance
 
PDF
Simplifying Event Streaming: Tools for Location Transparency and Data Evoluti...
confluent
 
PPTX
Serverless GraphQL. AppSync 101
Marcin Sodkiewicz
 
PPTX
goto; London: Keeping your Cloud Footprint in Check
Coburn Watson
 
PDF
A unified analytics platform with Kafka and Flink | Stephan Ewen, Ververica
HostedbyConfluent
 
Distributed Kafka Architecture Taboola Scale
Apache Kafka TLV
 
Ceilo componentization diagrams
Fabio Giannetti
 
Uber Business Metrics Generation and Management Through Apache Flink
Wenrui Meng
 
Ceilometer presentation ods havana final - published
eNovance
 
Simplifying Event Streaming: Tools for Location Transparency and Data Evoluti...
confluent
 
Serverless GraphQL. AppSync 101
Marcin Sodkiewicz
 
goto; London: Keeping your Cloud Footprint in Check
Coburn Watson
 
A unified analytics platform with Kafka and Flink | Stephan Ewen, Ververica
HostedbyConfluent
 

What's hot (19)

PDF
I/O intensiveなKafka ConsumerアプリケーションのスループットをLINE Ads Platformではどのように改善したか
LINE Corporation
 
PPTX
Managing Your Cloud Spend With PlanForCloud - RightScale Compute 2013
RightScale
 
PDF
Data / Streaming / Microservices Platform with Devops
Kidong Lee
 
PDF
Santa Cloud: How Netflix Does Holiday Capacity Planning - South Bay SRE Meetu...
Coburn Watson
 
PPTX
Windows Azure Zero Downtime Upgrade
Pavel Revenkov
 
PDF
Kafka and Stream Processing, Taking Analytics Real-time, Mike Spicer
confluent
 
PDF
Kafka Case by getting data from SAP
Techrom Tecnologia
 
PPTX
Autoscale without netscaler_ccceu13
Nguyen Anh Tu
 
PPTX
Serverless Reality
Lynn Langit
 
PDF
Administrative techniques to reduce Kafka costs | Anna Kepler, Viasat
HostedbyConfluent
 
PDF
Comparing Cloud VM Types and Prices: AWS vs Azure vs Google vs IBM
RightScale
 
PPTX
Scaling Galaxy on Google Cloud Platform
Lynn Langit
 
PPTX
Shift Remote: WEB - GraphQL and React – Quick Start - Dubravko Bogovic (Infobip)
Shift Conference
 
PDF
Visualizing AutoTrader Traffic in Near Real-Time with Spark Streaming-(Jon Gr...
Spark Summit
 
PPTX
Михаил Максимов ( Software engineer, DataArt. AWS certified Solution Architect)
DataArt
 
PDF
GraphQL API on a Serverless Environment
Itai Yaffe
 
PPTX
Grafana optimization for Prometheus
Mitsuhiro Tanda
 
PDF
9 Ways to Reduce Cloud Storage Costs
RightScale
 
PDF
Hands on Compute Engine
Simon Su
 
I/O intensiveなKafka ConsumerアプリケーションのスループットをLINE Ads Platformではどのように改善したか
LINE Corporation
 
Managing Your Cloud Spend With PlanForCloud - RightScale Compute 2013
RightScale
 
Data / Streaming / Microservices Platform with Devops
Kidong Lee
 
Santa Cloud: How Netflix Does Holiday Capacity Planning - South Bay SRE Meetu...
Coburn Watson
 
Windows Azure Zero Downtime Upgrade
Pavel Revenkov
 
Kafka and Stream Processing, Taking Analytics Real-time, Mike Spicer
confluent
 
Kafka Case by getting data from SAP
Techrom Tecnologia
 
Autoscale without netscaler_ccceu13
Nguyen Anh Tu
 
Serverless Reality
Lynn Langit
 
Administrative techniques to reduce Kafka costs | Anna Kepler, Viasat
HostedbyConfluent
 
Comparing Cloud VM Types and Prices: AWS vs Azure vs Google vs IBM
RightScale
 
Scaling Galaxy on Google Cloud Platform
Lynn Langit
 
Shift Remote: WEB - GraphQL and React – Quick Start - Dubravko Bogovic (Infobip)
Shift Conference
 
Visualizing AutoTrader Traffic in Near Real-Time with Spark Streaming-(Jon Gr...
Spark Summit
 
Михаил Максимов ( Software engineer, DataArt. AWS certified Solution Architect)
DataArt
 
GraphQL API on a Serverless Environment
Itai Yaffe
 
Grafana optimization for Prometheus
Mitsuhiro Tanda
 
9 Ways to Reduce Cloud Storage Costs
RightScale
 
Hands on Compute Engine
Simon Su
 
Ad

Similar to Scala(finagle)@SmartNews_English (20)

PDF
KFServing and Feast
Animesh Singh
 
PPTX
Event-Based API Patterns and Practices
LaunchAny
 
PDF
Actors or Not: Async Event Architectures
Yaroslav Tkachenko
 
PDF
An approach to responsive, realtime with Backbone.js and WebSockets
Andrei Sebastian Cîmpean
 
PDF
Timeline service V2 at the Hadoop Summit SJ 2016
Vrushali Channapattan
 
PDF
Timeline Service v.2 (Hadoop Summit 2016)
Sangjin Lee
 
PPT
Ajax
rahmed_sct
 
PPTX
Angular or React
Orkhan Gasimov
 
PPTX
Kafka streams decoupling with stores
Yoni Farin
 
PPT
Web Programming using Asynchronous JavaX
SivanN6
 
PDF
Building Scalable Stateless Applications with RxJava
Rick Warren
 
PDF
Deep learning and streaming in Apache Spark 2.2 by Matei Zaharia
GoDataDriven
 
PPT
Ajax
Manav Prasad
 
PPTX
Data Pipeline at Tapad
Toby Matejovsky
 
PDF
Predictable reactive state management - ngrx
Ilia Idakiev
 
PDF
M2M Protocol Interoperability using IoT Toolkit
Michael Koster
 
PDF
M2M Protocol Interoperability using IoT Toolkit
Michael Koster
 
PDF
Object models for interoperability
Michael Koster
 
ODP
Developing Microservices using Spring - Beginner's Guide
Mohanraj Thirumoorthy
 
PPTX
Integration Monday - BizTalk Migrator Deep Dive
BizTalk360
 
KFServing and Feast
Animesh Singh
 
Event-Based API Patterns and Practices
LaunchAny
 
Actors or Not: Async Event Architectures
Yaroslav Tkachenko
 
An approach to responsive, realtime with Backbone.js and WebSockets
Andrei Sebastian Cîmpean
 
Timeline service V2 at the Hadoop Summit SJ 2016
Vrushali Channapattan
 
Timeline Service v.2 (Hadoop Summit 2016)
Sangjin Lee
 
Angular or React
Orkhan Gasimov
 
Kafka streams decoupling with stores
Yoni Farin
 
Web Programming using Asynchronous JavaX
SivanN6
 
Building Scalable Stateless Applications with RxJava
Rick Warren
 
Deep learning and streaming in Apache Spark 2.2 by Matei Zaharia
GoDataDriven
 
Data Pipeline at Tapad
Toby Matejovsky
 
Predictable reactive state management - ngrx
Ilia Idakiev
 
M2M Protocol Interoperability using IoT Toolkit
Michael Koster
 
M2M Protocol Interoperability using IoT Toolkit
Michael Koster
 
Object models for interoperability
Michael Koster
 
Developing Microservices using Spring - Beginner's Guide
Mohanraj Thirumoorthy
 
Integration Monday - BizTalk Migrator Deep Dive
BizTalk360
 
Ad

More from Shigekazu Takei (7)

PDF
Scala@SmartNews_20150221
Shigekazu Takei
 
PDF
Startprintf_2013May18
Shigekazu Takei
 
PDF
Pfds 9 2_2
Shigekazu Takei
 
PDF
Pfds 5 2+6_4_2
Shigekazu Takei
 
PDF
Ids ips
Shigekazu Takei
 
PDF
Stanford ml neuralnetwork
Shigekazu Takei
 
PDF
Pfds ex3 9
Shigekazu Takei
 
Scala@SmartNews_20150221
Shigekazu Takei
 
Startprintf_2013May18
Shigekazu Takei
 
Pfds 9 2_2
Shigekazu Takei
 
Pfds 5 2+6_4_2
Shigekazu Takei
 
Stanford ml neuralnetwork
Shigekazu Takei
 
Pfds ex3 9
Shigekazu Takei
 

Recently uploaded (20)

PPTX
Dev Dives: Automate, test, and deploy in one place—with Unified Developer Exp...
AndreeaTom
 
PDF
Structs to JSON: How Go Powers REST APIs
Emily Achieng
 
PDF
Data_Analytics_vs_Data_Science_vs_BI_by_CA_Suvidha_Chaplot.pdf
CA Suvidha Chaplot
 
PDF
Accelerating Oracle Database 23ai Troubleshooting with Oracle AHF Fleet Insig...
Sandesh Rao
 
PDF
Google I/O Extended 2025 Baku - all ppts
HusseinMalikMammadli
 
PPTX
AI in Daily Life: How Artificial Intelligence Helps Us Every Day
vanshrpatil7
 
PDF
Tea4chat - another LLM Project by Kerem Atam
a0m0rajab1
 
PDF
Software Development Methodologies in 2025
KodekX
 
PDF
Security features in Dell, HP, and Lenovo PC systems: A research-based compar...
Principled Technologies
 
PDF
Unlocking the Future- AI Agents Meet Oracle Database 23ai - AIOUG Yatra 2025.pdf
Sandesh Rao
 
PDF
REPORT: Heating appliances market in Poland 2024
SPIUG
 
PDF
Responsible AI and AI Ethics - By Sylvester Ebhonu
Sylvester Ebhonu
 
PDF
Brief History of Internet - Early Days of Internet
sutharharshit158
 
PPTX
IT Runs Better with ThousandEyes AI-driven Assurance
ThousandEyes
 
PPTX
OA presentation.pptx OA presentation.pptx
pateldhruv002338
 
PDF
A Strategic Analysis of the MVNO Wave in Emerging Markets.pdf
IPLOOK Networks
 
PDF
Presentation about Hardware and Software in Computer
snehamodhawadiya
 
PDF
Orbitly Pitch Deck|A Mission-Driven Platform for Side Project Collaboration (...
zz41354899
 
PDF
A Day in the Life of Location Data - Turning Where into How.pdf
Precisely
 
PDF
Cloud-Migration-Best-Practices-A-Practical-Guide-to-AWS-Azure-and-Google-Clou...
Artjoker Software Development Company
 
Dev Dives: Automate, test, and deploy in one place—with Unified Developer Exp...
AndreeaTom
 
Structs to JSON: How Go Powers REST APIs
Emily Achieng
 
Data_Analytics_vs_Data_Science_vs_BI_by_CA_Suvidha_Chaplot.pdf
CA Suvidha Chaplot
 
Accelerating Oracle Database 23ai Troubleshooting with Oracle AHF Fleet Insig...
Sandesh Rao
 
Google I/O Extended 2025 Baku - all ppts
HusseinMalikMammadli
 
AI in Daily Life: How Artificial Intelligence Helps Us Every Day
vanshrpatil7
 
Tea4chat - another LLM Project by Kerem Atam
a0m0rajab1
 
Software Development Methodologies in 2025
KodekX
 
Security features in Dell, HP, and Lenovo PC systems: A research-based compar...
Principled Technologies
 
Unlocking the Future- AI Agents Meet Oracle Database 23ai - AIOUG Yatra 2025.pdf
Sandesh Rao
 
REPORT: Heating appliances market in Poland 2024
SPIUG
 
Responsible AI and AI Ethics - By Sylvester Ebhonu
Sylvester Ebhonu
 
Brief History of Internet - Early Days of Internet
sutharharshit158
 
IT Runs Better with ThousandEyes AI-driven Assurance
ThousandEyes
 
OA presentation.pptx OA presentation.pptx
pateldhruv002338
 
A Strategic Analysis of the MVNO Wave in Emerging Markets.pdf
IPLOOK Networks
 
Presentation about Hardware and Software in Computer
snehamodhawadiya
 
Orbitly Pitch Deck|A Mission-Driven Platform for Side Project Collaboration (...
zz41354899
 
A Day in the Life of Location Data - Turning Where into How.pdf
Precisely
 
Cloud-Migration-Best-Practices-A-Practical-Guide-to-AWS-Azure-and-Google-Clou...
Artjoker Software Development Company
 

Scala(finagle)@SmartNews_English

  • 1. SCALA @ SMARTNEWS High Performance Ad Server with Finagle @taketon_
  • 2. Who? • @taketon_ • Ph.D in Psychology(Vision) • TypeSafe and Beer Lover
  • 3. SmartNews • Mobile News App, which uses machine learning algorithms
 to discover and aggregate news • 10 million DL globally
  • 5. Ad • Started Ad delivery(only in Japan) from 2014/Dec • Policy: Ads as Content
  • 7. Ad Server • Implemented within about 2 months
  • 9. Finagle • OSS RPC Framework by Twitter, Inc. • Using Future like Akka • Wrapper of Netty • "Server as a function"
  • 10. Finagle • We use Finagle for Movie Ad Server • avg. 20ms latency / Max 2000qps
  • 11. Pros • easy to build server • High Performance (backed by Netty) • Async Handling by Future type • shared model by thrift IDL • provides metrics via twitter-server and Tracer
  • 12. Cons • slightly slow to update (e.g. upgrade to Scala 2.11) • (waiting for finagle-redis update) • Different Behavior between twitter.util.Future and scala.concurrent.Future (pop-quiz) • limited documentation • not a good fit with NewRelic (instead, use Tracer)
  • 14. Handling Async • Type as a document • Future indicates IO call • Procedures in AdServer • Request -> JSON parse -> Data load -> Campaign Filtering -> Response
  • 15. Server as a function • Server : Request => Response ! class Service[-Req, +Rep] extends (Req => Future[Rep])
  • 16. Ad Service • Launches ListeningServer(backed by Netty) on `:port` ! class AdService extends Service[Request, Response] { override def apply(request: Request): Future[Response] = { // hogehoge } } val server = Http.serve(":port", new AdService()) Await.result(server) * caution: This code needs transformation of Request to HttpRequest
 (also Response)
  • 17. JSON Parse • Jackson Streaming API • AdRequest is defined in .thrift file ! trait JsonParser { def read(request: Request):Option[AdRequest] }
  • 18. Data Load • Future type indicates the function causes heavy IO task ! trait ContextLoader { def load(): Future[CampaignContext] }
  • 19. Data Load • Campaign Master Info is stored in MySQL, and be cached on JVM memories. • Use AtomicReference to ConcurrentHashMap as cache ! trait ContextLoader { def load(): Future[CampaignContext] }
  • 20. Campaign Filtering • Filtering campaigns based on Context and Request ! trait CampaignFilter { def filter( request: AdRequest, ctx: CampaignContext ): Option[AdResponse] }
  • 21. Future Chain • add callback to the function with flatMap • callback will receive the result of former Future function, then returns new Future ! def flatMap[B](f: A => Future[B]): Future[B]
  • 22. Future Chain (flatMap) ! def apply(request: Request): Future[Response] = { val adReqOpt: Option[AdRequest] = JSONParser.read(request) val fAdResOpt: Future[Option[AdResponse]] = adReqOpt.map { adReq => val fCtx: Future[CampaignContext] = ContextLoader.load() fCtx.map { ctx => CampaignFilter.filter(adReq, ctx) } }.getOrElse { Future.value(None) } !
  • 23. Future Chain (flatMap) ! fAdResOpt.flatMap { adResOpt => adResOpt.map { adRes => val fSessionKeyOpt = RedisService.getKey() fSessionKeyOpt.flatMap { sessionKeyOpt => sessionKeyOpt.map { sessionKey => Future.value(mkResponse(adRes, sessionKey)) }.getOrElse { Future.value(Response(NO_CONTENT)) } } }.getOrElse { Future.value(Response(NO_CONTENT)) } } }
  • 24. Future Chain (optionT) • optionT[A]: Future[Option[A]] => OptionT[Future, A] • need to make Future as instance of Monad (gist) ! def apply(request: Request): Future[Response] = { (for { adReq <- optionT(JSONParser.read(request).point[Future]) ctx <- LocalCache.load().liftM[OptionT] adRes <- optionT(CampaignFilter.filter(adReq, ctx).point[Future]) sessionKey <- optionT(RedisService.getKey()) } yield mkResponse(adRes, sessionKey)).run.map { _.getOrElse(Response(NO_CONTENT)) } } !
  • 25. Filter • Set filter for application-agnostic behavior, like timeout class HttpTimeoutFilter ( val timeOutMs: Int ) extends TimeoutFilter[Request, Response]( timeOutMs.milliseconds, new GlobalRequestTimeoutException(timeOutMs.milliseconds), DefaultTimer.twitter){ } ! Http.serve(":port", new HttpTimeoutFilter(100) andThen AdService) !
  • 26. Routing val muxer = new HttpMuxer() .withHandler("/ad", new AdService()) ! val server = Http.server(":port", muxer) Await.result(server)
  • 27. Tips for Performance • Basically the server will not be CPU-bound • Wrap IO-bound process by Future
  • 28. Tips for Performance • The cost for creating instances for Future or Option can be ignored • For constructing List, use mutable data structure (e.g. ArrayBuffer) and finally call toList • For transforming List, use Iterator and finally call toList • Practice for Performance tuning in Scala (Japanese)
  • 29. Summary • Finagle will be a good fit for Ad Server • We used mutable for data construction • However, no need for sensitive for tuning • (́-`).。oO(Hope Finagle will become more popular)