Rafael Bagmanov «Scala in a wild enterprise»

1,987 views
1,877 views

Published on

Published in: Technology
1 Comment
3 Likes
Statistics
Notes
  • A very interesting presentation! I was at the ScalaDev, it's awful that it was too brief due to lack of time.
       Reply 
    Are you sure you want to  Yes  No
    Your message goes here
No Downloads
Views
Total views
1,987
On SlideShare
0
From Embeds
0
Number of Embeds
7
Actions
Shares
0
Downloads
23
Comments
1
Likes
3
Embeds 0
No embeds

No notes for slide

Rafael Bagmanov «Scala in a wild enterprise»

  1. 1. Scala in a wildenterpriseRafael Bagmanov( Grid Dynamics )the?
  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. ● open source - open-genesis.org● 2 years of development● > 50 KLOC of scala code● successfully deployed to production in onelarge american financial institution● Buzzwords: continuous deployment, cloud,chef, devops, aws, openstackOpenGenesisDeployment orchestration tool
  6. 6. ● Integration with legacy apps and data (lots ofSOAP and xml)● sophisticated security policies● IT department separated from developmentteam● J2EE Containers everywhere● Risk averseEnterprise characteristics
  7. 7. Typical "lightweight" j2ee stackWeb layerService layerData access layerDBSpring MVCSpringJPA
  8. 8. j2ee stack. Scala editionWeb layerService layerData access layerDBSpring MVC + scala magicSpring + scala implicitsJPA Squeryl
  9. 9. j2ee stack. Scala editionWeb layerService layerData access layerDBSpring MVCSpringSquerylWAR
  10. 10. j2ee stack. Scala edition + scalagoodnessWeb layerService layerData access layerDBSpring MVCSpringSquerylWorkflow distributedengineAkkaWAR
  11. 11. Service layer: Spring
  12. 12. ● DI fits almost nicely with scalaSpring with scala
  13. 13. ● DI fits almost nicely with scalaclass GenesisRestController {@Autowired var genesisService: GenesisService = _}class GenesisRestController {@BeanProperty var genesisService: GenesisService = _}class GenesisRestController (genesisService: GenesisService) {}Spring with scala
  14. 14. ● DI fits almost nicely with scala○ "Everything is a trait" approach cant be doneSpring with scala
  15. 15. ● DI fits almost nicely with scala○ "Everything is a trait" approach cant be done○ Be aware of type inference in @Configuration beantrait Serviceclass ServiceImpl extends Service@Configurationclass ServiceContext {@Bean def service = new ServiceImpl}Spring with scala
  16. 16. ● DI fits almost nicely with scala○ "Everything is a trait" approach cant be done○ Be aware of type inference in @Configuration beantrait Serviceclass ServiceImpl extends Service@Configurationclass ServiceContext {@Bean def service: Service = new ServiceImpl}Spring with scala
  17. 17. ● DI fits almost nicely with scala● Rich spring templates libraries.Spring with scala
  18. 18. ● DI fits almost nicely with scala● Rich spring templates libraries.springLdapTemplate.authenticate("user", "*", "password", newAuthenticationErrorCallback {def execute(e: Exception) {log.error(e)}})Spring with scala
  19. 19. ● DI fits almost nicely with scala● Rich spring templates libraries.springLdapTemplate.authenticate("user", "*", "password", newAuthenticationErrorCallback {def execute(e: Exception) {log.error(e)}})Spring with scala
  20. 20. ● DI fits almost nicely with scala● Rich spring templates libraries.springLdapTemplate.authenticate("user", "*", "password", newAuthenticationErrorCallback {def execute(e: Exception) {log.error(e)}})springLdapTemplate.authenticate("user", "*", "password", log.error(_))Spring with scala
  21. 21. ● 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)}}Spring with scala
  22. 22. ● DI fits almost nicely with scala● Rich spring templates libraries.● AOP for free (almost)Spring with scala
  23. 23. ● DI fits almost nicely with scala● Rich spring templates libraries.● AOP for free (almost)○ Be aware of naming in debug infodef findUsers(projectId: Int) {dao.findUsers(projectId)}def findUsers2(projectId: Int) {dao.allUsers().filter(_.projectId == projectId)}Spring with scala
  24. 24. ● DI fits almost nicely with scala● Rich spring templates libraries.● AOP for free (almost)○ Be aware of naming in debug infodef findUsers(projectId: Int) { // debugIfo: name "projectId"dao.findUsers(projectId)}def findUsers2(projectId: Int) { // debugInfo: name "projectId$"dao.allUsers().filter(_.projectId == projectId)}Spring with scala
  25. 25. ● DI fits almost nicely with scala● Rich spring templates libraries.● AOP for free (almost)● Spring security just worksSpring with scala
  26. 26. Persistence layer: Squeryl
  27. 27. ● Lightweight ORM written in scalaSqueryl
  28. 28. ● Lightweight ORM written in scalaSquerylclass Workflow(override val id: Int) extends KeyedEntity[Int]
  29. 29. ● Lightweight ORM written in scalaSquerylclass Workflow(override val id: Int) extends KeyedEntity[Int]object GS extends Schema {val workflows = table[Workflow]}
  30. 30. ● Lightweight ORM written in scalaSquerylclass 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. ● Lightweight ORM written in scala○ First class support for scala collections, options, etcSqueryl
  32. 32. ● Lightweight ORM written in scala○ First class support for scala collections, options, etc○ Integrates with spring transaction management(not out of the box)Squeryl
  33. 33. ● Lightweight ORM written in scala○ First class support for scala collections, options, etc○ Integrates with spring transaction management(not out of the box)Squeryl@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 asHibernate doeshibernate squeryl
  35. 35. ● Lightweight ORM written in scala○ Likes heap in the same proportion asHibernate does○ Lots of "black magic" in source codeSqueryl
  36. 36. ● Lightweight ORM written in scala● Internal scala DSL for writing queries○ Type safe queries - compile time syntax checkSqueryl
  37. 37. ● Lightweight ORM written in scala● Internal scala DSL for writing queries○ Lots of "black magic" in source codeSqueryl
  38. 38. ● Lightweight ORM written in scala● Internal scala DSL for writing queries○ Lots of "black magic" in source code○ Fallback on native sql is not easySqueryl
  39. 39. ● 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 andincreases compilation timeSqueryl
  40. 40. ● 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 andincrease compilation time○ The approach is somewhat flawed (opinion)Squeryl
  41. 41. Web layer: Spring MVClift-jsonscala magic
  42. 42. ● RESTfull web servicesWeb layercase 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))@ResponseBodydef create(@RequestBody @Valid request: User): User = userService.create(request)}
  43. 43. ● RESTfull web services● Easy to make Hypermedia REST withimplicitsWeb layer@Controller@RequestMapping(Array("/rest/users"))class UsersController {import com.griddynamics.genesis.rest.links.Hypermedia._@RequestMapping(method = Array(RequestMethod.POST))@ResponseBodydef create(@RequestBody @Valid request: User): Hypermedia[User] = {userService.create(request).withLink("/rest/users", LinkType.SELF)}
  44. 44. Couple of words aboutAKKA
  45. 45. Ехал Акка через АккаСмотрит Акка в Акка АккаСунул Акка Акка в АккаАкка Акка Акка Акка ** Ode to Akka in russian
  46. 46. Greatest challenge:
  47. 47. Greatest challenge:People
  48. 48. ● Hiring is hardChallenges
  49. 49. ● Hiring is hard○ Scala is a talent attractionChallenges
  50. 50. ● Hiring is hard○ Scala is a talent attraction○ In avg: 0.5 interview per monthChallenges
  51. 51. ● Hiring is hard● Settling team standards and codeconventionChallenges
  52. 52. ● Hiring is hard● Settling team standards and codeconvention○ Tools are not there yetChallenges
  53. 53. ● Hiring is hard● Settling team standards and codeconvention○ Tools are not there yet○ Between "OCaml" and "Java" firesChallenges
  54. 54. ● Hiring is hard● Settling team standards and codeconvention○ Tools are not there yet○ Between "OCaml" and "Java" fires○ "Effective scala" by Twitter and "Scala style guide"might help (a bit)Challenges
  55. 55. The greatest code-review mystery ofall timesif (option.isDefined) {..}option.foreach { .. }option match {case Some(x) => ..case None => ..}How to deal with scala.Option?
  56. 56. The greatest code-review mystery ofall timesif (option.isDefined) {..}option.foreach { .. }option match {case Some(x) => ..case None => ..}How to deal with scala.Option?
  57. 57. Recruiting javadevelopers
  58. 58. aka
  59. 59. 5 stages of grief
  60. 60. 1. Denial2. Anger3. Bargaining4. Depression5. Acceptance5 stages of grief
  61. 61. 1. Denial2. Anger3. Bargaining4. Depression5. Acceptance5 stages of grief
  62. 62. 1. Denial2. Anger3. Bargaining4. Depression5. Acceptance5 stages of grief
  63. 63. 1. Denial2. Anger3. Bargaining4. Depression5. Acceptance5 stages of grief
  64. 64. 1. Denial2. Anger3. Bargaining4. Depression5. Acceptance5 stages of grief
  65. 65. 1. Denial2. Anger3. Bargaining4. Depression5. Acceptance5 stages of grief

×