Переход на Scala: босиком по граблям
-
Upload
svetlana-bozhko -
Category
Technology
-
view
802 -
download
4
Transcript of Переход на Scala: босиком по граблям
Переход на Scala: босиком по граблям
Data Processing Team
Java / Scala / Clojure / Groovy / ?
JVM
“Во-первых, это красиво…” *
Почему Scala?
akka-http / spray / finagle / play
REST & HTTP
Spray
Implicits
def strangeIdea(n: Int)(implicit s: String) = s * n
package spray.routing
...
trait HttpServiceBase extends Directives {
/** * Supplies the actor behavior for executing the given route. */ def runRoute(route: Route)(implicit eh: ExceptionHandler, rh: RejectionHandler, ac: ActorContext, rs: RoutingSettings, log: LoggingContext): Actor.Receive = {...}
def createOrUpdateCookieProfileRoute(): Route = post { pathPrefix(ApiVersion) { pathPrefix("cookies" / Segment) { cookieId => path("cookieProfiles" / IntNumber) { trackingSetupId => parameters('cookieSetTime.as[DateTime].?, 'cookieLastSeenTime.as[DateTime].?) { (cookieSetTime, cookieLastSeenTime) => entity(as[CookieProfile]) { cookieProfile => traceName("POST COOKIE PROFILE") { ctx => val serviceActor: ActorRef = newStorageServiceActor() val message = MergeCookieProfile(ctx, cookieProfile, cookieSetTime, cookieLastSeenTime) serviceActor.tell(message, ActorRef.noSender) } } } } } } }
trait JsonSerializerSupport {
implicit val formats = DefaultFormats ++ BinaryTypeSerializers.all ++ JodaTimeSerializers.all}
https://github.com/gettyimages/spray-swagger
Swagger
@ApiOperation( httpMethod = "POST", value = "Create/Update CookieProfile by cookieId and trackingSetupId", notes = "Creates new CookieProfile if it doesn't exists or updates old one if it exists in storage.”) @ApiImplicitParams(Array( new ApiImplicitParam( name = Fields.CookieId, value = Description.CookieId, required = true, dataType = DataTypes.String, paramType = ParamType.Path), new ApiImplicitParam( name = Fields.TrackingSetupId, value = Description.TrackingSetupId, required = true, dataType = DataTypes.Integer, paramType = ParamType.Path), new ApiImplicitParam( name = Fields.CookieSetTime, value = Description.CookieSetTime, dataType = DataTypes.String, paramType = ParamType.Query), new ApiImplicitParam( name = Fields.CookieLastSeenTime, value = Description.CookieLastSeenTime, dataType = DataTypes.String, paramType = ParamType.Query), new ApiImplicitParam( name = Fields.Body, value = Description.Body, required = true, dataType = DataTypes.CookieProfile, paramType = ParamType.Body))) @ApiResponses(Array( new ApiResponse(code = 200, message = Responses.Ok, response = classOf[SuccessResponse]), new ApiResponse(code = 400, message = Responses.BadRequest, response = classOf[ErrorResponse]), new ApiResponse(code = 500, message = Responses.InternalError, response = classOf[ErrorResponse]), new ApiResponse(code = 503, message = Responses.ServiceUnavailable))) @Path("/{cookieId}/cookieProfiles/{trackingSetupId}")
Akka
“blocking problem”
Shared state
Как это тестировать?
test("return 404 code for not existing cookie with cookieProfiles") { Get("/v1/cookies/777/cookieProfiles") ~> route ~> check { handled should be(right = true) response.status should be(StatusCodes.NotFound) } }
http://gatling.io/
Нагрузочные тесты
DevOps
Отличное решение
Kamonhttp://kamon.io/
Если вы сами готовы его допиливать
ELK & Grafana
Maven & sbt
Что бы могло пойти не так?
Итак, вы решили перейти на Scala
Сложность и академичность
IDE
OOP & FP
Explicit is better than implicit
Много споров о стиле
Take it easy
Плавный переход к Scala
Инкрементальное внедрение языка
Постоянное изучение
“Технологии идеальны, а люди – *удаки” **
* — Старый анекдот** — Baruch Sadogursky aka @jbaruch
Источники: