69

Rafael Bagmanov «Scala in a wild enterprise»

Embed Size (px)

DESCRIPTION

 

Citation preview

Page 1: Rafael Bagmanov «Scala in a wild enterprise»
Page 2: Rafael Bagmanov «Scala in a wild enterprise»
Page 3: Rafael Bagmanov «Scala in a wild enterprise»

Scala in a wild enterpriseRafael Bagmanov ( Grid Dynamics )

the?

Page 4: Rafael Bagmanov «Scala in a wild enterprise»

In what use cases (types of applications) does Scala make the least sense?

Page 5: Rafael Bagmanov «Scala in a wild enterprise»

"Database front end, CRUD apps.

Most of the boring apps that are built with Struts and Spring"

David Pollak "Barriers to scala adoption" Infoq.com

Page 6: Rafael Bagmanov «Scala in a wild enterprise»
Page 7: Rafael Bagmanov «Scala in a wild enterprise»

OpenGenesisgithub.com/griddynamics/OpenGenesis

Page 8: Rafael Bagmanov «Scala in a wild enterprise»

● 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

OpenGenesisDeployment orchestration tool

Page 9: Rafael Bagmanov «Scala in a wild enterprise»

● 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

Enterprise characteristics

Page 10: Rafael Bagmanov «Scala in a wild enterprise»

Typical "lightweight" j2ee stack

Web layer

Service layer

Data access layer

DB

Spring MVC

Spring

JPA

Page 11: Rafael Bagmanov «Scala in a wild enterprise»

j2ee stack. Scala edition

Web layer

Service layer

Data access layer

DB

Spring MVC + scala magic

Spring + scala implicits

JPA Squeryl

Page 12: Rafael Bagmanov «Scala in a wild enterprise»

j2ee stack. Scala edition

Web layer

Service layer

Data access layer

DB

Spring MVC

Spring

Squeryl

WAR

Page 13: Rafael Bagmanov «Scala in a wild enterprise»

j2ee stack. Scala edition + scala goodness

Web layer

Service layer

Data access layer

DB

Spring MVC

Spring

Squeryl

Workflow distributed engine

Akka

WAR

Page 14: Rafael Bagmanov «Scala in a wild enterprise»

Service layer: Spring

Page 15: Rafael Bagmanov «Scala in a wild enterprise»

● DI fits almost nicely with scala

Spring with scala

Page 16: Rafael Bagmanov «Scala in a wild enterprise»

● DI fits almost nicely with scalaclass GenesisRestController {

@Autowired var genesisService: GenesisService = _

}

class GenesisRestController {

@BeanProperty var genesisService: GenesisService = _

}

class GenesisRestController (genesisService: GenesisService) {}

Spring with scala

Page 17: Rafael Bagmanov «Scala in a wild enterprise»

● DI fits almost nicely with scala○ "Everything is a trait" approach can't be done

Spring with scala

Page 18: Rafael Bagmanov «Scala in a wild enterprise»

● DI fits almost nicely with scala○ "Everything is a trait" approach can't be done

○ Be aware of type inference in @Configuration beantrait Service

class ServiceImpl extends Service

@Configuration

class ServiceContext {

@Bean def service = new ServiceImpl

}

Spring with scala

Page 19: Rafael Bagmanov «Scala in a wild enterprise»

● DI fits almost nicely with scala○ "Everything is a trait" approach can't be done

○ Be aware of type inference in @Configuration beantrait Service

class ServiceImpl extends Service

@Configuration

class ServiceContext {

@Bean def service: Service = new ServiceImpl

}

Spring with scala

Page 20: Rafael Bagmanov «Scala in a wild enterprise»

● DI fits almost nicely with scala

● Rich spring templates libraries.

Spring with scala

Page 21: Rafael Bagmanov «Scala in a wild enterprise»

● DI fits almost nicely with scala

● Rich spring templates libraries.

springLdapTemplate.authenticate("user", "*", "password", new

AuthenticationErrorCallback {

def execute(e: Exception) {log.error(e)}

})

