Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.

Scala @ soundcloud [scaladores]

437 views

Published on

Scala @ soundcloud [scaladores]

Published in: Software
  • Be the first to comment

Scala @ soundcloud [scaladores]

  1. 1. @flaviowbrasil Aficionado por open source Expert em escalabilidade Mestre Jedi Scala Prefere + uma sessão de profiling do que uma tarde na praia
  2. 2. @herval Fundador de Startups Dois Easter Eggs publicados Padawan Scala Tem um cachorro com nome de sorvete
  3. 3. 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
  4. 4. Era uma vez uma startup... Uma base de código Um punhado de construtores
  5. 5. Um milhão de features Base de código gigante
  6. 6. Move fast and break things
  7. 7. Quebrando os muros
  8. 8. Muitos vilarejos, muitos idiomas Microserviços → "tudo é http" Culturas de código Infraestrutura Monitoramento "production ready"
  9. 9. A Torre de Babel Mais pessoas → mais linguagens N+1 linguagens N = número de linguagens de programação existentes
  10. 10. Move fast without breaking everything, bitte.
  11. 11. Java Serviços de base Bibliotecas compartilhadas Monitoria Autenticação/segurança (cross-cutting concerns) INFRAESTRUTURA BÁSICA
  12. 12. JVM-Kit
  13. 13. Estudo de caso O novo Stream
  14. 14. Reescrever pra quê? Novas features Latência Vazão Microserviços
  15. 15. API Timeline
  16. 16. API Timeline Roshi
  17. 17. API Timeline Roshi Autentic. Autoriz. Geo loc.
  18. 18. API Timeline Roshi Autentic. Autoriz. Geo loc.
  19. 19. API Timeline Roshi Autentic. Autoriz. Geo loc. Playlists Tracks Usuários
  20. 20. API Timeline Roshi Autentic. Autoriz. Geo loc. Playlists Tracks Usuários Likes Coment. Promoted Stats
  21. 21. API Timeline Roshi Autentic. Autoriz. Geo loc. Playlists Tracks Usuários Likes Coment. Promoted Stats ...
  22. 22. Buscar API Agregar Timeline Roshi Autentic. Autoriz. Geo loc. Playlists Tracks Usuários Likes Coment. Promoted Stats ...
  23. 23. Buscar Latência
  24. 24. API Timeline Roshi Autentic. Autoriz. Geo loc. Playlists Tracks Usuários Likes Coment. Promoted Stats ...
  25. 25. Agregar Complexidade
  26. 26. API Timeline Roshi Autentic. Autoriz. Geo loc. Playlists Tracks Usuários Likes Coment. Promoted Stats ...
  27. 27. Scala yay!
  28. 28. Buscar Paralelizar
  29. 29. Futuros
  30. 30. Futuros Referência para um valor que será disponibilizado no futuro.
  31. 31. Futuros val response: Future[Int] = … // Não compila response + 1
  32. 32. Futuros val response: Future[Int] = … // Adiciona um callback response.onSuccess { int => println(int) }
  33. 33. Futuros val response: Future[Int] = … // Compõe um novo futuro val count: Future[Int] = response.map { int => int + 1 }
  34. 34. Futuros for { user <- authenticate(request) } yield { }
  35. 35. Futuros for { user <- authenticate(request) geo <- geoLocationFor(request, user) } yield { }
  36. 36. Futuros for { user <- authenticate(request) geo <- geoLocationFor(request, user) timeline <- timelineFor(user, geo) } yield { }
  37. 37. Futuros for { user <- authenticate(request) geo <- geoLocationFor(request, user) timeline <- timelineFor(user, geo) resources <- fetchTracks(timeline) .join(fetchPlaylists(timeline)) .join(fetchComments(timeline)) } yield { }
  38. 38. 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) }
  39. 39. 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) }
  40. 40. Futuros + NIO Escalabilidade
  41. 41. Máquinas
  42. 42. Máquinas Processos
  43. 43. Máquinas Processos Threads
  44. 44. Máquinas Processos Threads Futuros
  45. 45. 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) }
  46. 46. Agregar Funcional
  47. 47. Collections
  48. 48. val timeline: Timeline = …
  49. 49. val timeline: Timeline = … val actorsToFetch: List[User] = timeline.items.map(_.actor)
  50. 50. val timeline: Timeline = … val actorsToFetch: List[User] = timeline.items.map(_.actor) val itemsByActor: Map[User, List[Item]] = timeline.items.groupBy(_.actor)
  51. 51. 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)
  52. 52. def createEnrichedTimeline( timeline: Timeline, users: Map[User, EnrichedUser]) = { timeline.items.map { item => new EnrichedItem( item, users.get(item.actor)) } }
  53. 53. Options
  54. 54. Option[T] None Some(value)
  55. 55. Options def findUser(id: Int): Option[User] // Nao compila render.json(findUser(666).name)
  56. 56. def findUser(id: Int): Option[User] // Compila findUser(666).map { case Some(user) => render.json(user.name) case None => render.notFound } Options
  57. 57. Pattern Matching
  58. 58. case class User(name: String, gender: Gender, email: Email)
  59. 59. case class User(name: String, gender: Gender, email: Email) timelineActors.foreach { }
  60. 60. case class User(name: String, gender: Gender, email: Email) timelineActors.foreach { case User(name, Female, Email(_, “soundcloud.com”) => println(“mulher trabalhando na soundcloud”) }
  61. 61. 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”) }
  62. 62. 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”) }
  63. 63. 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”) }
  64. 64. Nem tudo são flores...
  65. 65. Código denso
  66. 66. Mas e o Stream...?
  67. 67. Mas e o Stream...? API Cassandra MySQL
  68. 68. Mas e o Stream...? API Cassandra MySQL ~400 ms
  69. 69. Mas e o Stream...? API MySQL Tracks SPelarvyilcisets SPelarvyilcisets Service Timeline Redis Service
  70. 70. Mas e o Stream...? ~150 ms API MySQL Tracks SPelarvyilcisets SPelarvyilcisets Service Timeline Redis Service
  71. 71. Mas só o Stream...? Data team Outros servicos em Scala Ferramental jvmkit
  72. 72. Mas só o Stream...? Stranglers
  73. 73. Mas só o Stream...? Stranglers
  74. 74. Mas só o Stream...? Stranglers Novo stream
  75. 75. Mas só o Stream...? Stranglers Novo stream Cache
  76. 76. Em resumo... Produtivo como Ruby, typesafe como Java* Move faster, break fewer things
  77. 77. O presente
  78. 78. O futuro! Padrões de código Bibliotecas mais estáveis Facilidade de inovação "One Scala"
  79. 79. Perguntas? by the way, we're hiring http://bit.ly/qconrj2014

×