Skip to content

Instantly share code, notes, and snippets.

@pvorb
Forked from gangstead/notes.md
Created December 18, 2014 01:43
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save pvorb/b93129c0476698623e20 to your computer and use it in GitHub Desktop.
Save pvorb/b93129c0476698623e20 to your computer and use it in GitHub Desktop.

Typesafe webinar notes: Spray & Akka HTTP

Presenter - Mathias Doenitz

Spray.io

  • embeddable http stack built on Akka actors
  • Just an HTTP integration layer, not for building full web apps
  • Server & client side

Spray features

  • Immutable case-class based http model
  • Fast, lightweight http client & server
  • Powerful DSL for server side API definition
  • Async, non-blocking, actor-friendly, modular, testable
  • Completely built in Scala (only such framework Mathias knows about)

Spray weaknesses

  • Chunked requests handling clunky (I would say doesn't work)
  • Large messages entities can be difficult
  • High-level routing DSL sometimes unintuitive, some mistakes not caught at compile time
  • Deep implicit structures, sometimes hard to debug
  • Missing features (notably websockets)

Akka-http is Spray 2.0

  • Addresses weaknesses
  • Java APIs
  • Simplified module structure
  • Core improvement : now based on Reactive Streams

Reactive Streams: Motivation

  • A Spray proxy that is receiving a file from a fast connection (like a LAN) and sending it to a slower connection (like a WAN, internet) lacks a way to provide back pressure
  • Stages in the pipeline need a way to push back (back pressure) to throttle previous, faster steps
  • Pushing back up the stages just moves the problem up the pipeline. We need the problem to be moved all the way back to the beginning.
  • Common solution: ACKing works, but is brittle, doesn't compose and isn't DRY

Reactive Streams address the problem of how to transfer data asynchronously between data producer and data consumer. Existing solutions:

  • Consumer Pulls data from Producer.
  • Blocking, not good for scaling
  • But the blocking is minimized if producer is faster than consumer, but you can't always ensure that
  • Producer Push data to Consumer whenever data becomes available
  • Straight forward, good performance
  • Only works reliably when consumer is faster than producer, otherwise leads to buffering
  • Dynamic push/pull two step process
  • Consumer signals demand (ie gie me 5 more)
  • Producer Pushes elements when available, but never more than requested
  • Can run in bounded memory, can increase machine utilisation since we don't need "headspace"

Now in the pipeline information flows in both directions. Signals for demand go one direction and data gets pushed the other direction. TCP semantically works in the same way and provides the back pressure.

Reactive Streams

  • Pipeline processing "done right"
  • Focus: define passing of data across an async boundary
  • Implementations provide DSLs for composable stream transformations
  • Many use cases
  • Joint effort of Netflix (video streams), Twitter (tweet streams), Red Hat, Pivotal & Typesafe

Akka-stream: basic concepts

  • Just one implementation of Reactive Streams
  • Most complete one in Scala
  • Source[T]: open end of pipeline producing Ts
  • Sink[T]: end-piece for consuming Ts
  • Flow[A,B]: an unconnected piece of pipeline
  • Generally, all abstractions are re-usable
  • "Materialization" : The process of starting an actual stream instance
  • So far this is not http specific. That's where Akka-http comes in.

Streams in Akka-http

  • Requests on one HTTP connection
  • Responses on one HTTP connectoin
  • Chunks of a chunked message
  • Bytes of a message entity
  • For a large, unchunked message

[example code]

  • Setting up the Server and Client transport layers with Flows (Akka-streams) looks a lot different from Spray
  • The HttpRequest is very similar to that from Spray
  • Now has a Chunked type of Http Entity

Benefits over Spray Design

  • Properly typed model for requests, responses and nested entities
  • Old model was a bunch of stuff crammed under one roof
  • Entities can have arbitrary size
  • Chunks no on an inner level, below the messages
  • Can now receive message headers before the entity
  • Not possible in Spray
  • Steven says : this is huge for performance

Akka-http module Structure

  • akka-http-core
  • http model (spray-http)
  • low-level stack (spray-can)
  • akka-http
  • (un)marshalling, (de)compression (spray-httpx)
  • Routing DSLs (spray-routing)
  • akka-http-testkit (spray-testkit)
  • No more spray-servlet (for now)
  • Steven says : (for now) sounds like (forever) since Play also doesn't seem to be coming back to running in a Servlet in favor of pushing the native stack

Roadmap

  • Finalize Reactive Streams API
  • Finish new akka modules
  • Add websockets support (client & server side)
  • Move Play onto akka-http (incrementally)
  • Play wants to move to websockets, so that's necessary before moving onto Play

Q & A

  • I asked about Spray-json going forward and he gave a long answer that implied it was going away. Well not really going away, but isn't going to be worked on in favor of doing something to unify all the myriad Json serliazation libraries.
  • Going forward Spray will only have support releases/patches, no more major releases
  • There are plans to integrate the overlap between Akka-streams and Spark. No definite plans, but Mathias is sure it will happen
  • How hard is it going to be to migrate? Relatively easy. There will be a migration guide.
  • Actors are lower level than streams. Streams are on the business level. There will be some interoperability such as an Actor that can act as a Source of a stream.
  • Streams api will have things that aren't possible with the collections api. Example: group within 1 second. Transform streams of events into stream of list of events.
  • There hasn't been any time spent on performance optimization. Right now Akka-http is a lot slower than Spray, but Mathias thinks it can be at least as fast and sees no reason why it won't be faster.
  • There is https support. Right now it's just a basic version, but it is crucial and there are people working on it.
  • Question about using Actors to parallelize slow stages of pipeline. Confusing answer: not a lot, depends on the application. There isn't a lot of built in stuff for that, but if you are good enough with Actors anything is possible.
  • How long will Spray be maintained and supported? He thinks at least a year, but that's ultimately up to Typesafe.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment