SlideShare a Scribd company logo
1 of 95
Download to read offline
@flaviowbrasil 
Aficionado por open 
source 
Expert em 
escalabilidade 
Mestre Jedi Scala 
Prefere uma sessão de 
profiling a uma tarde 
na praia
@herval 
Fundador de Startups 
Dois Easter Eggs 
publicados 
Padawan Scala 
Tem um cachorro
A Nuvem de Som 
12 horas de novo conteúdo/ minuto 
350 milhões de usuários/mês 
12 milhões de horas ouvidas/mês 
1 usuário no espaço
Era uma vez uma startup...
Era uma vez uma startup... 
Uma base de código
Era uma vez uma startup... 
Uma base de código 
Um punhado de construtores
Move fast 
and break 
things
Um milhão de features 
Base de código gigante
Quebrando os muros
Muitos vilarejos, muitos idiomas
Muitos vilarejos, muitos idiomas 
Microserviços → "tudo é http" 
Culturas de código 
Infraestrutura 
Monitoramento 
"production ready"
Ninguém entende ninguém
Move fast 
without breaking everything, bitte.
Java
Java 
Serviços de base 
Bibliotecas compartilhadas 
Monitoria 
Autenticação/segurança 
(cross-cutting concerns)
Java 
Serviços de base 
Bibliotecas compartilhadas 
Monitoria 
Autenticação/segurança 
(cross-cutting concerns) 
INFRAESTRUTURA BÁSICA
JVM-Kit 
+ Finagle
Estudo de caso 
O novo Stream
Reescrever pra quê?
Reescrever pra quê? 
API 
Cassandra 
MySQL
Reescrever pra quê? 
API 
Cassandra 
MySQL
Reescrever pra quê? 
80% request queueing 
API 
Cassandra 
MySQL
Reescrever pra quê? 
Novas features 
Latência 
Vazão 
Microserviços
API 
Timeline
API 
Timeline 
Roshi
API 
Timeline 
Roshi 
Autentic. 
Autoriz. 
Geo loc.
API 
Timeline 
Roshi 
Autentic. 
Autoriz. 
Geo loc.
API 
Timeline 
Roshi 
Autentic. 
Autoriz. 
Geo loc. 
Playlists 
Tracks 
Usuários
API 
Timeline 
Roshi 
Autentic. 
Autoriz. 
Geo loc. 
Playlists 
Tracks 
Usuários 
Likes 
Coment. 
Promoted 
Stats
API 
Timeline 
Roshi 
Autentic. 
Autoriz. 
Geo loc. 
Playlists 
Tracks 
Usuários 
Likes 
Coment. 
Promoted 
Stats 
...
Buscar 
API 
Agregar 
Timeline 
Roshi 
Autentic. 
Autoriz. 
Geo loc. 
Playlists 
Tracks 
Usuários 
Likes 
Coment. 
Promoted 
Stats 
...
Buscar 
Latência
API 
Timeline 
Roshi 
Autentic. 
Autoriz. 
Geo loc. 
Playlists 
Tracks 
Usuários 
Likes 
Coment. 
Promoted 
Stats 
...
Agregar 
Complexidade
API 
Timeline 
Roshi 
Autentic. 
Autoriz. 
Geo loc. 
Playlists 
Tracks 
Usuários 
Likes 
Coment. 
Promoted 
Stats 
...
Scala 
yay!
Buscar 
Paralelizar
Futuros
Futuros 
Referência para um 
valor que será 
disponibilizado no 
futuro.
Futuros 
val response: Future[Int] = … 
// Não compila 
response + 1
Futuros 
val response: Future[Int] = … 
// Adiciona um callback 
response.onSuccess { int => 
println(int) 
}
Futuros 
val response: Future[Int] = … 
// Compõe um novo futuro 
val count: Future[Int] = 
response.map { int => 
int + 1 
}
Futuros 
for { 
user <- authenticate(request) 
} yield { 
}
Futuros 
for { 
user <- authenticate(request) 
geo <- geoLocationFor(request, user) 
} yield { 
}
Futuros 
for { 
user <- authenticate(request) 
geo <- geoLocationFor(request, user) 
timeline <- timelineFor(user, geo) 
} yield { 
}
Futuros 
for { 
user <- authenticate(request) 
geo <- geoLocationFor(request, user) 
timeline <- timelineFor(user, geo) 
resources <- 
fetchTracks(timeline) 
.join(fetchPlaylists(timeline)) 
.join(fetchComments(timeline)) 
} yield { 
}
Futuros 
for { 
user <- authenticate(request) 
geo <- geoLocationFor(request, user) 
timeline <- timelineFor(user, geo) 
resources <- 
fetchTracks(timeline) 
.join(fetchPlaylists(timeline)) 
.join(fetchComments(timeline)) 
} yield { 
new EnrichedTimeline(timeline, resources) 
}
Futuros 
def handle(request: Request): Future[EnrichedTimeline] = 
for { 
user <- authenticate(request) 
geo <- geoLocationFor(request, user) 
timeline <- timelineFor(user, geo) 
resources <- 
fetchTracks(timeline) 
.join(fetchPlaylists(timeline)) 
.join(fetchComments(timeline)) 
} yield { 
new EnrichedTimeline(timeline, resources) 
}
Futuros 
+ NIO 
Escalabilidade
Máquinas
Máquinas 
Processos
Máquinas 
Processos 
Threads
Máquinas 
Processos 
Threads 
Futuros
Futuros 
def handle(request: Request): Future[EnrichedTimeline] = 
for { 
user <- authenticate(request) 
geo <- geoLocationFor(request, user) 
timeline <- timelineFor(user, geo) 
resources <- 
fetchTracks(timeline) 
.join(fetchPlaylists(timeline)) 
.join(fetchComments(timeline)) 
} yield { 
new EnrichedTimeline(timeline, resources) 
}
Agregar 
Funcional
Collections
val timeline: Timeline = …
val timeline: Timeline = … 
val actorsToFetch: List[User] = 
timeline.items.map(_.actor)
val timeline: Timeline = … 
val actorsToFetch: List[User] = 
timeline.items.map(_.actor) 
val itemsByActor: Map[User, List[Item]] = 
timeline.items.groupBy(_.actor)
val timeline: Timeline = … 
val actorsToFetch: List[User] = 
timeline.items.map(_.actor) 
val itemsByActor: Map[User, List[Item]] = 
timeline.items.groupBy(_.actor) 
val numberOfItemsByActor: Map[User, Int] = 
itemsByActor.mapValues(_.size)
def createEnrichedTimeline( 
timeline: Timeline, 
users: Map[User, EnrichedUser]) = { 
timeline.items.map { item => 
new EnrichedItem( 
item, users.get(item.actor)) 
} 
}
Options
Option[T] 
None Some(value)
Options 
def findUser(id: Int): Option[User] 
// Não compila 
render.json(findUser(666).name)
def findUser(id: Int): Option[User] 
// Compila 
findUser(666).map { 
case Some(user) => render.json(user.name) 
case None => render.notFound 
} 
Options
Pattern 
Matching
case class User(name: String, gender: Gender, email: Email)
case class User(name: String, gender: Gender, email: Email) 
timelineActors.foreach { 
}
case class User(name: String, gender: Gender, email: Email) 
timelineActors.foreach { 
case User(name, Female, Email(_, “soundcloud.com”) => 
println(“mulher trabalhando na soundcloud”) 
}
case class User(name: String, gender: Gender, email: Email) 
timelineActors.foreach { 
case User(name, Female, Email(_, “soundcloud.com”) => 
println(“mulher trabalhando na soundcloud”) 
case User(name, Male, Email(_, “soundcloud.com”) => 
println(“homem trabalhando na soundcloud”) 
}
case class User(name: String, gender: Gender, email: Email) 
timelineActors.foreach { 
case User(name, Female, Email(_, “soundcloud.com”) => 
println(“mulher trabalhando na soundcloud”) 
case User(name, Male, Email(_, “soundcloud.com”) => 
println(“homem trabalhando na soundcloud”) 
case User(name, gender, Email(_, “qconrio.com.br”) => 
println(“organizador da qconrio”) 
}
case class User(name: String, gender: Gender, email: Email) 
timelineActors.foreach { 
case User(name, Female, Email(_, “soundcloud.com”) => 
println(“mulher trabalhando na soundcloud”) 
case User(name, Male, Email(_, “soundcloud.com”) => 
println(“homem trabalhando na soundcloud”) 
case User(name, gender, Email(_, “qconrio.com.br”) => 
println(“organizador da qconrio”) 
case _ => 
println(“pessoa desconhecida”) 
}
Nem tudo são flores...
Código denso 
def flatMap[B, That] 
(f: (A) ⇒ Traversable[B]) 
(implicit bf: CanBuildFrom[ 
List[A], B, That]): That
Código denso 
def flatMap[B, That] 
(f: (A) ⇒ Traversable[B]) 
(implicit bf: CanBuildFrom[ 
List[A], B, That]): That 
listOfThings.flatMap(_.toUpperCase)
XML também é código? 
<fruits> 
<fruit type="banana" origin="brazil"/> 
<fruit type="apple"/> 
<fruit type="orange" origin="usa"/> 
<fruit type="orange" origin="brazil"/> 
</fruits>  "fruit" 
filter { _  "@origin" 
exists (_.text == "brazil") }
Mas e o Stream...?
Mas e o Stream...? 
API 
Cassandra 
MySQL
Mas e o Stream...? 
API 
MySQL 
Tracks 
SPelarvyilcisets 
SMeurvltiicpele 
Services 
Timeline Redis 
Service
Mas e o Stream...? 
~150 ms 
~0% request queueing 
API 
MySQL 
Tracks 
SPelarvyilcisets 
SMeurvltiicpele 
Services 
Timeline Redis 
Service
Mas só o Stream...? 
Data team 
Outros serviços em 
Scala 
Ferramental jvmkit
Stranglers
Stranglers
Stranglers 
Novo 
stream 
Cache
O presente
Em resumo... 
Produtivo como Ruby, typesafe 
como Java* 
Move faster 
break fewer things
O futuro
O futuro 
Padrões de código 
Bibliotecas mais estáveis 
Facilidade de inovação 
"One Scala"
Perguntas?

More Related Content

Viewers also liked

3personasenlahistoria
3personasenlahistoria3personasenlahistoria
3personasenlahistoriaticovago
 
So you think JSON is cool?
So you think JSON is cool?So you think JSON is cool?
So you think JSON is cool?Herval Freire
 
08 Le Shopping Dhommes
08 Le Shopping Dhommes08 Le Shopping Dhommes
08 Le Shopping Dhommeszut
 
daniela tdc
daniela tdcdaniela tdc
daniela tdcdany286
 

Viewers also liked (6)

Tag Libraries
Tag LibrariesTag Libraries
Tag Libraries
 
3personasenlahistoria
3personasenlahistoria3personasenlahistoria
3personasenlahistoria
 
So you think JSON is cool?
So you think JSON is cool?So you think JSON is cool?
So you think JSON is cool?
 
08 Le Shopping Dhommes
08 Le Shopping Dhommes08 Le Shopping Dhommes
08 Le Shopping Dhommes
 
Legacy
LegacyLegacy
Legacy
 
daniela tdc
daniela tdcdaniela tdc
daniela tdc
 

Similar to Scala e Arquitetura de Microsserviços para APIs de Streaming

Possibilidades com python
Possibilidades com pythonPossibilidades com python
Possibilidades com pythonUFPA
 
Desenvolvendo para WEB com JAVA
Desenvolvendo para WEB com JAVADesenvolvendo para WEB com JAVA
Desenvolvendo para WEB com JAVAWillian Magalhães
 
Ecosistema spring a_plataforma_enterprise_jav
Ecosistema spring a_plataforma_enterprise_javEcosistema spring a_plataforma_enterprise_jav
Ecosistema spring a_plataforma_enterprise_javJulio Viegas
 
Apache NiFi com postgresql
Apache NiFi com postgresqlApache NiFi com postgresql
Apache NiFi com postgresqlGerdan Santos
 
Apache NiFi com PostgreSQL - PGConf.Brasil 2018
Apache NiFi com PostgreSQL - PGConf.Brasil 2018Apache NiFi com PostgreSQL - PGConf.Brasil 2018
Apache NiFi com PostgreSQL - PGConf.Brasil 2018Davy Alvarenga Machado
 
De a máxima cobertura nos seus testes de API
De a máxima cobertura nos seus testes de APIDe a máxima cobertura nos seus testes de API
De a máxima cobertura nos seus testes de APIElias Nogueira
 
As Novidades Do C# 4.0 - NetPonto
As Novidades Do C# 4.0 - NetPontoAs Novidades Do C# 4.0 - NetPonto
As Novidades Do C# 4.0 - NetPontoPaulo Morgado
 
Além do Webdriver e Page Objects - Versão completa
Além do Webdriver e Page Objects - Versão completaAlém do Webdriver e Page Objects - Versão completa
Além do Webdriver e Page Objects - Versão completaCharles Kilesse
 
LINQ - Language Integrated Query
LINQ - Language Integrated QueryLINQ - Language Integrated Query
LINQ - Language Integrated QueryDalton Valadares
 
JQuery Alagoinhas Dev Day - UNEB
JQuery Alagoinhas Dev Day - UNEBJQuery Alagoinhas Dev Day - UNEB
JQuery Alagoinhas Dev Day - UNEBLuciano Borges
 
Evento Front End SP - Organizando o Javascript
 Evento Front End SP - Organizando o Javascript Evento Front End SP - Organizando o Javascript
Evento Front End SP - Organizando o JavascriptMichel Ribeiro
 
[Datafest 2018] Apache Spark Structured Stream - Moedor de dados em tempo qua...
[Datafest 2018] Apache Spark Structured Stream - Moedor de dados em tempo qua...[Datafest 2018] Apache Spark Structured Stream - Moedor de dados em tempo qua...
[Datafest 2018] Apache Spark Structured Stream - Moedor de dados em tempo qua...Eiti Kimura
 
Golang para desenvolvedores pragmáticos parte 2
Golang para desenvolvedores pragmáticos  parte 2Golang para desenvolvedores pragmáticos  parte 2
Golang para desenvolvedores pragmáticos parte 2Wilson Júnior
 

Similar to Scala e Arquitetura de Microsserviços para APIs de Streaming (20)

Possibilidades com python
Possibilidades com pythonPossibilidades com python
Possibilidades com python
 
JQuery
JQuery JQuery
JQuery
 
Desenvolvendo para WEB com JAVA
Desenvolvendo para WEB com JAVADesenvolvendo para WEB com JAVA
Desenvolvendo para WEB com JAVA
 
Ecosistema spring a_plataforma_enterprise_jav
Ecosistema spring a_plataforma_enterprise_javEcosistema spring a_plataforma_enterprise_jav
Ecosistema spring a_plataforma_enterprise_jav
 
Apache NiFi com postgresql
Apache NiFi com postgresqlApache NiFi com postgresql
Apache NiFi com postgresql
 
Apache NiFi com PostgreSQL - PGConf.Brasil 2018
Apache NiFi com PostgreSQL - PGConf.Brasil 2018Apache NiFi com PostgreSQL - PGConf.Brasil 2018
Apache NiFi com PostgreSQL - PGConf.Brasil 2018
 
Minicurso groovy grails
Minicurso groovy grailsMinicurso groovy grails
Minicurso groovy grails
 
De a máxima cobertura nos seus testes de API
De a máxima cobertura nos seus testes de APIDe a máxima cobertura nos seus testes de API
De a máxima cobertura nos seus testes de API
 
As Novidades Do C# 4.0 - NetPonto
As Novidades Do C# 4.0 - NetPontoAs Novidades Do C# 4.0 - NetPonto
As Novidades Do C# 4.0 - NetPonto
 
Tdc2010 web
Tdc2010 webTdc2010 web
Tdc2010 web
 
Além do Webdriver e Page Objects - Versão completa
Além do Webdriver e Page Objects - Versão completaAlém do Webdriver e Page Objects - Versão completa
Além do Webdriver e Page Objects - Versão completa
 
LINQ - Language Integrated Query
LINQ - Language Integrated QueryLINQ - Language Integrated Query
LINQ - Language Integrated Query
 
API Apontador
API ApontadorAPI Apontador
API Apontador
 
JQuery Alagoinhas Dev Day - UNEB
JQuery Alagoinhas Dev Day - UNEBJQuery Alagoinhas Dev Day - UNEB
JQuery Alagoinhas Dev Day - UNEB
 
Dinamizando Sites Estáticos
Dinamizando Sites EstáticosDinamizando Sites Estáticos
Dinamizando Sites Estáticos
 
Realtime com node.js e socket.io
Realtime com node.js e socket.ioRealtime com node.js e socket.io
Realtime com node.js e socket.io
 
Evento Front End SP - Organizando o Javascript
 Evento Front End SP - Organizando o Javascript Evento Front End SP - Organizando o Javascript
Evento Front End SP - Organizando o Javascript
 
[Datafest 2018] Apache Spark Structured Stream - Moedor de dados em tempo qua...
[Datafest 2018] Apache Spark Structured Stream - Moedor de dados em tempo qua...[Datafest 2018] Apache Spark Structured Stream - Moedor de dados em tempo qua...
[Datafest 2018] Apache Spark Structured Stream - Moedor de dados em tempo qua...
 
Golang para desenvolvedores pragmáticos parte 2
Golang para desenvolvedores pragmáticos  parte 2Golang para desenvolvedores pragmáticos  parte 2
Golang para desenvolvedores pragmáticos parte 2
 
Kotlin no desenvolvimento Mobile - FTSL
Kotlin no desenvolvimento Mobile - FTSLKotlin no desenvolvimento Mobile - FTSL
Kotlin no desenvolvimento Mobile - FTSL
 

More from Herval Freire

Stress Testing at Twitter: a tale of New Year Eves
Stress Testing at Twitter: a tale of New Year EvesStress Testing at Twitter: a tale of New Year Eves
Stress Testing at Twitter: a tale of New Year EvesHerval Freire
 
Recommendation engines
Recommendation enginesRecommendation engines
Recommendation enginesHerval Freire
 
Sollipsis Publishing Catalog
Sollipsis   Publishing CatalogSollipsis   Publishing Catalog
Sollipsis Publishing CatalogHerval Freire
 
Sollipsis Venture Forum
Sollipsis   Venture ForumSollipsis   Venture Forum
Sollipsis Venture ForumHerval Freire
 
Sollipsis Premium Games
Sollipsis   Premium GamesSollipsis   Premium Games
Sollipsis Premium GamesHerval Freire
 
Padrões De Projeto e Anti Patterns
Padrões De Projeto e Anti PatternsPadrões De Projeto e Anti Patterns
Padrões De Projeto e Anti PatternsHerval Freire
 
Biofeedback - Slides CBIS
Biofeedback - Slides CBISBiofeedback - Slides CBIS
Biofeedback - Slides CBISHerval Freire
 
[ “Love", :Ruby ].each { |i| p i }
[ “Love", :Ruby ].each { |i| p i }[ “Love", :Ruby ].each { |i| p i }
[ “Love", :Ruby ].each { |i| p i }Herval Freire
 

More from Herval Freire (10)

Stress Testing at Twitter: a tale of New Year Eves
Stress Testing at Twitter: a tale of New Year EvesStress Testing at Twitter: a tale of New Year Eves
Stress Testing at Twitter: a tale of New Year Eves
 
Recommendation engines
Recommendation enginesRecommendation engines
Recommendation engines
 
Startup Don'ts
Startup Don'tsStartup Don'ts
Startup Don'ts
 
Sollipsis Publishing Catalog
Sollipsis   Publishing CatalogSollipsis   Publishing Catalog
Sollipsis Publishing Catalog
 
Sollipsis Venture Forum
Sollipsis   Venture ForumSollipsis   Venture Forum
Sollipsis Venture Forum
 
Sollipsis Premium Games
Sollipsis   Premium GamesSollipsis   Premium Games
Sollipsis Premium Games
 
Sollipsis Catalog
Sollipsis   CatalogSollipsis   Catalog
Sollipsis Catalog
 
Padrões De Projeto e Anti Patterns
Padrões De Projeto e Anti PatternsPadrões De Projeto e Anti Patterns
Padrões De Projeto e Anti Patterns
 
Biofeedback - Slides CBIS
Biofeedback - Slides CBISBiofeedback - Slides CBIS
Biofeedback - Slides CBIS
 
[ “Love", :Ruby ].each { |i| p i }
[ “Love", :Ruby ].each { |i| p i }[ “Love", :Ruby ].each { |i| p i }
[ “Love", :Ruby ].each { |i| p i }
 

Scala e Arquitetura de Microsserviços para APIs de Streaming

  • 1.
  • 2. @flaviowbrasil Aficionado por open source Expert em escalabilidade Mestre Jedi Scala Prefere uma sessão de profiling a uma tarde na praia
  • 3. @herval Fundador de Startups Dois Easter Eggs publicados Padawan Scala Tem um cachorro
  • 4. A Nuvem de Som 12 horas de novo conteúdo/ minuto 350 milhões de usuários/mês 12 milhões de horas ouvidas/mês 1 usuário no espaço
  • 5. Era uma vez uma startup...
  • 6. Era uma vez uma startup... Uma base de código
  • 7. Era uma vez uma startup... Uma base de código Um punhado de construtores
  • 8. Move fast and break things
  • 9. Um milhão de features Base de código gigante
  • 12. Muitos vilarejos, muitos idiomas Microserviços → "tudo é http" Culturas de código Infraestrutura Monitoramento "production ready"
  • 14. Move fast without breaking everything, bitte.
  • 15. Java
  • 16. Java Serviços de base Bibliotecas compartilhadas Monitoria Autenticação/segurança (cross-cutting concerns)
  • 17. Java Serviços de base Bibliotecas compartilhadas Monitoria Autenticação/segurança (cross-cutting concerns) INFRAESTRUTURA BÁSICA
  • 18.
  • 20. Estudo de caso O novo Stream
  • 21.
  • 23. Reescrever pra quê? API Cassandra MySQL
  • 24. Reescrever pra quê? API Cassandra MySQL
  • 25. Reescrever pra quê? 80% request queueing API Cassandra MySQL
  • 26. Reescrever pra quê? Novas features Latência Vazão Microserviços
  • 29. API Timeline Roshi Autentic. Autoriz. Geo loc.
  • 30. API Timeline Roshi Autentic. Autoriz. Geo loc.
  • 31. API Timeline Roshi Autentic. Autoriz. Geo loc. Playlists Tracks Usuários
  • 32. API Timeline Roshi Autentic. Autoriz. Geo loc. Playlists Tracks Usuários Likes Coment. Promoted Stats
  • 33. API Timeline Roshi Autentic. Autoriz. Geo loc. Playlists Tracks Usuários Likes Coment. Promoted Stats ...
  • 34. Buscar API Agregar Timeline Roshi Autentic. Autoriz. Geo loc. Playlists Tracks Usuários Likes Coment. Promoted Stats ...
  • 36. API Timeline Roshi Autentic. Autoriz. Geo loc. Playlists Tracks Usuários Likes Coment. Promoted Stats ...
  • 38. API Timeline Roshi Autentic. Autoriz. Geo loc. Playlists Tracks Usuários Likes Coment. Promoted Stats ...
  • 41.
  • 43. Futuros Referência para um valor que será disponibilizado no futuro.
  • 44. Futuros val response: Future[Int] = … // Não compila response + 1
  • 45. Futuros val response: Future[Int] = … // Adiciona um callback response.onSuccess { int => println(int) }
  • 46. Futuros val response: Future[Int] = … // Compõe um novo futuro val count: Future[Int] = response.map { int => int + 1 }
  • 47. Futuros for { user <- authenticate(request) } yield { }
  • 48. Futuros for { user <- authenticate(request) geo <- geoLocationFor(request, user) } yield { }
  • 49. Futuros for { user <- authenticate(request) geo <- geoLocationFor(request, user) timeline <- timelineFor(user, geo) } yield { }
  • 50. Futuros for { user <- authenticate(request) geo <- geoLocationFor(request, user) timeline <- timelineFor(user, geo) resources <- fetchTracks(timeline) .join(fetchPlaylists(timeline)) .join(fetchComments(timeline)) } yield { }
  • 51. Futuros for { user <- authenticate(request) geo <- geoLocationFor(request, user) timeline <- timelineFor(user, geo) resources <- fetchTracks(timeline) .join(fetchPlaylists(timeline)) .join(fetchComments(timeline)) } yield { new EnrichedTimeline(timeline, resources) }
  • 52. Futuros def handle(request: Request): Future[EnrichedTimeline] = for { user <- authenticate(request) geo <- geoLocationFor(request, user) timeline <- timelineFor(user, geo) resources <- fetchTracks(timeline) .join(fetchPlaylists(timeline)) .join(fetchComments(timeline)) } yield { new EnrichedTimeline(timeline, resources) }
  • 53. Futuros + NIO Escalabilidade
  • 58. Futuros def handle(request: Request): Future[EnrichedTimeline] = for { user <- authenticate(request) geo <- geoLocationFor(request, user) timeline <- timelineFor(user, geo) resources <- fetchTracks(timeline) .join(fetchPlaylists(timeline)) .join(fetchComments(timeline)) } yield { new EnrichedTimeline(timeline, resources) }
  • 62. val timeline: Timeline = … val actorsToFetch: List[User] = timeline.items.map(_.actor)
  • 63. val timeline: Timeline = … val actorsToFetch: List[User] = timeline.items.map(_.actor) val itemsByActor: Map[User, List[Item]] = timeline.items.groupBy(_.actor)
  • 64. val timeline: Timeline = … val actorsToFetch: List[User] = timeline.items.map(_.actor) val itemsByActor: Map[User, List[Item]] = timeline.items.groupBy(_.actor) val numberOfItemsByActor: Map[User, Int] = itemsByActor.mapValues(_.size)
  • 65. def createEnrichedTimeline( timeline: Timeline, users: Map[User, EnrichedUser]) = { timeline.items.map { item => new EnrichedItem( item, users.get(item.actor)) } }
  • 68. Options def findUser(id: Int): Option[User] // Não compila render.json(findUser(666).name)
  • 69. def findUser(id: Int): Option[User] // Compila findUser(666).map { case Some(user) => render.json(user.name) case None => render.notFound } Options
  • 71. case class User(name: String, gender: Gender, email: Email)
  • 72. case class User(name: String, gender: Gender, email: Email) timelineActors.foreach { }
  • 73. case class User(name: String, gender: Gender, email: Email) timelineActors.foreach { case User(name, Female, Email(_, “soundcloud.com”) => println(“mulher trabalhando na soundcloud”) }
  • 74. case class User(name: String, gender: Gender, email: Email) timelineActors.foreach { case User(name, Female, Email(_, “soundcloud.com”) => println(“mulher trabalhando na soundcloud”) case User(name, Male, Email(_, “soundcloud.com”) => println(“homem trabalhando na soundcloud”) }
  • 75. case class User(name: String, gender: Gender, email: Email) timelineActors.foreach { case User(name, Female, Email(_, “soundcloud.com”) => println(“mulher trabalhando na soundcloud”) case User(name, Male, Email(_, “soundcloud.com”) => println(“homem trabalhando na soundcloud”) case User(name, gender, Email(_, “qconrio.com.br”) => println(“organizador da qconrio”) }
  • 76. case class User(name: String, gender: Gender, email: Email) timelineActors.foreach { case User(name, Female, Email(_, “soundcloud.com”) => println(“mulher trabalhando na soundcloud”) case User(name, Male, Email(_, “soundcloud.com”) => println(“homem trabalhando na soundcloud”) case User(name, gender, Email(_, “qconrio.com.br”) => println(“organizador da qconrio”) case _ => println(“pessoa desconhecida”) }
  • 77. Nem tudo são flores...
  • 78.
  • 79. Código denso def flatMap[B, That] (f: (A) ⇒ Traversable[B]) (implicit bf: CanBuildFrom[ List[A], B, That]): That
  • 80. Código denso def flatMap[B, That] (f: (A) ⇒ Traversable[B]) (implicit bf: CanBuildFrom[ List[A], B, That]): That listOfThings.flatMap(_.toUpperCase)
  • 81. XML também é código? <fruits> <fruit type="banana" origin="brazil"/> <fruit type="apple"/> <fruit type="orange" origin="usa"/> <fruit type="orange" origin="brazil"/> </fruits> "fruit" filter { _ "@origin" exists (_.text == "brazil") }
  • 82.
  • 83. Mas e o Stream...?
  • 84. Mas e o Stream...? API Cassandra MySQL
  • 85. Mas e o Stream...? API MySQL Tracks SPelarvyilcisets SMeurvltiicpele Services Timeline Redis Service
  • 86. Mas e o Stream...? ~150 ms ~0% request queueing API MySQL Tracks SPelarvyilcisets SMeurvltiicpele Services Timeline Redis Service
  • 87. Mas só o Stream...? Data team Outros serviços em Scala Ferramental jvmkit
  • 92. Em resumo... Produtivo como Ruby, typesafe como Java* Move faster break fewer things
  • 94. O futuro Padrões de código Bibliotecas mais estáveis Facilidade de inovação "One Scala"