Slides
Transcrição
Slides
Aficionado por open source Expert em escalabilidade Mestre Jedi Scala Prefere uma sessão de profiling a uma tarde na praia @flaviowbrasil Fundador de Startups Dois Easter Eggs publicados Padawan Scala Tem um cachorro @herval 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ê? Cassandra API MySQL Reescrever pra quê? Cassandra API MySQL Reescrever pra quê? 80% request queueing Cassandra API MySQL Reescrever pra quê? Novas features Latência Vazão Microserviços API Timeline API Timeline Roshi Autoriz. Autentic. API Geo loc. Timeline Roshi Autoriz. Autentic. API Geo loc. Timeline Roshi Autoriz. Autentic. API Geo loc. Playlists Tracks Usuários Timeline Roshi Autoriz. Likes Autentic. Coment. API Promoted Geo loc. Stats Playlists Tracks Usuários Timeline Roshi Autoriz. Likes Autentic. Coment. API Promoted Geo loc. Stats Playlists ... Tracks Usuários Timeline Roshi Autoriz. Likes Buscar Agregar Autentic. Coment. API Promoted Geo loc. Stats Playlists ... Tracks Usuários Timeline Roshi Buscar Latência Autoriz. Likes Autentic. Coment. API Promoted Geo loc. Stats Playlists ... Tracks Usuários Timeline Roshi Agregar Complexidade Autoriz. Likes Autentic. Coment. API Promoted Geo loc. Stats Playlists ... Tracks Usuários Timeline Roshi 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) Options def findUser(id: Int): Option[User] // Compila findUser(666).map { case Some(user) => render.json(user.name) case None => render.notFound } 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...? Cassandra API MySQL Mas e o Stream...? Tracks Playlists Service Multiple Service Services MySQL API Timeline Service Redis Mas e o Stream...? ~150 ms Tracks Playlists Service Multiple Service Services MySQL API Timeline Service Redis 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?