Scala in a wild enterprise

1,122
-1

Published on

Video: (in russian)
http://www.youtube.com/watch?v=4pTDhgWW6ko

0 Comments
0 Likes
Statistics
Notes
  • Be the first to comment

  • Be the first to like this

No Downloads
Views
Total Views
1,122
On Slideshare
0
From Embeds
0
Number of Embeds
2
Actions
Shares
0
Downloads
9
Comments
0
Likes
0
Embeds 0
No embeds

No notes for slide

Scala in a wild enterprise

  1. 1. th e?Scala in a wild enterprise Rafael Bagmanov ( Grid Dynamics )
  2. 2. In what use cases (types of applications) does Scala make the least sense?
  3. 3. "Database front end, CRUD apps.Most of the boring apps that are built withStruts and Spring" David Pollak "Barriers to scala adoption" Infoq.com
  4. 4. OpenGenesisgithub.com/griddynamics/OpenGenesis
  5. 5. OpenGenesisDeployment orchestration tool● open source - open-genesis.org● 2 years of development● > 50 KLOC of scala code● successfully deployed to production in one large american financial institution● Buzzwords: continuous deployment, cloud, chef, devops, aws, openstack
  6. 6. Enterprise characteristics● Integration with legacy apps and data (lots of SOAP and xml)● sophisticated security policies● IT department separated from development team● J2EE Containers everywhere● Risk averse
  7. 7. Typical "lightweight" j2ee stack Web layer Spring MVC Service layer Spring Data access layer JPA DB
  8. 8. j2ee stack. Scala edition Web layer Spring MVC + scala magic Service layer Spring + scala implicits Data access layer JPA Squeryl DB
  9. 9. j2ee stack. Scala edition WAR Spring MVC Web layer Spring Service layer Squeryl Data access layer DB
  10. 10. j2ee stack. Scala edition + scala goodness WAR Spring MVC Web layer Akka Spring Workflow distributed Service layer engine Squeryl Data access layer DB
  11. 11. Service layer: Spring
  12. 12. Spring with scala● DI fits almost nicely with scala
  13. 13. Spring with scala● DI fits almost nicely with scala class GenesisRestController { @Autowired var genesisService: GenesisService = _ } class GenesisRestController { @BeanProperty var genesisService: GenesisService = _ } class GenesisRestController (genesisService: GenesisService) {}
  14. 14. Spring with scala● DI fits almost nicely with scala ○ "Everything is a trait" approach cant be done
  15. 15. Spring with scala● DI fits almost nicely with scala ○ "Everything is a trait" approach cant be done ○ Be aware of type inference in @Configuration bean trait Service class ServiceImpl extends Service @Configuration class ServiceContext { @Bean def service = new ServiceImpl }
  16. 16. Spring with scala● DI fits almost nicely with scala ○ "Everything is a trait" approach cant be done ○ Be aware of type inference in @Configuration bean trait Service class ServiceImpl extends Service @Configuration class ServiceContext { @Bean def service: Service = new ServiceImpl }
  17. 17. Spring with scala● DI fits almost nicely with scala● Rich spring templates libraries.
  18. 18. Spring with scala● DI fits almost nicely with scala● Rich spring templates libraries. springLdapTemplate.authenticate("user", "*", "password", new AuthenticationErrorCallback { def execute(e: Exception) {log.error(e)} })
  19. 19. Spring with scala● DI fits almost nicely with scala● Rich spring templates libraries. springLdapTemplate.authenticate("user", "*", "password", new AuthenticationErrorCallback { def execute(e: Exception) {log.error(e)} })
  20. 20. Spring with scala● DI fits almost nicely with scala● Rich spring templates libraries. springLdapTemplate.authenticate("user", "*", "password", new AuthenticationErrorCallback { def execute(e: Exception) {log.error(e)} }) springLdapTemplate.authenticate("user", "*", "password", log.error(_))
  21. 21. Spring with scala● DI fits almost nicely with scala● Rich spring templates libraries. springLdapTemplate.authenticate("user", "*", "password", log.error(_)) implicit def authErrorCallbackWrapper(func:(Exception) => Any) = { new AuthenticationErrorCallback { def execute(exception: Exception): Unit = func(exception) } }
  22. 22. Spring with scala● DI fits almost nicely with scala● Rich spring templates libraries.● AOP for free (almost)
  23. 23. Spring with scala● DI fits almost nicely with scala● Rich spring templates libraries.● AOP for free (almost) ○ Be aware of naming in debug info def findUsers(projectId: Int) { dao.findUsers(projectId) } def findUsers2(projectId: Int) { dao.allUsers().filter(_.projectId == projectId) }
  24. 24. Spring with scala● DI fits almost nicely with scala● Rich spring templates libraries.● AOP for free (almost) ○ Be aware of naming in debug info def findUsers(projectId: Int) { // debugIfo: name "projectId" dao.findUsers(projectId) } def findUsers2(projectId: Int) { // debugInfo: name "projectId$" dao.allUsers().filter(_.projectId == projectId) }
  25. 25. Spring with scala● DI fits almost nicely with scala● Rich spring templates libraries.● AOP for free (almost)● Spring security just works
  26. 26. Persistence layer: Squeryl
  27. 27. Squeryl● Lightweight ORM written in scala
  28. 28. Squeryl● Lightweight ORM written in scala class Workflow(override val id: Int) extends KeyedEntity[Int]
  29. 29. Squeryl● Lightweight ORM written in scala class Workflow(override val id: Int) extends KeyedEntity[Int] object GS extends Schema { val workflows = table[Workflow] }
  30. 30. Squeryl● Lightweight ORM written in scala class Workflow(override val id: Int) extends KeyedEntity[Int] object GS extends Schema { val workflows = table[Workflow] } def find(workflowId: Int) = from(GS.workflows)(w => where(w.id === workflowId) select (w) orderBy(w.id desc) )
  31. 31. Squeryl● Lightweight ORM written in scala ○ First class support for scala collections, options, etc
  32. 32. Squeryl● Lightweight ORM written in scala ○ First class support for scala collections, options, etc ○ Integrates with spring transaction management (not out of the box)
  33. 33. Squeryl● Lightweight ORM written in scala ○ First class support for scala collections, options, etc ○ Integrates with spring transaction management (not out of the box) @Transactional(propagation = REQUIRES_NEW) def find(workflowId: Int) = from(GS.workflows)(w => where(w.id === workflowId) select (w) orderBy(w.id desc) )
  34. 34. Squeryl● Lightweight ORM written in scala ○ Likes heap in the same proportion as Hibernate doeshibernate squeryl
  35. 35. Squeryl● Lightweight ORM written in scala ○ Likes heap in the same proportion as Hibernate does ○ Lots of "black magic" in source code
  36. 36. Squeryl● Lightweight ORM written in scala● Internal scala DSL for writing queries ○ Type safe queries - compile time syntax check
  37. 37. Squeryl● Lightweight ORM written in scala● Internal scala DSL for writing queries ○ Lots of "black magic" in source code
  38. 38. Squeryl● Lightweight ORM written in scala● Internal scala DSL for writing queries ○ Lots of "black magic" in source code ○ Fallback on native sql is not easy
  39. 39. Squeryl● Lightweight ORM written in scala● Internal scala DSL for writing queries ○ Lots of "black magic" in source code ○ Fallback on native sql is not easy ○ Lots of implicits drives IDE crazy and increases compilation time
  40. 40. Squeryl● Lightweight ORM written in scala● Internal scala DSL for writing queries ○ Lots of "black magic" in source code ○ Fallback on native sql is not easy ○ Lots of implicits drives IDE crazy and increase compilation time ○ The approach is somewhat flawed (opinion)
  41. 41. Web layer: Spring MVC lift-json scala magic
  42. 42. Web layer● RESTfull web services case class User ( @NotBlank username: String, @Email @Size(min = 1, max = 256) email: String, password: Option[String] ) @Controller @RequestMapping(Array("/rest/users")) class UsersController { @RequestMapping(method = Array(RequestMethod.POST)) @ResponseBody def create(@RequestBody @Valid request: User): User = userService.create(request) }
  43. 43. Web layer● RESTfull web services● Easy to make Hypermedia REST with implicits @Controller @RequestMapping(Array("/rest/users")) class UsersController { import com.griddynamics.genesis.rest.links.Hypermedia._ @RequestMapping(method = Array(RequestMethod.POST)) @ResponseBody def create(@RequestBody @Valid request: User): Hypermedia[User] = { userService.create(request).withLink("/rest/users", LinkType.SELF) }
  44. 44. Couple of words about AKKA
  45. 45. Ехал Акка через АккаСмотрит Акка в Акка Акка Сунул Акка Акка в Акка Акка Акка Акка Акка * * Ode to Akka in russian
  46. 46. Greatest challenge:
  47. 47. Greatest challenge: People
  48. 48. Challenges● Hiring is hard
  49. 49. Challenges● Hiring is hard ○ Scala is a talent attraction
  50. 50. Challenges● Hiring is hard ○ Scala is a talent attraction ○ In avg: 0.5 interview per month
  51. 51. Challenges● Hiring is hard● Settling team standards and code convention
  52. 52. Challenges● Hiring is hard● Settling team standards and code convention ○ Tools are not there yet
  53. 53. Challenges● Hiring is hard● Settling team standards and code convention ○ Tools are not there yet ○ Between "OCaml" and "Java" fires
  54. 54. Challenges● Hiring is hard● Settling team standards and code convention ○ Tools are not there yet ○ Between "OCaml" and "Java" fires ○ "Effective scala" by Twitter and "Scala style guide" might help (a bit)
  55. 55. The greatest code-review mystery ofall timesHow to deal with scala.Option if (option.isDefined) { option match { case Some(x) => .. .. case None => .. ? } } option.foreach { .. }
  56. 56. The greatest code-review mystery ofall timesHow to deal with scala.Option if (option.isDefined) { option match { case Some(x) => .. .. case None => .. ? } } option.foreach { .. }
  57. 57. Recruiting java developers
  58. 58. aka
  59. 59. 5 stages of grief
  60. 60. 5 stages of grief1. Denial2. Anger3. Bargaining4. Depression5. Acceptance
  61. 61. 5 stages of grief1. Denial2. Anger3. Bargaining4. Depression5. Acceptance
  62. 62. 5 stages of grief1. Denial2. Anger3. Bargaining4. Depression5. Acceptance
  63. 63. 5 stages of grief1. Denial2. Anger3. Bargaining4. Depression5. Acceptance
  64. 64. 5 stages of grief1. Denial2. Anger3. Bargaining4. Depression5. Acceptance
  65. 65. 5 stages of grief1. Denial2. Anger3. Bargaining4. Depression5. Acceptance

×