finagle your own codec - scala by the bay 2016
TRANSCRIPT
![Page 1: Finagle Your Own Codec - Scala By The Bay 2016](https://reader035.vdocuments.site/reader035/viewer/2022070602/587942421a28ab23468b66c9/html5/thumbnails/1.jpg)
Copyright 2016 Tendril, Inc. All rights reserved.
FINAGLE YOUR OWN CODEC
Extending Finagle with Protocol Buffers
![Page 2: Finagle Your Own Codec - Scala By The Bay 2016](https://reader035.vdocuments.site/reader035/viewer/2022070602/587942421a28ab23468b66c9/html5/thumbnails/2.jpg)
Copyright 2016 Tendril, Inc. All rights reserved.Scalae By The Bay | November 11, 2016
AgendaINTRODUCTION
2
Finagle Protocol Concepts
Finagle ProtobufLessons and Recommendations
![Page 3: Finagle Your Own Codec - Scala By The Bay 2016](https://reader035.vdocuments.site/reader035/viewer/2022070602/587942421a28ab23468b66c9/html5/thumbnails/3.jpg)
Copyright 2016 Tendril, Inc. All rights reserved.
FINAGLE PROTOCOL CONCEPTS
3
![Page 4: Finagle Your Own Codec - Scala By The Bay 2016](https://reader035.vdocuments.site/reader035/viewer/2022070602/587942421a28ab23468b66c9/html5/thumbnails/4.jpg)
Copyright 2016 Tendril, Inc. All rights reserved.Scalae By The Bay | November 11, 2016
WHAT IS FINAGLE ANYWAY?
Finagle is an extensible RPC system for the JVM, used to construct high-concurrency servers.
…Most of Finagle’s code is protocol agnostic, simplifying the
implementation of new protocols.
http://twitter.github.io/finagle/(emphasis mine)
4
![Page 5: Finagle Your Own Codec - Scala By The Bay 2016](https://reader035.vdocuments.site/reader035/viewer/2022070602/587942421a28ab23468b66c9/html5/thumbnails/5.jpg)
Copyright 2016 Tendril, Inc. All rights reserved.Scalae By The Bay | November 11, 2016
Why RPC and Binary Formats?
• RPC vs REST• Operation-oriented• No mapping to fixed verbs
• Binary formats vs JSON• Smaller message size• Serialization performance• Versioning and other semantics
• Interface Definition Language (IDL)• Available operations• Message schema
CONCEPTS
5
![Page 6: Finagle Your Own Codec - Scala By The Bay 2016](https://reader035.vdocuments.site/reader035/viewer/2022070602/587942421a28ab23468b66c9/html5/thumbnails/6.jpg)
Copyright 2016 Tendril, Inc. All rights reserved.Scalae By The Bay | November 11, 2016
What is a Protocol?
• Merriam-Webstera set of conventions governing the treatment and especially the formatting of data in an electronic communications system
• A protocol includes• Codec • Dispatchers • Client and server configuration and initialization • Error handling • Integration with code generators or compilers
CONCEPTS
6
![Page 7: Finagle Your Own Codec - Scala By The Bay 2016](https://reader035.vdocuments.site/reader035/viewer/2022070602/587942421a28ab23468b66c9/html5/thumbnails/7.jpg)
Copyright 2016 Tendril, Inc. All rights reserved.Scalae By The Bay | November 11, 2016
What is a Codec
• Codec trait• Defines encoding/decoding
• Interface to Netty channel pipeline• Modify the service filter stack• Server and Client sides
• Symmetric – same objects both sides?• Request and Response – same encoding both ways?
• CodecFactory relates client and server
CONCEPTS
7
![Page 8: Finagle Your Own Codec - Scala By The Bay 2016](https://reader035.vdocuments.site/reader035/viewer/2022070602/587942421a28ab23468b66c9/html5/thumbnails/8.jpg)
Copyright 2016 Tendril, Inc. All rights reserved.Scalae By The Bay | November 11, 2016
End to End FlowCONCEPTS
8
Client ClientDispatch Encoder
Finagle/Netty
Decoder Service Dispatch
Service Impl
![Page 9: Finagle Your Own Codec - Scala By The Bay 2016](https://reader035.vdocuments.site/reader035/viewer/2022070602/587942421a28ab23468b66c9/html5/thumbnails/9.jpg)
Copyright 2016 Tendril, Inc. All rights reserved.Scalae By The Bay | November 11, 2016
Interfaces
• What sort of interface to expose?• Finagle interfaces – e.g. Service[Req,Resp]• Your protocol
• Thrift - special compiler – Scrooge • Protobuf - code generated by protoc
CONCEPTS
9
![Page 10: Finagle Your Own Codec - Scala By The Bay 2016](https://reader035.vdocuments.site/reader035/viewer/2022070602/587942421a28ab23468b66c9/html5/thumbnails/10.jpg)
Copyright 2016 Tendril, Inc. All rights reserved.Scalae By The Bay | November 11, 2016
Connection Handling
• Connection pooling• Connections created for requests• One connection == one active request• Reuse only after a request is done• Configuration of pool size limits, Etc
• Mux (connection multiplexing)• One connection used for many simultaneous requests• Match responses up with open requests• Simpler configuration model
CONCEPTS
10
![Page 11: Finagle Your Own Codec - Scala By The Bay 2016](https://reader035.vdocuments.site/reader035/viewer/2022070602/587942421a28ab23468b66c9/html5/thumbnails/11.jpg)
Copyright 2016 Tendril, Inc. All rights reserved.Scalae By The Bay | November 11, 2016
Service Stack
• Finagle services are created from a stack of components• Timeouts• Stats
• Stack API • Flexibility but complexity
• ClientBuilder / ServerBuilder• Simpler but limited• Provides basic stack
• ClientBuilder and ServerBuilder will be deprecated eventually
CONCEPTS
11
![Page 12: Finagle Your Own Codec - Scala By The Bay 2016](https://reader035.vdocuments.site/reader035/viewer/2022070602/587942421a28ab23468b66c9/html5/thumbnails/12.jpg)
Copyright 2016 Tendril, Inc. All rights reserved.Scalae By The Bay | November 11, 2016
Error Handling – Two Types of Errors
• Application• Something gone wrong in the service • Exception• Non-exceptional fail response
• Framework• Timeouts• Rejections• Uncaught exceptions
CONCEPTS
12
![Page 13: Finagle Your Own Codec - Scala By The Bay 2016](https://reader035.vdocuments.site/reader035/viewer/2022070602/587942421a28ab23468b66c9/html5/thumbnails/13.jpg)
Copyright 2016 Tendril, Inc. All rights reserved.Scalae By The Bay | November 11, 2016
Error Handling – Ways to Handle
• Protocol • E.g. Thrift has an exception type
• Transport • Error message is a certain type on the wire
• Application • User messages must include some room for errors
• How should exceptions be caught and mapped on the server?
• How should they map back on the client? • Same mechanism or different mechanisms for client and
server?
CONCEPTS
13
![Page 14: Finagle Your Own Codec - Scala By The Bay 2016](https://reader035.vdocuments.site/reader035/viewer/2022070602/587942421a28ab23468b66c9/html5/thumbnails/14.jpg)
Copyright 2016 Tendril, Inc. All rights reserved.
FINAGLE-PROTOBUF
14
![Page 15: Finagle Your Own Codec - Scala By The Bay 2016](https://reader035.vdocuments.site/reader035/viewer/2022070602/587942421a28ab23468b66c9/html5/thumbnails/15.jpg)
Copyright 2016 Tendril, Inc. All rights reserved.Scalae By The Bay | November 11, 2016
Protobuf Message IDL
message Echo { optional string phrase = 1; optional uint32 offset = 2; optional com.tendril.platform.common.Context context = 3;}
val echoMessage = Echo.newBuilder .setPhrase("myPhrase") .setOffset(0) .build
echoMessage.hasContext should be(false)
FINAGLE-PROTOBUF
15
![Page 16: Finagle Your Own Codec - Scala By The Bay 2016](https://reader035.vdocuments.site/reader035/viewer/2022070602/587942421a28ab23468b66c9/html5/thumbnails/16.jpg)
Copyright 2016 Tendril, Inc. All rights reserved.Scalae By The Bay | November 11, 2016
Protobuf Service IDLservice EchoService { rpc Echo (EchoRequest) returns (EchoResponse);}
public static abstract class EchoService implements com.google.protobuf.Service {… public interface Interface { public abstract void echo( com.google.protobuf.RpcController controller, Echo.EchoRequest request, com.google.protobuf.RpcCallback<Echo.EchoResponse> done); } …}
FINAGLE-PROTOBUF
16
![Page 17: Finagle Your Own Codec - Scala By The Bay 2016](https://reader035.vdocuments.site/reader035/viewer/2022070602/587942421a28ab23468b66c9/html5/thumbnails/17.jpg)
Copyright 2016 Tendril, Inc. All rights reserved.Scalae By The Bay | November 11, 2016
Request and Response
message EchoRequest { optional string phrase = 1;}
message EchoResponse { optional com.tendril.platform.common.Error error = 1; optional Echo echo = 2;}
FINAGLE-PROTOBUF
17
![Page 18: Finagle Your Own Codec - Scala By The Bay 2016](https://reader035.vdocuments.site/reader035/viewer/2022070602/587942421a28ab23468b66c9/html5/thumbnails/18.jpg)
Copyright 2016 Tendril, Inc. All rights reserved.Scalae By The Bay | November 11, 2016
Client Creation and Invocation
def buildEchoClient(port: Int, filters:SimpleFilter[ProtobufRequest,ProtobufResponse]*) (implicit factory: RpcFactory, executorService: ExecutorService, tracer: Tracer) = { val clientBuilder = ClientBuilder() …
val serviceStub = EchoService.newStub(null) .asInstanceOf[ {def newStub(channel: RpcChannel): EchoService}]
factory.createStub( … )}
val distributedEchoClient = buildEchoClient(distributedServerPort)val controller = factory.createController()val request = EchoRequest.newBuilder().setPhrase("Hello world”).build()val callback = new RpcCallback[EchoResponse] { … }distributedEchoClient.echo(controller, request, callback)
FINAGLE-PROTOBUF
18
![Page 19: Finagle Your Own Codec - Scala By The Bay 2016](https://reader035.vdocuments.site/reader035/viewer/2022070602/587942421a28ab23468b66c9/html5/thumbnails/19.jpg)
Copyright 2016 Tendril, Inc. All rights reserved.Scalae By The Bay | November 11, 2016
Client Creation and Dispatch
• RpcFactory – build stub• Stub
• Generated by protoc, implements RPC service interface• Delegates method calls to a channel
• RpcChannelImpl• Uses ClientBuilder to build the Finagle
Service[Request,Response]• callMethod() delegates to the service• When service future completes, calls or fails the callback
• Encoder• Method code from hashed method name
(SimpleMethodService)
FINAGLE-PROTOBUF
19
![Page 20: Finagle Your Own Codec - Scala By The Bay 2016](https://reader035.vdocuments.site/reader035/viewer/2022070602/587942421a28ab23468b66c9/html5/thumbnails/20.jpg)
Copyright 2016 Tendril, Inc. All rights reserved.
Service Creation
def buildEchoServer(port: Int, impl: EchoService.Interface, filters:SimpleFilter[ProtobufRequest,ProtobufResponse]*) (implicit factory: RpcFactory, executorService: ExecutorService, tracer: Tracer) = { val serverBuilder = ServerBuilder() ... factory.createServer( … )}
class ReverseEchoService extends EchoService.Interface { def echo(controller: RpcController, request: EchoRequest, callback: RpcCallback[EchoResponse]) { val response = EchoResponse.newBuilder.setPhrase(request.getPhrase.reverse).build callback.run(response) }}
FINAGLE-PROTOBUF
20Scalae By The Bay | November 11, 2016
![Page 21: Finagle Your Own Codec - Scala By The Bay 2016](https://reader035.vdocuments.site/reader035/viewer/2022070602/587942421a28ab23468b66c9/html5/thumbnails/21.jpg)
Copyright 2016 Tendril, Inc. All rights reserved.Scalae By The Bay | November 11, 2016
Service Creation and Dispatch
• RpcFactory – build service• Service implementation – implements protoc generated
interface• ServiceDispatcher
• Determine which method to call• Call method and fulfill Promise (Future returned to Finagle)
• RpcControl – failure and cancellation• RpcCallback[T] – run method
• One instance for [Response], one for [Throwable]• In practice we wrap this behind Guava ListenableFuture
interface
FINAGLE-PROTOBUF
21
![Page 22: Finagle Your Own Codec - Scala By The Bay 2016](https://reader035.vdocuments.site/reader035/viewer/2022070602/587942421a28ab23468b66c9/html5/thumbnails/22.jpg)
Copyright 2016 Tendril, Inc. All rights reserved.Scalae By The Bay | November 11, 2016
Wire Formats
• Wire Format Version 0
• Wire Format Version 1
FINAGLE-PROTOBUF
22
Method code Message length
Protobuf message
Trace span Protobuf messageTracingMarker Span Parent span Method Code Message
lengthVersion
![Page 23: Finagle Your Own Codec - Scala By The Bay 2016](https://reader035.vdocuments.site/reader035/viewer/2022070602/587942421a28ab23468b66c9/html5/thumbnails/23.jpg)
Copyright 2016 Tendril, Inc. All rights reserved.Scalae By The Bay | November 11, 2016
Version Detection
• Service is configured V0 or V1 on startup• V1 service can handle V0 or V1 frames• Detects version based on version and marker fields
• Client configured as V0 or V1 • All responses V0
• No update to clients for response version detection• Backwards compatibility maintained
FINAGLE-PROTOBUF
23
![Page 24: Finagle Your Own Codec - Scala By The Bay 2016](https://reader035.vdocuments.site/reader035/viewer/2022070602/587942421a28ab23468b66c9/html5/thumbnails/24.jpg)
Copyright 2016 Tendril, Inc. All rights reserved.Scalae By The Bay | November 11, 2016
Error Handling and Mapping
message Error { optional uint32 code = 1; optional string message = 2; }
• ServiceExceptionHandler• Service-side (ServiceDispatcher)• Maps exception to message
• ExceptionResponseHandler• Client-side (RpcChannelImpl)• Maps message to exception
FINAGLE-PROTOBUF
24
![Page 25: Finagle Your Own Codec - Scala By The Bay 2016](https://reader035.vdocuments.site/reader035/viewer/2022070602/587942421a28ab23468b66c9/html5/thumbnails/25.jpg)
Copyright 2016 Tendril, Inc. All rights reserved.
LESSONS AND RECOMMENDATIONS
25
![Page 26: Finagle Your Own Codec - Scala By The Bay 2016](https://reader035.vdocuments.site/reader035/viewer/2022070602/587942421a28ab23468b66c9/html5/thumbnails/26.jpg)
Copyright 2016 Tendril, Inc. All rights reserved.Scalae By The Bay | November 11, 2016
Why build your own protocol
• One-side support (e.g. HTTP)• Legacy or other interop• Wrapping another protocol (e.g. MySQL, Redis)
• Use existing protocols (e.g. Thrift) otherwise
LESSONS
26
![Page 27: Finagle Your Own Codec - Scala By The Bay 2016](https://reader035.vdocuments.site/reader035/viewer/2022070602/587942421a28ab23468b66c9/html5/thumbnails/27.jpg)
Copyright 2016 Tendril, Inc. All rights reserved.Scalae By The Bay | November 11, 2016
Error Handling
• Tricky to get right, tricky to test• Prefer transport or in-protocol handling• Avoid forcing a message format
LESSONS
27
![Page 28: Finagle Your Own Codec - Scala By The Bay 2016](https://reader035.vdocuments.site/reader035/viewer/2022070602/587942421a28ab23468b66c9/html5/thumbnails/28.jpg)
Copyright 2016 Tendril, Inc. All rights reserved.Scalae By The Bay | November 11, 2016
Support
• Community is solidly Thrift• Twitter support is mostly Mux • If you go another way you’re doing a lot of work on your
own• If you build on Mux you get many Twitter enhancements
“for free”
LESSONS
28
![Page 29: Finagle Your Own Codec - Scala By The Bay 2016](https://reader035.vdocuments.site/reader035/viewer/2022070602/587942421a28ab23468b66c9/html5/thumbnails/29.jpg)
Copyright 2016 Tendril, Inc. All rights reserved.Scalae By The Bay | November 11, 2016
Adapt or Adopt
• Generated interfaces • Generated interface or Finagle interface• Existing generator or roll your own
• Hide or expose Twitter Futures, Finagle? • Façade approaches are very tricky
• Mapping or leaky abstractions• Hand-rolled or generated code ??• More layers and more magic == fewer experts on your team
LESSONS
29
![Page 30: Finagle Your Own Codec - Scala By The Bay 2016](https://reader035.vdocuments.site/reader035/viewer/2022070602/587942421a28ab23468b66c9/html5/thumbnails/30.jpg)
Copyright 2016 Tendril, Inc. All rights reserved.Scalae By The Bay | November 11, 2016
Interfaces and Implementations
• Your protocol defines interfaces
• Implementations supplied in your libraries?• Default implementations? • Example implementations?• Good docs?
LESSONS
30
![Page 31: Finagle Your Own Codec - Scala By The Bay 2016](https://reader035.vdocuments.site/reader035/viewer/2022070602/587942421a28ab23468b66c9/html5/thumbnails/31.jpg)
Copyright 2016 Tendril, Inc. All rights reserved.Scalae By The Bay | November 11, 2016
Make things easy for your developers
• Examples • Testbeds • Seed projects
LESSONS
31
![Page 32: Finagle Your Own Codec - Scala By The Bay 2016](https://reader035.vdocuments.site/reader035/viewer/2022070602/587942421a28ab23468b66c9/html5/thumbnails/32.jpg)
Copyright 2016 Tendril, Inc. All rights reserved.Scalae By The Bay | November 11, 2016
Learning about Finagle
• Configuration settings• Diagnosing failures
• What behavior is from Finagle? • What behavior is from your protocol?
LESSONS
32
![Page 33: Finagle Your Own Codec - Scala By The Bay 2016](https://reader035.vdocuments.site/reader035/viewer/2022070602/587942421a28ab23468b66c9/html5/thumbnails/33.jpg)
Copyright 2016 Tendril, Inc. All rights reserved.Scalae By The Bay | November 11, 2016
Things to Check Out
• ScalaPB• http://trueaccord.github.io/ScalaPB/• “Spark and Protocol Buffers – An Awesome Combination”
• Nadav Samet, Saturday 9:50• Finagle Serial
• https://github.com/finagle/finagle-serial• Finagle Protobuf
• https://github.com/finagle/finagle-protobuf
LESSONS
33