Top Banner
Reasonable RPC with Remotely ScalaDays, 18th March 2015 Rúnar Bjarnason Tim Perrett
39

Reasonable RPC with Remotely

Jul 16, 2015

Download

Technology

Timothy Perrett
Welcome message from author
This document is posted to help you gain knowledge. Please leave a comment to let me know what you think about it! Share it to your friends and learn new things together.
Transcript
Page 1: Reasonable RPC with Remotely

Reasonable RPC with Remotely

ScalaDays, 18th March 2015

Rúnar Bjarnason Tim Perrett

Page 2: Reasonable RPC with Remotely
Page 3: Reasonable RPC with Remotely

Existing solutionsNo panaceas. Just tradeoffs.

Page 4: Reasonable RPC with Remotely

Monolith

• All functionality in a single binary

• Doesn’t scale

• Difficult to evolve and maintain

Page 5: Reasonable RPC with Remotely

Broker pattern

• Message bus or broker mediates between services

• Single point of failure/integration

• If broker goes down, the whole system is down

Page 6: Reasonable RPC with Remotely

Message-passing

• Lightweight and inexpensive

• Reliable and scales well

• Discovery is a pain

Page 7: Reasonable RPC with Remotely

Message passing solutions

• Finagle

• Thrift

• Akka

• HTTP*(JSON+XML)/REST

Page 8: Reasonable RPC with Remotely

Finagle

• Imperative API

• No reuse

• Too powerful

• No higher-order constructs

Page 9: Reasonable RPC with Remotely

Thrift

• All of the problems with Finagle

• Tough tooling

• Documentation is lacking

• No formal spec for wire format

Page 10: Reasonable RPC with Remotely

Akka

• Too powerful

• Untyped

• Actor system API bleeds to the outside

• Behavior of complex systems is unreasonable

Page 11: Reasonable RPC with Remotely

HTTP*(JSON+XML)/REST

• Unproductive, developer time wasted

• Marshalling/unmarshalling

• Defining HTTP endpoints and using HTTP clients

• Resources wasted on HTTP layer and parsing

• Does what we want, but at tremendous cost

Page 12: Reasonable RPC with Remotely

Our VisionProductivity, Safety, Reuse

Page 13: Reasonable RPC with Remotely

Productivity

Don’t want to think about:

• HTTP protocol specifics

• Every possible failure mode

• Serialization format

• Compatibility

Page 14: Reasonable RPC with Remotely

Safety

• Ad-hoc evolution doesn’t scale

• Incompatibilities should be compile-time failures

• Fail as early as possible

Page 15: Reasonable RPC with Remotely

Reuse

• Use an actual programming language

• Build protocols from modular primitives

• Compose large protocols from small ones

Page 16: Reasonable RPC with Remotely

RemotelyRPC for reasonable people

Page 17: Reasonable RPC with Remotely

RemotelyRPC for reasonable people

BETA

Page 18: Reasonable RPC with Remotely

Remotely

• Pilot for Verizon open-source

• Taking the time to build exactly what we want to use

• You can use it too!

Page 19: Reasonable RPC with Remotely

Remote call

val x = factorial(9)

Page 20: Reasonable RPC with Remotely

Remote reference

factorial: Remote[Int => Int]

Page 21: Reasonable RPC with Remotely

Applying a remote function

val x: Remote[Int] = factorial(9)

Page 22: Reasonable RPC with Remotely

Getting a response

val x: Response[Int] = factorial(9).run(endpoint)

Page 23: Reasonable RPC with Remotely

Response monad

type Demo[A] = Kleisli[Response, Endpoint, A]

implicit def remoteToK[A](r: Remote[A]): Demo[A] = Kleisli.ask[Response, Endpoint].flatMapK(r.run)

def call: Demo[(Movie,List[Actor])] = for { a <- MovieClient.getMovie("m2") b <- MovieClient.getActors(a) } yield (a,b)

Page 24: Reasonable RPC with Remotely

Running Responses

val address = new InetSocketAddress("10.1.0.1",8080)

val exe: Task[(Movie,List[Actor])] = for { transport <- NettyTransport.single(address) endpoint = Endpoint.single(transport) output <- call(endpoint)(Context.empty) _ <- transport.shutdown } yield output

val (movie, actors) = exe.run

Page 25: Reasonable RPC with Remotely

Demo

Page 26: Reasonable RPC with Remotely

Feature Pageant

Page 27: Reasonable RPC with Remotely

Binary Codecs

• Fast, lightweight binary serialization • Built on scodec • Ships with codecs for standard Scala types • Easy to make codecs for your own types

• Future goal: Fully automate codec-creation

Page 28: Reasonable RPC with Remotely

Pluggable transports

• Uses Netty 4 out of the box

• Akka I/O

• Netty 3

• ØMQ

Page 29: Reasonable RPC with Remotely

Pluggable transports

type Handler = Process[Task,BitVector] => Process[Task,BitVector]

Page 30: Reasonable RPC with Remotely

Endpoints

case class Endpoint( connections: Process[Task,Handler])

Page 31: Reasonable RPC with Remotely

Endpoint combinators

def circuitBroken: (Duration,Int,Endpoint) => Endpoint

def failoverChain: (Duration,Process[Task,Endpoint]) => Endpoint

Page 32: Reasonable RPC with Remotely

Context-passing

• Context provides arbitrary container for experiment propagation.

• Every request tagged with a UUID.

• Contains stack of request UUIDs.

• highlights the “path” through the system request graph when debugging.

Page 33: Reasonable RPC with Remotely

Pluggable monitoring

• Report round-trip latency timing.

• Trace every request uniquely.

• Trace the request stack entirely.

• Bring your own by implementing the Monitoring trait.

• Uses println out of the box.

Page 34: Reasonable RPC with Remotely

Capability checking

• Protocol versioning over time inevitable

• Determine client/server compatibility before establishing connection

Page 35: Reasonable RPC with Remotely

How fast is it?

• Went from 56 ms to 32 ms(production payload)

• In benchmarks on modest hardware

• Min: ~400 μs

• Mean: ~1.5 ms

• Throughput is an issue currently

Page 36: Reasonable RPC with Remotely

Spray I/O Netty 4

Page 37: Reasonable RPC with Remotely

Future work

• Prettier API

• Drastically improve throughput

• Extensible protocol language

• More built-ins for e.g. server-side map and flatMap

• Remote polymorphic functions

Page 38: Reasonable RPC with Remotely

Summary

• Remotely is productive

• It’s safe

• It promotes code reuse

• You can contribute!

Page 39: Reasonable RPC with Remotely

EOF@runarorama @timperrett

github.com/oncue/remotely github.com/oncue/remotely-demo