Spring with scala

Page 22: Rafael Bagmanov «Scala in a wild enterprise»

● DI fits almost nicely with scala

● Rich spring templates libraries.

springLdapTemplate.authenticate("user", "*", "password", new

AuthenticationErrorCallback {

def execute(e: Exception) {log.error(e)}

})

Spring with scala

Page 23: Rafael Bagmanov «Scala in a wild enterprise»

● 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(_))

Spring with scala

Page 24: Rafael Bagmanov «Scala in a wild enterprise»

● 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

Page 25: Rafael Bagmanov «Scala in a wild enterprise»

● DI fits almost nicely with scala

● Rich spring templates libraries.

● AOP for free (almost)

Spring with scala

Page 26: Rafael Bagmanov «Scala in a wild enterprise»

● 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)

}

Spring with scala

Page 27: Rafael Bagmanov «Scala in a wild enterprise»

● 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)

}

Spring with scala

Page 28: Rafael Bagmanov «Scala in a wild enterprise»

● DI fits almost nicely with scala

● Rich spring templates libraries.

● AOP for free (almost)

● Spring security just works

Spring with scala

Page 29: Rafael Bagmanov «Scala in a wild enterprise»

Persistence layer: Squeryl

Page 30: Rafael Bagmanov «Scala in a wild enterprise»

● Lightweight ORM written in scala

Squeryl

Page 31: Rafael Bagmanov «Scala in a wild enterprise»

● Lightweight ORM written in scala

Squeryl

class Workflow(override val id: Int) extends KeyedEntity[Int]

Page 32: Rafael Bagmanov «Scala in a wild enterprise»

● Lightweight ORM written in scala

Squeryl

class Workflow(override val id: Int) extends KeyedEntity[Int]

object GS extends Schema {

val workflows = table[Workflow]

}

Page 33: Rafael Bagmanov «Scala in a wild enterprise»

● Lightweight ORM written in scala

Squeryl

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)

)

Page 34: Rafael Bagmanov «Scala in a wild enterprise»

● Lightweight ORM written in scala○ First class support for scala collections, options, etc

Squeryl

Page 35: Rafael Bagmanov «Scala in a wild enterprise»

● Lightweight ORM written in scala○ First class support for scala collections, options, etc

○ Integrates with spring transaction management

(not out of the box)

Squeryl

Page 36: Rafael Bagmanov «Scala in a wild enterprise»

● 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)

)

Page 37: Rafael Bagmanov «Scala in a wild enterprise»

Squeryl

● Lightweight ORM written in scala

○ Likes heap in the same proportion as Hibernate does

hibernate squeryl

Page 38: Rafael Bagmanov «Scala in a wild enterprise»

● Lightweight ORM written in scala

○ Likes heap in the same proportion as Hibernate does

○ Lot's of "black magic" in source code

Squeryl

Page 39: Rafael Bagmanov «Scala in a wild enterprise»

● Lightweight ORM written in scala

● Internal scala DSL for writing queries○ Type safe queries - compile time syntax check

Squeryl

Page 40: Rafael Bagmanov «Scala in a wild enterprise»

● Lightweight ORM written in scala

● Internal scala DSL for writing queries○ Lot's of "black magic" in source code

Squeryl

Page 41: Rafael Bagmanov «Scala in a wild enterprise»

● Lightweight ORM written in scala

● Internal scala DSL for writing queries○ Lot's of "black magic" in source code

○ Fallback on native sql is not easy

Squeryl

Page 42: Rafael Bagmanov «Scala in a wild enterprise»

● Lightweight ORM written in scala

● Internal scala DSL for writing queries○ Lot's of "black magic" in source code

○ Fallback on native sql is not easy

○ Lots of implicits drives IDE crazy and increases compilation time

Squeryl

Page 43: Rafael Bagmanov «Scala in a wild enterprise»

● Lightweight ORM written in scala

● Internal scala DSL for writing queries○ Lot's 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)

Squeryl

Page 44: Rafael Bagmanov «Scala in a wild enterprise»

Web layer: Spring MVClift-json

scala magic

Page 45: Rafael Bagmanov «Scala in a wild enterprise»

● RESTfull web services

Web layer

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)

}

Page 46: Rafael Bagmanov «Scala in a wild enterprise»

● RESTfull web services

● Easy to make Hypermedia REST with

implicits

Web layer

@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)

}

Page 47: Rafael Bagmanov «Scala in a wild enterprise»

Couple of words aboutAKKA

Page 48: Rafael Bagmanov «Scala in a wild enterprise»

Ехал Акка через Акка

Смотрит Акка в Акка Акка

Сунул Акка Акка в Акка

Акка Акка Акка Акка *

* Ode to Akka in russian

Page 49: Rafael Bagmanov «Scala in a wild enterprise»

Greatest challenge:

Page 50: Rafael Bagmanov «Scala in a wild enterprise»

Greatest challenge:People

Page 51: Rafael Bagmanov «Scala in a wild enterprise»

● Hiring is hard

Challenges

Page 52: Rafael Bagmanov «Scala in a wild enterprise»

● Hiring is hard○ Scala is a talent attraction

Challenges

Page 53: Rafael Bagmanov «Scala in a wild enterprise»

● Hiring is hard○ Scala is a talent attraction

○ In avg: 0.5 interview per month

Challenges

Page 54: Rafael Bagmanov «Scala in a wild enterprise»

● Hiring is hard

● Settling team standards and code

convention

Challenges

Page 55: Rafael Bagmanov «Scala in a wild enterprise»

● Hiring is hard

● Settling team standards and code

convention○ Tools are not there yet

Challenges

Page 56: Rafael Bagmanov «Scala in a wild enterprise»

● Hiring is hard

● Settling team standards and code

convention○ Tools are not there yet

○ Between "OCaml" and "Java" fires

Challenges

Page 57: Rafael Bagmanov «Scala in a wild enterprise»

● 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)

Challenges

Page 58: Rafael Bagmanov «Scala in a wild enterprise»

The greatest code-review mystery of all times

if (option.isDefined) {

..

}

option.foreach { .. }

option match { case Some(x) => .. case None => ..}

How to deal with scala.Option

?

Page 59: Rafael Bagmanov «Scala in a wild enterprise»

The greatest code-review mystery of all times

if (option.isDefined) {

..

}

option.foreach { .. }

option match { case Some(x) => .. case None => ..}

How to deal with scala.Option

?

Page 60: Rafael Bagmanov «Scala in a wild enterprise»

Recruiting java developers

Page 61: Rafael Bagmanov «Scala in a wild enterprise»

aka

Page 62: Rafael Bagmanov «Scala in a wild enterprise»

5 stages of grief

Page 63: Rafael Bagmanov «Scala in a wild enterprise»

1. Denial

2. Anger

3. Bargaining

4. Depression

5. Acceptance

5 stages of grief

Page 64: Rafael Bagmanov «Scala in a wild enterprise»

1. Denial

2. Anger

3. Bargaining

4. Depression

5. Acceptance

5 stages of grief

Page 65: Rafael Bagmanov «Scala in a wild enterprise»

1. Denial

2. Anger

3. Bargaining

4. Depression

5. Acceptance

5 stages of grief

Page 66: Rafael Bagmanov «Scala in a wild enterprise»

1. Denial

2. Anger

3. Bargaining

4. Depression

5. Acceptance

5 stages of grief

Page 67: Rafael Bagmanov «Scala in a wild enterprise»

1. Denial

2. Anger

3. Bargaining

4. Depression

5. Acceptance

5 stages of grief

Page 68: Rafael Bagmanov «Scala in a wild enterprise»

1. Denial

2. Anger

3. Bargaining

4. Depression

5. Acceptance

5 stages of grief

Page 69: Rafael Bagmanov «Scala in a wild enterprise»