Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Newer
Older
100644 1233 lines (904 sloc) 50.306 kb
f74d889 @mccue Changing contents of README.md to Finagle Developer Guide
mccue authored
1 <a name="Top"></a>
2
3 # Finagle Developer Guide (July 24, 2011 Draft)
4
5 * <a href="#Quick Start">Quick Start</a>
6 - <a href="#Simple HTTP Server">Simple HTTP Server</a>
7 - <a href="#Simple HTTP Client">Simple HTTP Client</a>
8 - <a href="#Simple Client and Server for Thrift">Simple Client and Server for Thrift</a>
9 * <a href="#Finagle Overview">Finagle Overview</a>
10 - <a href="#Client Features">Client Features</a>
11 - <a href="#Server Features">Server Features</a>
12 - <a href="#Supported Protocols">Supported Protocols</a>
13 * <a href="#Architecture">Architecture</a>
14 - <a href="#Future Objects">Future Objects</a>
15 - <a href="#Service Objects">Service Objects</a>
16 - <a href="#Filter Objects">Filter Objects</a>
17 - <a href="#Codec Objects">Codec Objects</a>
18 - <a href="#Servers">Servers</a>
19 - <a href="#Clients">Clients</a>
20 - <a href="#Threading Model">Threading Model</a>
21 - <a href="#Starting and Stopping Services">Starting and Stopping Servers</a>
22 - <a href="#Exception Handling">Exception Handling</a>
23 * <a href="#Finagle Projects and Packages">Finagle Projects and Packages</a>
24 * <a href="#Using Future Objects">Using Future Objects</a>
25 - <a href="#Future Callbacks">Future Callbacks</a>
26 - <a href="#Future Timeouts">Future Timeouts</a>
27 - <a href="#Future Exceptions">Future Exceptions</a>
28 - <a href="#Promises">Promises</a>
29 - <a href="#Using Future map and flatMap Operations">Using Future map and flatMap Operations</a>
30 - <a href="#Using Future in Scatter/Gather Patterns">Using Future in Scatter/Gather Patterns</a>
31 - <a href="#Using Future Pools">Using Future Pools</a>
32 * <a href="#Using Future Objects With Java">Using Future Objects With Java</a>
33 - <a href="#Imperative Java Style">Imperative Java Style</a>
34 - <a href="#Functional Java Style">Functional Java Style</a>
35 * <a href="#Creating a Service">Creating a Service</a>
36 * <a href="#Creating Simple Filters">Creating Filters</a>
37 * <a href="#Building a Robust Server">Building a Robust Server</a>
38 * <a href="#Building a Robust Client">Building a Robust Client</a>
39 * <a href="#Creating Filters to Transform Requests and Responses">Creating Filters to Transform Requests and Responses</a>
40 * <a href="#Using ServerSet Objects">Using ServerSet Objects</a>
41 * <a href="#Additional Samples">Additional Samples</a>
42 * <a href="#API Reference Documentation">API Reference Documentation</a>
43 * <a href="#Revision History">Revision History</a>
44 - <a href="#1.4.3 (2011-05-17)">1.4.3 (2011-05-17)</a>
45 - <a href="#1.2.3 (2011-03-18)">1.2.3 (2011-03-18)</a>
46
47 <a name="Quick Start"></a>
48
49 ## Quick Start
50
f3ee11d @evnm [split] Fix deprecated link to ServerSet documentation in README.
evnm authored
51 Finagle is an asynchronous network stack for the JVM that you can use to build *asynchronous* Remote Procedure Call (RPC) clients and servers in Java, Scala, or any JVM-hosted language. Finagle provides a rich set of tools that are protocol independent.
f74d889 @mccue Changing contents of README.md to Finagle Developer Guide
mccue authored
52
53 The following Quick Start sections show how to implement simple RPC servers and clients in Scala and Java. The first example shows the creation a simple HTTP server and corresponding client. The second example shows the creation of a Thrift server and client. You can use these examples to get started quickly and have something that works in just a few lines of code. For a more detailed description of Finagle and its features, start with <a href="#Finagle Overview">Finagle Overview</a> and come back to Quick Start later.
54
55 [Top](#Top)
56
57 <a name="Simple HTTP Server"></a>
58
59 ### Simple HTTP Server
60
f3ee11d @evnm [split] Fix deprecated link to ServerSet documentation in README.
evnm authored
61 Consider a very simple implementation of an HTTP server and client in which clients make HTTP GET requests and the server responds to each one with an HTTP 200 OK response.
f74d889 @mccue Changing contents of README.md to Finagle Developer Guide
mccue authored
62
63 The following server, which is shown in both Scala and Java, responds to a client's HTTP request with an HTTP 200 OK response:
64
65 ##### Scala HTTP Server Implementation
66
67 val service: Service[HttpRequest, HttpResponse] = new Service[HttpRequest, HttpResponse] { // 1
f3ee11d @evnm [split] Fix deprecated link to ServerSet documentation in README.
evnm authored
68 def apply(request: HttpRequest) = Future(new DefaultHttpResponse(HTTP_1_1, OK)) // 2
f74d889 @mccue Changing contents of README.md to Finagle Developer Guide
mccue authored
69 }
70
71 val address: SocketAddress = new InetSocketAddress(10000) // 3
72
73 val server: Server[HttpRequest, HttpResponse] = ServerBuilder() // 4
74 .codec(Http)
75 .bindTo(address)
b12649c @mariusae [split] finagle README: fix up examples so that they actually compile
mariusae authored
76 .name("HttpServer")
f74d889 @mccue Changing contents of README.md to Finagle Developer Guide
mccue authored
77 .build(service)
78
79 ##### Java HTTP Server Implementation
80
81 Service<HttpRequest, HttpResponse> service = new Service<HttpRequest, HttpResponse>() { // 1
82 public Future<HttpResponse> apply(HttpRequest request) {
83 return Future.value( // 2
f3ee11d @evnm [split] Fix deprecated link to ServerSet documentation in README.
evnm authored
84 new DefaultHttpResponse(HttpVersion.HTTP_1_1, HttpResponseStatus.OK));
f74d889 @mccue Changing contents of README.md to Finagle Developer Guide
mccue authored
85 }
86 };
87
88 ServerBuilder.safeBuild(service, ServerBuilder.get() // 4
89 .codec(Http.get())
b12649c @mariusae [split] finagle README: fix up examples so that they actually compile
mariusae authored
90 .name("HttpServer")
91 .bindTo(new InetSocketAddress("localhost", 10000))); // 3
f74d889 @mccue Changing contents of README.md to Finagle Developer Guide
mccue authored
92
93
94 ##### HTTP Server Code Annotations
95
f3ee11d @evnm [split] Fix deprecated link to ServerSet documentation in README.
evnm authored
96 1. Create a new Service that handles HTTP requests and responses.
f74d889 @mccue Changing contents of README.md to Finagle Developer Guide
mccue authored
97 2. For each request, respond asynchronously with an HTTP 200 OK response. A Future instance represents an asynchronous operation that may be performed later.
98 3. Specify the socket addresses on which your server responds; in this case, on port 10000 of localhost.
99 4. Build a server that responds to HTTP requests on the socket and associate it with your service. In this case, the Server builder specifies
100 - an HTTP codec, which ensures that only valid HTTP requests are received by the server
101 - the host socket that listens for requests
102 - the association between the server and the service, which is specified by `.build` in Scala and the first argument to `safeBuild` in Java
103 - the name of the service
104
105 [Top](#Top)
106
107 <a name="Simple HTTP Client"></a>
108
109 ### Simple HTTP Client
110
111 The client, which is shown in both Scala and Java, connects to the server, and issues a simple HTTP GET request:
112
113 ##### Scala HTTP Client Implementation
114
115 val client: Service[HttpRequest, HttpResponse] = ClientBuilder() // 1
116 .codec(Http)
117 .hosts(address)
118 .build()
119
120 // Issue a request, get a response:
121 val request: HttpRequest = new DefaultHttpRequest(HTTP_1_1, GET, "/") // 2
122 val responseFuture: Future[HttpResponse] = client(request) // 3
123 onSuccess { response => println("Received response: " + response) // 4
124 }
125
126 ##### Java HTTP Client Implementation
127
128 Service<HttpRequest, HttpResponse> client = ClientBuilder.safeBuild(ClientBuilder.get() // 1
129 .codec(Http.get())
130 .hosts("localhost:10000")
131 .hostConnectionLimit(1));
132
133 // Issue a request, get a response:
134 HttpRequest request = new DefaultHttpRequest(HttpVersion.HTTP_1_1, HttpMethod.GET, "/"); // 2
135 client.apply(request).addEventListener(new FutureEventListener<HttpResponse>() { // 3
136 public void onSuccess(HttpResponse response) { // 4
137 System.out.println("received response: " + response);
138 }
139 public void onFailure(Throwable cause) {
140 System.out.println("failed with cause: " + cause);
141 }
142 });
143
144 ##### HTTP Client Code Annotations
145
146 1. Build a client that sends an HTTP request to the host identified by its socket address. In this case, the Client builder specifies
147 - an HTTP request filter, which ensures that only valid HTTP requests are sent to the server
148 - a list of the server's hosts that can process requests
149 - to build this client service
150 2. Create an HTTP GET request.
151 3. Make the request to the host identified in your client.
152 4. Specify a callback, `onSuccess`, that Finagle executes when the response arrives.
153
154 Note: Although the example shows building the client and execution of the built client on the same thread, you should build your clients only once and execute them separately. There is no requirement to maintain a 1:1 relationship between building a client and executing a client.
155
156 [Top](#Top)
157
158 <a name="Simple Client and Server for Thrift"></a>
159
160 ### Simple Client and Server for Thrift
161
162 Apache Thrift is a binary communication protocol that defines available methods using an interface definition language (IDL). Consider the following Thrift IDL definition for a `Hello` service that defines only one method, `hi`:
163
164 service Hello {
165 string hi();
166 }
167
168 #### Simple Thrift Server
169
170 In this Finagle example, the `ThriftServer` object implements the `Hello` service defined using the Thrift IDL.
171
172 ##### Scala Thrift Server Implementation
173
174 object ThriftServer {
175 def main(args: Array[String]) {
176 // Implement the Thrift Interface
177 val processor = new Hello.ServiceIface { // 1
178 def hi() = Future.value("hi") // 2
179 }
180
181 val service = new Hello.Service(processor, new TBinaryProtocol.Factory()) // 3
182
183 val server: Server = ServerBuilder() // 4
184 .name("HelloService")
185 .bindTo(new InetSocketAddress(8080))
186 .codec(ThriftServerFramedCodec())
187 .build(service)
188 }
189 }
190
191 ##### Java Thrift Server Implementation
192
193 Hello.ServiceIface processor = new Hello.ServiceIface() { // 1
194 public Future<String> hi() { // 2
195 return Future.value("hi");
196 }
f3ee11d @evnm [split] Fix deprecated link to ServerSet documentation in README.
evnm authored
197 }
f74d889 @mccue Changing contents of README.md to Finagle Developer Guide
mccue authored
198
199 ServerBuilder.safeBuild( // 4
200 new Hello.Service(processor, new TBinaryProtocol.Factory()), // 3
f3ee11d @evnm [split] Fix deprecated link to ServerSet documentation in README.
evnm authored
201 ServerBuilder.get()
f74d889 @mccue Changing contents of README.md to Finagle Developer Guide
mccue authored
202 .name("HelloService")
203 .codec(ThriftServerFramedCodecFactory$.MODULE$)
b12649c @mariusae [split] finagle README: fix up examples so that they actually compile
mariusae authored
204 .bindTo(new InetSocketAddress(8080)));
f74d889 @mccue Changing contents of README.md to Finagle Developer Guide
mccue authored
205
206 ##### Thrift Server Code Annotations
207
f3ee11d @evnm [split] Fix deprecated link to ServerSet documentation in README.
evnm authored
208 1. Create a Thrift processor that implements the Thrift service interface, which is `Hello` in this example.
f74d889 @mccue Changing contents of README.md to Finagle Developer Guide
mccue authored
209 2. Implement the service interface. In this case, the only method in the interface is `hi`, which only returns the string `"hi"`. The returned value must be a `Future` to conform the signature of a Finagle `Service`. (In a more robust example, the Thrift service might perform asynchronous communication.)
210 3. Create an adapter from the Thrift processor to a Finagle service. In this case, the `Hello` Thrift service uses `TBinaryProtocol` as the Thrift protocol.
211 4. Build a server that responds to Thrift requests on the socket and associate it with your service. In this case, the Server builder specifies
212 - the name of the service
213 - the host addresses that can receive requests
214 - the Finagle-provided `ThriftServerFramedCodec` codec, which ensures that only valid Thrift requests are received by the server
215 - the association between the server and the service
216
217 #### Simple Thrift Client
218
219 In this Finagle example, the `ThriftClient` object creates a Finagle client that executes the methods defined in the `Hello` Thrift service.
220
221 ##### Scala Thrift Client Implementation
222
223 object ThriftClient {
224 def main(args: Array[String]) {
225 // Create a raw Thrift client service. This implements the
226 // ThriftClientRequest => Future[Array[Byte]] interface.
227 val service: Service[ThriftClientRequest, Array[Byte]] = ClientBuilder() // 1
228 .hosts(new InetSocketAddress(8080))
229 .codec(ThriftClientFramedCodec())
230 .hostConnectionLimit(1)
231 .build()
232
233 // Wrap the raw Thrift service in a Client decorator. The client provides
234 // a convenient procedural interface for accessing the Thrift server.
235 val client = new Hello.ServiceToClient(service, new TBinaryProtocol.Factory()) // 2
236
237 client.hi() onSuccess { response => // 3
238 println("Received response: " + response)
239 } ensure {
240 service.release() // 4
241 }
242 }
243 }
244
245 ##### Java Thrift Client Implementation
246
247 Service<ThriftClientRequest, byte[]> client = ClientBuilder.safeBuild(ClientBuilder.get() // 1
248 .hosts(new InetSocketAddress(8080))
249 .codec(new ThriftClientFramedCodecFactory())
250 .hostConnectionLimit(1));
251
f3ee11d @evnm [split] Fix deprecated link to ServerSet documentation in README.
evnm authored
252 Hello.ServiceIface client =
f74d889 @mccue Changing contents of README.md to Finagle Developer Guide
mccue authored
253 new Hello.ServiceToClient(client, new TBinaryProtocol.Factory()); // 2
254
255 client.hi().addEventListener(new FutureEventListener<String>() {
256 public void onSuccess(String s) { // 3
257 System.out.println(s);
258 }
259
260 public void onFailure(Throwable t) {
261 System.out.println("Exception! ", t.toString());
262 });
263
264 ##### Thrift Client Code Annotation
bf776ce @mariusae minimal README.
mariusae authored
265
f74d889 @mccue Changing contents of README.md to Finagle Developer Guide
mccue authored
266 1. Build a client that sends a Thrift protocol-based request to the host identified by its socket address. In this case, the Client builder specifies
267 - the host addresses that can receive requests
268 - the Finagle-provided `ThriftServerFramedCodec` codec, which ensures that only valid Thrift requests are received by the server
269 - to build this client service
270 2. Make a remote procedure call to the `Hello` Thrift service's `Hi` method. This returns a `Future` that represents the eventual arrival of a response.
271 3. When the response arrives, the `onSuccess` callback executes to print the result.
272 4. Release resources acquired by the client.
bf776ce @mariusae minimal README.
mariusae authored
273
f74d889 @mccue Changing contents of README.md to Finagle Developer Guide
mccue authored
274 [Top](#Top)
ec2ae88 @bierbaum updated readme (still needs a lot of work)
bierbaum authored
275
f74d889 @mccue Changing contents of README.md to Finagle Developer Guide
mccue authored
276 <a name="Finagle Overview"></a>
277
278 ## Finagle Overview
279
280 Use the Finagle library to implement asynchronous Remote Procedure Call (RPC) clients and servers. Finagle is flexible enough to support a variety of RPC styles, including request-response, streaming, and pipelining; for example, HTTP pipelining and Redis pipelining. It also makes it easy to work with stateful RPC styles; for example, RPCs that require authentication and those that support transactions.
281
282 [Top](#Top)
283
284 <a name="Client Features"></a>
ec2ae88 @bierbaum updated readme (still needs a lot of work)
bierbaum authored
285
235b186 improving readme
Nick Kallen authored
286 ### Client Features
ec2ae88 @bierbaum updated readme (still needs a lot of work)
bierbaum authored
287
235b186 improving readme
Nick Kallen authored
288 * Connection Pooling
289 * Load Balancing
290 * Failure Detection
291 * Failover/Retry
391f93d corrected readme
Nick Kallen authored
292 * Distributed Tracing (a la [Dapper](http://research.google.com/pubs/pub36356.html))
235b186 improving readme
Nick Kallen authored
293 * Service Discovery (e.g., via Zookeeper)
294 * Rich Statistics
f74d889 @mccue Changing contents of README.md to Finagle Developer Guide
mccue authored
295 * Native OpenSSL Bindings
296
297 [Top](#Top)
298
299 <a name="Server Features"></a>
ec2ae88 @bierbaum updated readme (still needs a lot of work)
bierbaum authored
300
235b186 improving readme
Nick Kallen authored
301 ### Server Features
ec2ae88 @bierbaum updated readme (still needs a lot of work)
bierbaum authored
302
235b186 improving readme
Nick Kallen authored
303 * Backpressure (to defend against abusive clients)
304 * Service Registration (e.g., via Zookeeper)
391f93d corrected readme
Nick Kallen authored
305 * Distributed Tracing
235b186 improving readme
Nick Kallen authored
306 * Native OpenSSL bindings
ec2ae88 @bierbaum updated readme (still needs a lot of work)
bierbaum authored
307
f74d889 @mccue Changing contents of README.md to Finagle Developer Guide
mccue authored
308 [Top](#Top)
309
310 <a name="Supported Protocols"></a>
311
235b186 improving readme
Nick Kallen authored
312 ### Supported Protocols
ec2ae88 @bierbaum updated readme (still needs a lot of work)
bierbaum authored
313
235b186 improving readme
Nick Kallen authored
314 * HTTP
391f93d corrected readme
Nick Kallen authored
315 * HTTP streaming (Comet)
235b186 improving readme
Nick Kallen authored
316 * Thrift
317 * Memcached/Kestrel
318 * More to come!
ec2ae88 @bierbaum updated readme (still needs a lot of work)
bierbaum authored
319
f74d889 @mccue Changing contents of README.md to Finagle Developer Guide
mccue authored
320 [Top](#Top)
ec2ae88 @bierbaum updated readme (still needs a lot of work)
bierbaum authored
321
f74d889 @mccue Changing contents of README.md to Finagle Developer Guide
mccue authored
322 <a name="Architecture"></a>
391f93d corrected readme
Nick Kallen authored
323
f74d889 @mccue Changing contents of README.md to Finagle Developer Guide
mccue authored
324 ## Architecture
391f93d corrected readme
Nick Kallen authored
325
f3ee11d @evnm [split] Fix deprecated link to ServerSet documentation in README.
evnm authored
326 Finagle extends the stream-oriented [Netty](http://www.jboss.org/netty) model to provide asynchronous requests and responses for remote procedure calls (RPC). Internally, Finagle manages a service stack to track outstanding requests, responses, and the events related to them. Finagle uses a Netty pipeline to manage connections between the streams underlying request and response messages. The following diagram shows the relationship between your RCP client or server, Finagle, Netty, and Java libraries:
391f93d corrected readme
Nick Kallen authored
327
5248a58 @mariusae [split] finagle·doc: fix up image links
mariusae authored
328 ![Relationship between your RCP client or server, Finagle, Netty, and Java Libraries (doc/FinagleRelationship.png)](https://github.com/twitter/finagle/raw/master/doc/FinagleRelationship.png)
391f93d corrected readme
Nick Kallen authored
329
f74d889 @mccue Changing contents of README.md to Finagle Developer Guide
mccue authored
330 Finagle manages a [Netty pipeline](http://docs.jboss.org/netty/3.2/api/org/jboss/netty/channel/ChannelPipeline.html) for servers built on Finagle RCP services. Netty itself is built on the Java [NIO](http://download.oracle.com/javase/1.5.0/docs/api/java/nio/channels/package-summary.html#package_description) library, which supports asynchronous IO. While an understanding of Netty or NIO might be useful, you can use Finagle without this background information.
391f93d corrected readme
Nick Kallen authored
331
f74d889 @mccue Changing contents of README.md to Finagle Developer Guide
mccue authored
332 Finagle objects are the building blocks of RCP clients and servers:
391f93d corrected readme
Nick Kallen authored
333
f74d889 @mccue Changing contents of README.md to Finagle Developer Guide
mccue authored
334 - <a href="#Future Objects">Future objects</a> enable asynchronous operations required by a service
335 - <a href="#Service Objects">Service objects</a> perform the work associated with a remote procedure call
336 - <a href="#Filter Objects">Filter objects</a> enable you to transform data or act on messages before or after the data or messages are processed by a service
337 - <a href="#Codec Objects">Codec objects</a> decode messages in a specific protocol before they are handled by a service and encode messages before they are transported to a client or server.
391f93d corrected readme
Nick Kallen authored
338
f74d889 @mccue Changing contents of README.md to Finagle Developer Guide
mccue authored
339 You combine these objects to create:
ec2ae88 @bierbaum updated readme (still needs a lot of work)
bierbaum authored
340
f74d889 @mccue Changing contents of README.md to Finagle Developer Guide
mccue authored
341 - <a href="#Servers">Servers</a>
342 - <a href="#Clients">Clients</a>
ec2ae88 @bierbaum updated readme (still needs a lot of work)
bierbaum authored
343
f74d889 @mccue Changing contents of README.md to Finagle Developer Guide
mccue authored
344 Finagle provides a `ServerBuilder` and a `ClientBuilder` object, which enable you to configure <a href="#Servers">servers</a> and <a href="#Clients">clients</a>, respectively.
ec2ae88 @bierbaum updated readme (still needs a lot of work)
bierbaum authored
345
f74d889 @mccue Changing contents of README.md to Finagle Developer Guide
mccue authored
346 [Top](#Top)
ec2ae88 @bierbaum updated readme (still needs a lot of work)
bierbaum authored
347
f74d889 @mccue Changing contents of README.md to Finagle Developer Guide
mccue authored
348 <a name="Future Objects"></a>
ec2ae88 @bierbaum updated readme (still needs a lot of work)
bierbaum authored
349
f74d889 @mccue Changing contents of README.md to Finagle Developer Guide
mccue authored
350 ### Future Objects
068ec55 reformatting
Nick Kallen authored
351
f3ee11d @evnm [split] Fix deprecated link to ServerSet documentation in README.
evnm authored
352 In Finagle, `Future` objects are the unifying abstraction for all asynchronous computation. A `Future` represents a computation that has not yet completed, which can either succeed or fail. The two most basic ways to use a `Future` are to
ec2ae88 @bierbaum updated readme (still needs a lot of work)
bierbaum authored
353
f74d889 @mccue Changing contents of README.md to Finagle Developer Guide
mccue authored
354 * block and wait for the computation to return
355 * register a callback to be invoked when the computation eventually succeeds or fails
ec2ae88 @bierbaum updated readme (still needs a lot of work)
bierbaum authored
356
f74d889 @mccue Changing contents of README.md to Finagle Developer Guide
mccue authored
357 For more information about `Future` objects, see <a href="#Using Future Objects">Using Future Objects</a>.
ec2ae88 @bierbaum updated readme (still needs a lot of work)
bierbaum authored
358
f74d889 @mccue Changing contents of README.md to Finagle Developer Guide
mccue authored
359 <!-- Future has methods, such as `times`, `parallel`, and `whileDo` that implement advanced control-flow patterns. -->
ec2ae88 @bierbaum updated readme (still needs a lot of work)
bierbaum authored
360
f74d889 @mccue Changing contents of README.md to Finagle Developer Guide
mccue authored
361 [Top](#Top)
235b186 improving readme
Nick Kallen authored
362
f74d889 @mccue Changing contents of README.md to Finagle Developer Guide
mccue authored
363 <a name="Service Objects"></a>
235b186 improving readme
Nick Kallen authored
364
f74d889 @mccue Changing contents of README.md to Finagle Developer Guide
mccue authored
365 ### Service Objects
235b186 improving readme
Nick Kallen authored
366
f3ee11d @evnm [split] Fix deprecated link to ServerSet documentation in README.
evnm authored
367 A `Service` is simply a function that receives a request and returns a `Future` object as a response. You extend the abstract `Service` class to implement your service; specifically, you must define an `apply` method that transforms the request into the future response.
235b186 improving readme
Nick Kallen authored
368
f74d889 @mccue Changing contents of README.md to Finagle Developer Guide
mccue authored
369 [Top](#Top)
235b186 improving readme
Nick Kallen authored
370
f74d889 @mccue Changing contents of README.md to Finagle Developer Guide
mccue authored
371 <a name="Filter Objects"></a>
235b186 improving readme
Nick Kallen authored
372
f74d889 @mccue Changing contents of README.md to Finagle Developer Guide
mccue authored
373 ### Filter Objects
235b186 improving readme
Nick Kallen authored
374
f3ee11d @evnm [split] Fix deprecated link to ServerSet documentation in README.
evnm authored
375 It is useful to isolate distinct phases of your application into a pipeline. For example, you may need to handle exceptions, authorization, and other phases before your service responds to a request. A `Filter` provides an easy way to decouple the protocol handling code from the implementation of the business rules. A `Filter` wraps a `Service` and, potentially, converts the input and output types of the service to other types. For an example of a filter, see <a href="#Creating Filters to Transform Requests and Responses">Creating Filters to Transform Requests and Responses</a>.
ec2ae88 @bierbaum updated readme (still needs a lot of work)
bierbaum authored
376
f74d889 @mccue Changing contents of README.md to Finagle Developer Guide
mccue authored
377 A `SimpleFilter` is a kind of `Filter` that does not convert the request and response types. For an example of a simple filter, see <a href="#Creating Filters">Creating Filters</a>.
235b186 improving readme
Nick Kallen authored
378
f74d889 @mccue Changing contents of README.md to Finagle Developer Guide
mccue authored
379 [Top](#Top)
235b186 improving readme
Nick Kallen authored
380
f74d889 @mccue Changing contents of README.md to Finagle Developer Guide
mccue authored
381 <a name="Codec Objects"></a>
ec2ae88 @bierbaum updated readme (still needs a lot of work)
bierbaum authored
382
f74d889 @mccue Changing contents of README.md to Finagle Developer Guide
mccue authored
383 ### Codec Objects
068ec55 reformatting
Nick Kallen authored
384
f74d889 @mccue Changing contents of README.md to Finagle Developer Guide
mccue authored
385 A `Codec` object encodes and decodes _wire_ protocols, such as HTTP. You can use Finagle-provided `Codec` objects for encoding and decoding the Thrift, HTTP, memcache, Kestrel, Twitter streaming, and generic multiplexeror protocols. You can also extend the `CodecFactory` class to implement encoding and decoding of other protocols.
235b186 improving readme
Nick Kallen authored
386
f74d889 @mccue Changing contents of README.md to Finagle Developer Guide
mccue authored
387 [Top](#Top)
235b186 improving readme
Nick Kallen authored
388
f74d889 @mccue Changing contents of README.md to Finagle Developer Guide
mccue authored
389 <!--
390 <a name="Channel Objects"></a>
235b186 improving readme
Nick Kallen authored
391
f74d889 @mccue Changing contents of README.md to Finagle Developer Guide
mccue authored
392 ### Channel Objects
ec2ae88 @bierbaum updated readme (still needs a lot of work)
bierbaum authored
393
f74d889 @mccue Changing contents of README.md to Finagle Developer Guide
mccue authored
394 Finagle makes streaming and pubsub-like RPCs easy. Streams rely on a generalization of `Future` called `Channel`. A `Channel` represents a stream of events that can be listened to. Every `Channel` has a sub-channel that indicates when a responder subscribes or unsubscribes to the channel.
235b186 improving readme
Nick Kallen authored
395
f74d889 @mccue Changing contents of README.md to Finagle Developer Guide
mccue authored
396 [Top](#Top)
397 -->
235b186 improving readme
Nick Kallen authored
398
f74d889 @mccue Changing contents of README.md to Finagle Developer Guide
mccue authored
399 <a name="Servers"></a>
235b186 improving readme
Nick Kallen authored
400
f74d889 @mccue Changing contents of README.md to Finagle Developer Guide
mccue authored
401 ### Servers
235b186 improving readme
Nick Kallen authored
402
f74d889 @mccue Changing contents of README.md to Finagle Developer Guide
mccue authored
403 In Finagle, RPC servers are built out of a `Service` and zero or more `Filter` objects. You apply filters to the service request after which you execute the service itself:
235b186 improving readme
Nick Kallen authored
404
5248a58 @mariusae [split] finagle·doc: fix up image links
mariusae authored
405 ![Relationship between a service and filters (doc/Filters.png)](https://github.com/twitter/finagle/raw/master/doc/Filters.png)
f74d889 @mccue Changing contents of README.md to Finagle Developer Guide
mccue authored
406
407 Typically, you use a `ServerBuilder` to create your server. A `ServerBuilder` enables you to specify the following general attributes:
408
409 <table>
410 <thead>
411 <tr>
412 <th>Attribute</th>
413 <th>Description</th>
414 <th>Default Value</th>
415 </tr>
416 </thead>
417 <tr>
418 <td>codec</td>
419 <td>Object to handle encoding and decoding of the service's request/response protocol</td>
420 <td><I>None</I></td>
421 </tr>
422 <tr>
423 <td>statsReceiver</td>
424 <td>Statistics receiver object, which enables logging of important events and statistics</td>
425 <td><I>None</I></td>
426 </tr>
427 <tr>
428 <td>name</td>
429 <td>Name of the service</td>
430 <td><I>None</I></td>
431 </tr>
432 <tr>
433 <td>bindTo</td>
434 <td>The IP host:port pairs on which to listen for requests; <CODE>localhost</CODE> is assumed if the host is not specified</td>
435 <td><I>None</I></td>
436 </tr>
437 <tr>
438 <td>logger</td>
439 <td>Logger object</td>
440 <td><I>None</I></td>
441 </tr>
442 </tbody>
443 </table>
444
445 You can specify the following attributes to handle fault tolerance and manage clients:
446
447 <table>
448 <thead>
449 <tr>
450 <th>Attribute</th>
451 <th>Description</th>
452 <th>Default Value</th>
453 </tr>
454 </thead>
455 <tr>
456 <td>maxConcurrentRequests</td>
457 <td>Maximum number of requests that can be handled concurrently by the server</td>
458 <td><I>None</I></td>
459 </tr>
460 <tr>
461 <td>hostConnectionMaxIdleTime</td>
462 <td>Maximum time that this server can be idle before the connection is closed</td>
463 <td><I>None</I></td>
464 </tr>
465 <tr>
466 <td>hostConnectionMaxLifeTime</td>
467 <td>Maximum time that this server can be connected before the connection is closed</td>
468 <td><I>None</I></td>
469 </tr>
470 <tr>
471 <td>requestTimeout</td>
472 <td>Maximum time to complete a request</td>
473 <td><I>None</I></td>
474 </tr>
475 <tr>
476 <td>readTimeout</td>
477 <td>Maximum time to wait for the first byte to be read</td>
478 <td><I>None</I></td>
479 </tr>
480 <tr>
481 <td>writeCompletionTimeout</td>
482 <td>Maximum time to wait for notification of write completion from a client</td>
483 <td><I>None</I></td>
484 </tr>
485 </tbody>
486 </table>
487
488 You can specify the following attributes to manage TCP connections:
489
490 <table>
491 <thead>
492 <tr>
493 <th>Attribute</th>
494 <th>Description</th>
495 <th>Default Value</th>
496 </tr>
497 </thead>
498 <tr>
499 <td>sendBufferSize</td>
500 <td>Requested TCP buffer size for responses</td>
501 <td><I>None</I></td>
502 </tr>
503 <tr>
504 <td>recvBufferSize</td>
505 <td>Actual TCP buffer size for requests</td>
506 <td><I>None</I></td>
507 </tr>
508 </tbody>
509 </table>
510
511 You can also specify these attributes:
512
513 <table>
514 <thead>
515 <tr>
516 <th>Attribute</th>
517 <th>Description</th>
518 <th>Default Value</th>
519 </tr>
520 </thead>
521 <tr>
522 <td>tls</td>
523 <td>The kind of transport layer security</td>
524 <td><I>None</I></td>
525 </tr>
526 <tr>
527 <td>startTls</td>
528 <td>Whether to start transport layer security</td>
529 <td><B>false</B></td>
530 </tr>
531 <tr>
532 <td>channelFactory</td>
533 <td>Channel service factory object</td>
534 <td><I>None</I></td>
535 </tr>
536 <tr>
537 <td>traceReceiver</td>
538 <td>Trace receiver object</td>
539 <td>new <CODE>NullTraceReceiver</CODE> object</td>
540 </tr>
541 </tbody>
542 </table>
543
f3ee11d @evnm [split] Fix deprecated link to ServerSet documentation in README.
evnm authored
544 Once you have defined your `Service`, it can be bound to an IP socket address, thus becoming an RPC server.
f74d889 @mccue Changing contents of README.md to Finagle Developer Guide
mccue authored
545
546 [Top](#Top)
547
548 <a name="Clients"></a>
549
550 ### Clients
551
f3ee11d @evnm [split] Fix deprecated link to ServerSet documentation in README.
evnm authored
552 Finagle makes it easy to build RPC clients with connection pooling, load balancing, logging, and statistics reporting. The balancing strategy is to pick the endpoint with the least number of outstanding requests, which is similar to _least connections_ in other load balancers. The load-balancer deliberately introduces jitter to avoid synchronicity (and thundering herds) in a distributed system.
f74d889 @mccue Changing contents of README.md to Finagle Developer Guide
mccue authored
553
f3ee11d @evnm [split] Fix deprecated link to ServerSet documentation in README.
evnm authored
554 Your code should separate building the client from invocation of the client. A client, once built, can be used with _lazy binding_, saving the resources required to build a client. Note: The examples, which show the creation of the client and its first execution together, represent the first-execution scenario. Typically, subsequent execution of the client does not require rebuilding.
f74d889 @mccue Changing contents of README.md to Finagle Developer Guide
mccue authored
555
556 Finagle will retry the request in the event of an error, up to the number of times specified; however, Finagle **does not assume your RPC service is Idempotent**. Retries occur only when the request is known to be idempotent, such as in the event of TCP-related `WriteException` errors, for which the RPC has not been transmitted to the remote server.
557
f3ee11d @evnm [split] Fix deprecated link to ServerSet documentation in README.
evnm authored
558 A robust way to use RPC clients is to have an upper-bound on how long to wait for a response to arrive. With `Future` objects, you can
f74d889 @mccue Changing contents of README.md to Finagle Developer Guide
mccue authored
559
560 * block, waiting for a response to arrive and throw an exception if it does not arrive in time.
561 * register a callback to handle the result if it arrives in time, and register another callback to invoke if the result does not arrive in time
562
563 A client is a `Service` and can be wrapped by `Filter` objects. Typically, you call `ClientBuilder` to create your client service. `ClientBuilder` enables you to specify the following general attributes:
564
565 <table>
566 <thead>
567 <tr>
568 <th>Attribute</th>
569 <th>Description</th>
570 <th>Default Value</th>
571 </tr>
572 </thead>
573 <tr>
574 <td>name</td>
575 <td>Name of the service</td>
576 <td><I>None</I></td>
577 </tr>
578 <tr>
579 <td>codec</td>
580 <td>Object to handle encoding and decoding of the service's request/response protocol</td>
581 <td><I>None</I></td>
582 </tr>
583 <tr>
584 <td>statsReceiver</td>
585 <td>Statistics receiver object, which enables logging of important events and statistics</td>
586 <td><I>None</I></td>
587 </tr>
588 <tr>
589 <td>loadStatistics</td>
590 <td>How often to load statistics from the server</td>
591 <td><B>(60, 10.seconds)</B></td>
592 </tr>
593 <tr>
594 <td>logger</td>
595 <td>A <CODE>Logger</CODE> object with which to log Finagle messages</td>
596 <td><I>None</I></td>
597 </tr>
598 <tr>
599 <td>retries</td>
600 <td>Number of retries per request (only applies to recoverable errors)</td>
601 <td><I>None</I></td>
602 </tr>
603 </tbody>
604 </table>
605
606 You can specify the following attributes to manage the host connection:
607
608 <table>
609 <thead>
610 <tr>
611 <th>Attribute</th>
612 <th>Description</th>
613 <th>Default Value</th>
614 </tr>
615 </thead>
616 <tr>
617 <td>connectionTimeout</td>
618 <td>Time allowed to establish a connection</td>
619 <td><B>10.milliseconds</B></td>
620 </tr>
621 <tr>
622 <td>requestTimeout</td>
623 <td>Request timeout</td>
624 <td><I>None</I>, meaning it waits forever</td>
625 </tr>
626 <tr>
627 <td>hostConnectionLimit</td>
628 <td>Number of connections allowed from this client to the host</td>
629 <td><I>None</I></td>
630 </tr>
631 <tr>
632 <td>hostConnectionCoresize</td>
633 <td>Host connection's cache allocation</td>
634 <td><I>None</I></td>
635 </tr>
636 <tr>
637 <td>hostConnectionIdleTime</td>
638 <td> </td>
639 <td><I>None</I></td>
640 </tr>
641 <tr>
642 <td>hostConnectionMaxIdleTime</td>
643 <td>Maximum time that the client can be idle until the connection is closed</td>
644 <td><I>None</I></td>
645 </tr>
646 <tr>
647 <td>hostConnectionMaxLifeTime</td>
648 <td>Maximum time that client can be connected before the connection is closed</td>
649 <td><I>None</I></td>
650 </tr>
651 </tbody>
652 </table>
653
654 You can specify the following attributes to manage TCP connections:
655
656 <table>
657 <thead>
658 <tr>
659 <th>Attribute</th>
660 <th>Description</th>
661 <th>Default Value</th>
662 </tr>
663 </thead>
664 <tr>
665 <td>sendBufferSize</td>
666 <td>Requested TCP buffer size for responses</td>
667 <td><I>None</I></td>
668 </tr>
669 <tr>
670 <td>recvBufferSize</td>
671 <td>Actual TCP buffer size for requests</td>
672 <td><I>None</I></td>
673 </tr>
674 </tbody>
675 </table>
676
677 You can also specify these attributes:
678
679 <table>
680 <tr>
681 <th>Attribute</th>
682 <th>Description</th>
683 <th>Default Value</th>
684 </tr>
685 <tr>
686 <td>cluster</td>
687 <td>The cluster connections associated with the client</td>
688 <td><I>None</I></td>
689 </tr>
690 <tr>
691 <td>channelFactory</td>
692 <td>Channel factory associated with this client</td>
693 <td><I>None</I></td>
694 </tr>
695 <tr>
696 <td>tls</td>
697 <td>The kind of transport layer security</td>
698 <td><I>None</I></td>
699 </tr>
700 <tr>
701 <td>startTls</td>
702 <td>Whether to start transport layer security</td>
703 <td><B>false</B></td>
704 </tr>
705 </table>
f3ee11d @evnm [split] Fix deprecated link to ServerSet documentation in README.
evnm authored
706
f74d889 @mccue Changing contents of README.md to Finagle Developer Guide
mccue authored
707 If you are using _stateful protocols_, such as those used for transaction processing or authentication, you should call `buildFactory`, which creates a `ServiceFactory` to support stateful connections.
708
709 [Top](#Top)
710
711 <a name="Threading Model"></a>
235b186 improving readme
Nick Kallen authored
712
189948e @mariusae [split] finagle: don't conflate asynchronicity with an event loop in the...
mariusae authored
713 ### Threading Model
235b186 improving readme
Nick Kallen authored
714
f3ee11d @evnm [split] Fix deprecated link to ServerSet documentation in README.
evnm authored
715 The Finagle threading model requires that you avoid blocking operations in the Finagle event loop. Finagle-provided methods do not block; however, you could inadvertently implement a client, service or a `Future` callback that blocks.
235b186 improving readme
Nick Kallen authored
716
f74d889 @mccue Changing contents of README.md to Finagle Developer Guide
mccue authored
717 Blocking events include but are not limited to
235b186 improving readme
Nick Kallen authored
718
f74d889 @mccue Changing contents of README.md to Finagle Developer Guide
mccue authored
719 * network calls
720 * system calls
721 * database calls
722 * any operation that synchronizes resources
235b186 improving readme
Nick Kallen authored
723
f74d889 @mccue Changing contents of README.md to Finagle Developer Guide
mccue authored
724 Note: You do not need to be concerned with long-running or CPU intensive operations if they do not block. Examples of these operations include image processing operations, public key cryptography, or anything that might take a non-trivial amount of clock time to perform. Only operations that block in Finagle are of concern. Because Finagle and its event loop use a relatively low number of threads, blocked threads can cause performance issues.
235b186 improving readme
Nick Kallen authored
725
f3ee11d @evnm [split] Fix deprecated link to ServerSet documentation in README.
evnm authored
726 Consider the following diagram, which shows how a client uses the Finagle event loop:
235b186 improving readme
Nick Kallen authored
727
5248a58 @mariusae [split] finagle·doc: fix up image links
mariusae authored
728 ![Relationship between your threads and Finagle (doc/ThreadEx.png)](https://github.com/twitter/finagle/raw/master/doc/ThreadEx.png)
cbaee89 @mariusae [split] document event loop.
mariusae authored
729
f74d889 @mccue Changing contents of README.md to Finagle Developer Guide
mccue authored
730 Your threads, which are shown on the left, are allowed to block. When you call a Finagle method or Finagle calls a method for you, it dispatches execution of these methods to its internal threads. Thus, the Finagle event loop and its threads cannot block without degrading the performance of other clients and servers that use the same Finagle instance.
ec2ae88 @bierbaum updated readme (still needs a lot of work)
bierbaum authored
731
f3ee11d @evnm [split] Fix deprecated link to ServerSet documentation in README.
evnm authored
732 In complex RCP operations, it may be necessary to perform blocking operations. In these cases, you must set up your own thread pool and use `Future` or `FuturePool` objects to execute the blocking operation on your own thread. Consider the following diagram:
ec2ae88 @bierbaum updated readme (still needs a lot of work)
bierbaum authored
733
5248a58 @mariusae [split] finagle·doc: fix up image links
mariusae authored
734 ![Handling operations that block (doc/ThreadExNonBlockingServer.png)](https://github.com/twitter/finagle/raw/master/doc/ThreadExNonBlockingServer.png)
235b186 improving readme
Nick Kallen authored
735
f74d889 @mccue Changing contents of README.md to Finagle Developer Guide
mccue authored
736 In this example, you can use a `FuturePool` object to provide threads for blocking operations outside of Finagle. Finagle can then dispatch the blocking operation to your thread. For more information about `FuturePool` objects, see <a href="#Using Future Pools">Using Future Pools</a>.
235b186 improving readme
Nick Kallen authored
737
f74d889 @mccue Changing contents of README.md to Finagle Developer Guide
mccue authored
738 [Top](#Top)
235b186 improving readme
Nick Kallen authored
739
f74d889 @mccue Changing contents of README.md to Finagle Developer Guide
mccue authored
740 <a name="Starting and Stopping Servers"></a>
235b186 improving readme
Nick Kallen authored
741
f74d889 @mccue Changing contents of README.md to Finagle Developer Guide
mccue authored
742 ### Starting and Stopping Servers
235b186 improving readme
Nick Kallen authored
743
f74d889 @mccue Changing contents of README.md to Finagle Developer Guide
mccue authored
744 A server automatically starts when you call `build` on the server after assigning the IP address on which it runs. To stop a server, call it's `close` method. The server will immediately stop accepting requests; however, the server will continue to process outstanding requests until all have been handled or until a specific duration has elapsed. You specify the duration when you call `close`. In this way, the server is allowed to drain out outstanding requests but will not run indefinitely. You are responsible for releasing all resources when the server is no longer needed.
235b186 improving readme
Nick Kallen authored
745
f74d889 @mccue Changing contents of README.md to Finagle Developer Guide
mccue authored
746 [Top](#Top)
235b186 improving readme
Nick Kallen authored
747
f74d889 @mccue Changing contents of README.md to Finagle Developer Guide
mccue authored
748 <a name="Exception Handling"></a>
235b186 improving readme
Nick Kallen authored
749
f74d889 @mccue Changing contents of README.md to Finagle Developer Guide
mccue authored
750 ### Exception Handling
235b186 improving readme
Nick Kallen authored
751
f74d889 @mccue Changing contents of README.md to Finagle Developer Guide
mccue authored
752 As soon as an exception occurs, it is executed. If more than one exception handler is defined, the first exception to occur executes its handler. Casting the exception as a `Future` means that the exception will not block; however, Finagle does not allow the thread causing the exception to continue. For an example, see <a href="#Future Exceptions">Future Exceptions</a>.
235b186 improving readme
Nick Kallen authored
753
f74d889 @mccue Changing contents of README.md to Finagle Developer Guide
mccue authored
754 [Top](#Top)
235b186 improving readme
Nick Kallen authored
755
f74d889 @mccue Changing contents of README.md to Finagle Developer Guide
mccue authored
756 <a name="Finagle Projects and Packages"></a>
235b186 improving readme
Nick Kallen authored
757
f74d889 @mccue Changing contents of README.md to Finagle Developer Guide
mccue authored
758 ## Finagle Projects and Packages
235b186 improving readme
Nick Kallen authored
759
f74d889 @mccue Changing contents of README.md to Finagle Developer Guide
mccue authored
760 The `Core` project contains the execution framework, Finagle classes, and supporting classes, whose objects are only of use within Finagle. The `Core` project includes the following packages:
235b186 improving readme
Nick Kallen authored
761
f74d889 @mccue Changing contents of README.md to Finagle Developer Guide
mccue authored
762 * `builder` - contains `ClientBuilder`, `ServerBuilder`
763 * `channel`
764 * `http`
765 * `loadbalancer`
766 * `pool`
767 * `service`
768 * `stats`
769 * `tracing`
770 * `util`
235b186 improving readme
Nick Kallen authored
771
f74d889 @mccue Changing contents of README.md to Finagle Developer Guide
mccue authored
772 It also contains packages to support remote procedure calls over Kestrel, Thrift, streams, clusters, and provides statistics collection (Ostrich).
235b186 improving readme
Nick Kallen authored
773
f74d889 @mccue Changing contents of README.md to Finagle Developer Guide
mccue authored
774 The `Util` project contains classes, such as `Future`, which are both generally useful and specifically useful to Finagle.
235b186 improving readme
Nick Kallen authored
775
f74d889 @mccue Changing contents of README.md to Finagle Developer Guide
mccue authored
776 [Top](#Top)
235b186 improving readme
Nick Kallen authored
777
f74d889 @mccue Changing contents of README.md to Finagle Developer Guide
mccue authored
778 <a name="Using Future Objects"></a>
235b186 improving readme
Nick Kallen authored
779
f74d889 @mccue Changing contents of README.md to Finagle Developer Guide
mccue authored
780 ## Using Future Objects
235b186 improving readme
Nick Kallen authored
781
f74d889 @mccue Changing contents of README.md to Finagle Developer Guide
mccue authored
782 In the simplest case, you can use `Future` to block for a request to complete. Consider an example that blocks for an HTTP GET request:
235b186 improving readme
Nick Kallen authored
783
f74d889 @mccue Changing contents of README.md to Finagle Developer Guide
mccue authored
784 // Issue a request, get a response:
785 val request: HttpRequest = new DefaultHttpRequest(HTTP_1_1, GET, "/")
786 val responseFuture: Future[HttpResponse] = client(request)
f3ee11d @evnm [split] Fix deprecated link to ServerSet documentation in README.
evnm authored
787
788 In this example, a client issuing the request will wait forever for a response unless you specified a value for the `requestTimeout` attribute when you built the <a href="#Clients">client</a>.
235b186 improving readme
Nick Kallen authored
789
f74d889 @mccue Changing contents of README.md to Finagle Developer Guide
mccue authored
790 Consider another example:
ec2ae88 @bierbaum updated readme (still needs a lot of work)
bierbaum authored
791
f74d889 @mccue Changing contents of README.md to Finagle Developer Guide
mccue authored
792 val responseFuture: Future[String] = executor.schedule(job)
f3ee11d @evnm [split] Fix deprecated link to ServerSet documentation in README.
evnm authored
793
f74d889 @mccue Changing contents of README.md to Finagle Developer Guide
mccue authored
794 In this example, the value of `responseFuture` is not available until after the scheduled job has finished executing and the caller will block until `responseFuture` has a value.
ec2ae88 @bierbaum updated readme (still needs a lot of work)
bierbaum authored
795
f74d889 @mccue Changing contents of README.md to Finagle Developer Guide
mccue authored
796 [Top](#Top)
d652c54 some tupos
Nick Kallen authored
797
f74d889 @mccue Changing contents of README.md to Finagle Developer Guide
mccue authored
798 <a name="Future Callbacks"></a>
d652c54 some tupos
Nick Kallen authored
799
f74d889 @mccue Changing contents of README.md to Finagle Developer Guide
mccue authored
800 ### Future Callbacks
6feb234 links to Scaladoc for Future and Channel
Nick Kallen authored
801
f74d889 @mccue Changing contents of README.md to Finagle Developer Guide
mccue authored
802 In cases where you want to continue execution immediately, you can specify a callback. The callback is identified by the `onSuccess` keyword:
d652c54 some tupos
Nick Kallen authored
803
f74d889 @mccue Changing contents of README.md to Finagle Developer Guide
mccue authored
804 val request: HttpRequest = new DefaultHttpRequest(HTTP_1_1, GET, "/")
805 val responseFuture: Future[HttpResponse] = client(request)
806 responseFuture onSuccess { responseFuture =>
807 println(responseFuture)
235b186 improving readme
Nick Kallen authored
808 }
ec2ae88 @bierbaum updated readme (still needs a lot of work)
bierbaum authored
809
f74d889 @mccue Changing contents of README.md to Finagle Developer Guide
mccue authored
810 [Top](#Top)
ec2ae88 @bierbaum updated readme (still needs a lot of work)
bierbaum authored
811
f74d889 @mccue Changing contents of README.md to Finagle Developer Guide
mccue authored
812 <a name="Future Timeouts"></a>
d652c54 some tupos
Nick Kallen authored
813
f74d889 @mccue Changing contents of README.md to Finagle Developer Guide
mccue authored
814 ### Future Timeouts
d652c54 some tupos
Nick Kallen authored
815
f74d889 @mccue Changing contents of README.md to Finagle Developer Guide
mccue authored
816 In cases where you want to continue execution after some amount of elapsed time, you can specify the length of time to wait in the `Future` object. The following example waits 1 second before displaying the value of the response:
d652c54 some tupos
Nick Kallen authored
817
f74d889 @mccue Changing contents of README.md to Finagle Developer Guide
mccue authored
818 val request: HttpRequest = new DefaultHttpRequest(HTTP_1_1, GET, "/")
819 val responseFuture: Future[HttpResponse] = client(request)
820 println(responseFuture(1.second))
f3ee11d @evnm [split] Fix deprecated link to ServerSet documentation in README.
evnm authored
821
f74d889 @mccue Changing contents of README.md to Finagle Developer Guide
mccue authored
822 In the above example, you do not know whether the response timed out before the request was satisfied. To determine what kind of response you actually received, you can provide two callbacks, one to handle `onSuccess` conditions and one for `onFailure` conditions. You use the `within` method of `Future` to specify how long to wait for the response. Finagle also creates a `Timer` thread on which to wait until one of the conditions are satisfied. Consider the following example:
391f93d corrected readme
Nick Kallen authored
823
f74d889 @mccue Changing contents of README.md to Finagle Developer Guide
mccue authored
824 import com.twitter.finagle.util.Timer._
825 ...
826 val request: HttpRequest = new DefaultHttpRequest(HTTP_1_1, GET, "/")
827 val responseFuture: Future[HttpResponse] = client(request)
828 responseFuture.within(1.second) onSuccess { response =>
829 println("responseFuture)
830 } onFailure {
831 case e: TimeoutException => ...
391f93d corrected readme
Nick Kallen authored
832 }
833
f74d889 @mccue Changing contents of README.md to Finagle Developer Guide
mccue authored
834 If a timeout occurs, Finagle takes the `onFailure` path. You can use a `TimeoutException` object to display a message or take other actions.
d652c54 some tupos
Nick Kallen authored
835
f74d889 @mccue Changing contents of README.md to Finagle Developer Guide
mccue authored
836 [Top](#Top)
391f93d corrected readme
Nick Kallen authored
837
f74d889 @mccue Changing contents of README.md to Finagle Developer Guide
mccue authored
838 <a name="Future Exceptions"></a>
839
840 ### Future Exceptions
391f93d corrected readme
Nick Kallen authored
841
f74d889 @mccue Changing contents of README.md to Finagle Developer Guide
mccue authored
842 To set up an exception, specify the action in a `try` block and handle failures in a `catch` block. Consider an example that handles `Future` timeouts as an exception:
843
844 val request: HttpRequest = new DefaultHttpRequest(HTTP_1_1, GET, "/")
845 val responseFuture: Future[HttpResponse] = client(request)
d652c54 some tupos
Nick Kallen authored
846 try {
f74d889 @mccue Changing contents of README.md to Finagle Developer Guide
mccue authored
847 println(responseFuture(1.second))
d652c54 some tupos
Nick Kallen authored
848 } catch {
f74d889 @mccue Changing contents of README.md to Finagle Developer Guide
mccue authored
849 case e: TimeoutException => ...
d652c54 some tupos
Nick Kallen authored
850 }
851
f74d889 @mccue Changing contents of README.md to Finagle Developer Guide
mccue authored
852 In this example, after 1 second, either the HTTP response is displayed or the `TimeoutException` is thrown.
853
854 [Top](#Top)
855
856 <a name="Promises"></a>
857
858 ### Promises
859
860 `Promise` is a subclass of `Future`. Although a `Future` can only be read, a `Promise` can be both read and written.
861 Usually a producer makes a `Promise` and casts it to a `Future` before giving it to the consumer. The following example shows how this might be useful in the case where you intend to make a `Future` service but need to anticipate errors:
862
863 def make() = {
864 ...
865 val promise = new Promise[Service[Req, Rep]]
866 ... {
867 case Ok(myObject) =>
868 ...
869 promise() = myConfiguredObject
870 case Error(cause) =>
871 promise() = Throw(new ...Exception(cause))
872 case Cancelled =>
873 promise() = Throw(new WriteException(new ...Exception))
874 }
875 promise
d652c54 some tupos
Nick Kallen authored
876 }
877
f74d889 @mccue Changing contents of README.md to Finagle Developer Guide
mccue authored
878 [Top](#Top)
879
880 <a name="Using Future map and flatMap Operations"></a>
881
882 ### Using Future map and flatMap Operations
883
388ddab streams
Nick Kallen authored
884 In addition to waiting for results to return, `Futures` can be transformed in interesting ways. For instance, it is possible to convert a `Future[String]` to a `Future[Int]` by using `map`:
885
886 val stringFuture: Future[String] = Future("1")
887 val intFuture: Future[Int] = stringFuture map (_.toInt)
888
f74d889 @mccue Changing contents of README.md to Finagle Developer Guide
mccue authored
889 Similar to `map`, you can use `flatMap` to easily _pipeline_ a sequence of `Futures`:
388ddab streams
Nick Kallen authored
890
891 val authenticateUser: Future[User] = User.authenticate(email, password)
892 val lookupTweets: Future[Seq[Tweet]] = authenticateUser flatMap { user =>
893 Tweet.findAllByUser(user)
894 }
895
896 In this example, `Tweet.findAllByUser(user)` is a function of type `User => Future[Seq[Tweet]]`.
d652c54 some tupos
Nick Kallen authored
897
f3ee11d @evnm [split] Fix deprecated link to ServerSet documentation in README.
evnm authored
898 <!--
388ddab streams
Nick Kallen authored
899
f74d889 @mccue Changing contents of README.md to Finagle Developer Guide
mccue authored
900 [Top](#Top)
901
902 <a name="Using Future handle and rescue Operations"></a>
903
904 ### Using Future handle and rescue Operations
388ddab streams
Nick Kallen authored
905
f74d889 @mccue Changing contents of README.md to Finagle Developer Guide
mccue authored
906 // TODO
388ddab streams
Nick Kallen authored
907
f74d889 @mccue Changing contents of README.md to Finagle Developer Guide
mccue authored
908 -->
909
910 [Top](#Top)
911
912 <a name="Using Future in Scatter/Gather Patterns"></a>
913
914 ### Using Future in Scatter/Gather Patterns
915
916 For scatter/gather patterns, the challenge is to issue a series of requests in parallel and wait for all of them to arrive. To wait for a sequence of `Future` objects to return, you can define a sequence to hold the objects and use the `Future.collect` method to wait for them, as follows:
917
918 val myFutures: Seq[Future[Int]] = ...
391f93d corrected readme
Nick Kallen authored
919 val waitTillAllComplete: Future[Seq[Int]] = Future.collect(myFutures)
388ddab streams
Nick Kallen authored
920
f74d889 @mccue Changing contents of README.md to Finagle Developer Guide
mccue authored
921 A more complex variation of scatter/gather pattern is to perform a sequence of asynchronous operations and harvest only those that return within a certain time, ignoring those that don't return within the specified time. For example, you might want to issue a set of parallel requests to _N_ partitions of a search index; those that don't return in time are assumed to be empty. The following example allows 1 second for the query to return:
388ddab streams
Nick Kallen authored
922
923 import com.twitter.finagle.util.Timer._
924
925 val results: Seq[Future[Result]] = partitions.map { partition =>
926 partition.get(query).within(1.second) handle {
927 case _: TimeoutException => EmptyResult
928 }
929 }
391f93d corrected readme
Nick Kallen authored
930 val allResults: Future[Seq[Result]] = Future.collect(timedResults)
388ddab streams
Nick Kallen authored
931
932 allResults onSuccess { results =>
933 println(results)
934 }
d652c54 some tupos
Nick Kallen authored
935
f74d889 @mccue Changing contents of README.md to Finagle Developer Guide
mccue authored
936 [Top](#Top)
ec2ae88 @bierbaum updated readme (still needs a lot of work)
bierbaum authored
937
f74d889 @mccue Changing contents of README.md to Finagle Developer Guide
mccue authored
938 <a name="Using Future Pools"></a>
388ddab streams
Nick Kallen authored
939
f74d889 @mccue Changing contents of README.md to Finagle Developer Guide
mccue authored
940 ### Using Future Pools
6feb234 links to Scaladoc for Future and Channel
Nick Kallen authored
941
f74d889 @mccue Changing contents of README.md to Finagle Developer Guide
mccue authored
942 A `FuturePool` object enables you to place a blocking operation on its own thread. In the following example, a service's `apply` method, which executes in the Finagle event loop, creates the `FuturePool` object and places the blocking operation on a thread associated with the `FuturePool` object. The `apply` method returns immediately without blocking.
388ddab streams
Nick Kallen authored
943
f74d889 @mccue Changing contents of README.md to Finagle Developer Guide
mccue authored
944 class ThriftFileReader extends Service[String, Array[Byte]] {
945 val diskIoFuturePool = FuturePool(Executors.newFixedThreadPool(4))
946
947 def apply(path: String) = {
948 val blockingOperation = {
949 scala.Source.fromFile(path) // potential to block
f3ee11d @evnm [split] Fix deprecated link to ServerSet documentation in README.
evnm authored
950 }
f74d889 @mccue Changing contents of README.md to Finagle Developer Guide
mccue authored
951 // give this blockingOperation to the future pool to execute
952 diskIoFuturePool(blockingOperation)
953 // returns immediately while the future pool executes the operation on a different thread
954 }
388ddab streams
Nick Kallen authored
955 }
956
f74d889 @mccue Changing contents of README.md to Finagle Developer Guide
mccue authored
957 [Top](#Top)
958
959 <a name="Using Future Objects With Java"></a>
960
961 ## Using Future Objects With Java
962
963 A `Future` object in Java is defined as `Future<`_Type_`>`, as in the following example:
f3ee11d @evnm [split] Fix deprecated link to ServerSet documentation in README.
evnm authored
964
f74d889 @mccue Changing contents of README.md to Finagle Developer Guide
mccue authored
965 Future<String> future = executor.schedule(job);
966
967 You must explicitly call the object's `apply` method:
968
969 // Wait indefinitely for result
970 String result = future.apply();
971
972 Arguments to the `apply` method are passed as functions:
388ddab streams
Nick Kallen authored
973
f3ee11d @evnm [split] Fix deprecated link to ServerSet documentation in README.
evnm authored
974 // Wait up to 1 second for result
f74d889 @mccue Changing contents of README.md to Finagle Developer Guide
mccue authored
975 String result = future.apply(Duration.apply(1, SECOND));
388ddab streams
Nick Kallen authored
976
f74d889 @mccue Changing contents of README.md to Finagle Developer Guide
mccue authored
977 There are two styles you can use to wait for a value. The _imperative_ style is the traditional Java programming style. The _functional_ style uses functions as objects and is the basis for Scala. You can use whichever style suits you best.
388ddab streams
Nick Kallen authored
978
f74d889 @mccue Changing contents of README.md to Finagle Developer Guide
mccue authored
979 [Top](#Top)
980
981 <a name="Imperative Java Style"></a>
982
983 ### Imperative Java Style
984
985 The following example shows the _imperative_ style, which uses an event listener that responds to a change in the `Future` object and calls the appropriate method:
986
987 Future<String> future = executor.schedule(job);
f3ee11d @evnm [split] Fix deprecated link to ServerSet documentation in README.
evnm authored
988 future.addEventListener(
f74d889 @mccue Changing contents of README.md to Finagle Developer Guide
mccue authored
989 new FutureEventListener<String>() {
f3ee11d @evnm [split] Fix deprecated link to ServerSet documentation in README.
evnm authored
990 public void onSuccess(String value) {
f74d889 @mccue Changing contents of README.md to Finagle Developer Guide
mccue authored
991 println(value);
992 }
993 public void onFailure(Throwable t) ...
994 }
995 )
996
997 [Top](#Top)
998
999 <a name="Functional Java Style"></a>
388ddab streams
Nick Kallen authored
1000
f74d889 @mccue Changing contents of README.md to Finagle Developer Guide
mccue authored
1001 ### Functional Java Style
388ddab streams
Nick Kallen authored
1002
1003
f74d889 @mccue Changing contents of README.md to Finagle Developer Guide
mccue authored
1004 The following example shows the _functional_ style, which is similar to the way in which you write Scala code:
1005
1006 Future<String> future = executor.schedule(job);
1007 future.onSuccess( new Function<String, Void>() {
1008 public Void apply(String value) { System.out.println(value);
1009 } ).onFailure(...).ensure(...);
1010
1011 The following example shows the _functional_ style for the `map` method:
1012
1013 Future<String> future = executor.schedule(job);
1014 Future<Integer> result = future.map(new Function<String, Integer>() {
1015 public Integer apply(String value) { return Integer.valueOf(value);
1016 }
388ddab streams
Nick Kallen authored
1017
f74d889 @mccue Changing contents of README.md to Finagle Developer Guide
mccue authored
1018 [Top](#Top)
388ddab streams
Nick Kallen authored
1019
f74d889 @mccue Changing contents of README.md to Finagle Developer Guide
mccue authored
1020 <a name="Creating a Service"></a>
388ddab streams
Nick Kallen authored
1021
f74d889 @mccue Changing contents of README.md to Finagle Developer Guide
mccue authored
1022 ## Creating a Service
388ddab streams
Nick Kallen authored
1023
f74d889 @mccue Changing contents of README.md to Finagle Developer Guide
mccue authored
1024 The following example extends the `Service` class to respond to an HTTP request:
1025
1026 class Respond extends Service[HttpRequest, HttpResponse] {
1027 def apply(request: HttpRequest) = {
1028 val response = new DefaultHttpResponse(HTTP_1_1, OK)
1029 response.setContent(copiedBuffer(myContent, UTF_8))
1030 Future.value(response)
1031 }
388ddab streams
Nick Kallen authored
1032 }
f3ee11d @evnm [split] Fix deprecated link to ServerSet documentation in README.
evnm authored
1033
f74d889 @mccue Changing contents of README.md to Finagle Developer Guide
mccue authored
1034 [Top](#Top)
388ddab streams
Nick Kallen authored
1035
f74d889 @mccue Changing contents of README.md to Finagle Developer Guide
mccue authored
1036 <a name="Creating Simple Filters"></a>
388ddab streams
Nick Kallen authored
1037
f74d889 @mccue Changing contents of README.md to Finagle Developer Guide
mccue authored
1038 ## Creating Simple Filters
388ddab streams
Nick Kallen authored
1039
f74d889 @mccue Changing contents of README.md to Finagle Developer Guide
mccue authored
1040 The following example extends the `SimpleFilter` class to throw an exception if the HTTP authorization header contains a different value than the specified string:
1041
1042 class Authorize extends SimpleFilter[HttpRequest, HttpResponse] {
1043 def apply(request: HttpRequest, continue: Service[HttpRequest, HttpResponse]) = {
1044 if ("shared secret" == request.getHeader("Authorization")) {
1045 continue(request)
1046 } else {
1047 Future.exception(new IllegalArgumentException("You don't know the secret"))
1048 }
1049 }
1050 }
391f93d corrected readme
Nick Kallen authored
1051
f74d889 @mccue Changing contents of README.md to Finagle Developer Guide
mccue authored
1052 The following example extends the `SimpleFilter`class to set the HTTP response code if an error occurs and return the error and stack trace in the response:
1053
1054 class HandleExceptions extends SimpleFilter[HttpRequest, HttpResponse] {
1055 def apply(request: HttpRequest, service: Service[HttpRequest, HttpResponse]) = {
1056 service(request) handle { case error =>
1057 val statusCode = error match {
1058 case _: IllegalArgumentException =>
1059 FORBIDDEN
1060 case _ =>
1061 INTERNAL_SERVER_ERROR
1062 }
f3ee11d @evnm [split] Fix deprecated link to ServerSet documentation in README.
evnm authored
1063
f74d889 @mccue Changing contents of README.md to Finagle Developer Guide
mccue authored
1064 val errorResponse = new DefaultHttpResponse(HTTP_1_1, statusCode)
1065 errorResponse.setContent(copiedBuffer(error.getStackTraceString, UTF_8))
1066
1067 errorResponse
1068 }
391f93d corrected readme
Nick Kallen authored
1069 }
1070 }
f3ee11d @evnm [split] Fix deprecated link to ServerSet documentation in README.
evnm authored
1071
f74d889 @mccue Changing contents of README.md to Finagle Developer Guide
mccue authored
1072 [Top](#Top)
391f93d corrected readme
Nick Kallen authored
1073
f74d889 @mccue Changing contents of README.md to Finagle Developer Guide
mccue authored
1074 <a name="Building a Robust Server"></a>
388ddab streams
Nick Kallen authored
1075
f74d889 @mccue Changing contents of README.md to Finagle Developer Guide
mccue authored
1076 ## Building a Robust Server
1077
1078 The following example encapsulates the filters and service in the previous examples and defines the execution order of the filters, followed by the service. The `ServerBuilder` object specifies the service that indicates the execution order along with the codec and IP address on which to bind the service:
391f93d corrected readme
Nick Kallen authored
1079
f74d889 @mccue Changing contents of README.md to Finagle Developer Guide
mccue authored
1080 object HttpServer {
1081 class HandleExceptions extends SimpleFilter[HttpRequest, HttpResponse] {...}
1082 class Authorize extends SimpleFilter[HttpRequest, HttpResponse] {...}
1083 class Respond extends Service[HttpRequest, HttpResponse] {... }
f3ee11d @evnm [split] Fix deprecated link to ServerSet documentation in README.
evnm authored
1084
388ddab streams
Nick Kallen authored
1085
f74d889 @mccue Changing contents of README.md to Finagle Developer Guide
mccue authored
1086 def main(args: Array[String]) {
1087 val handleExceptions = new HandleExceptions
1088 val authorize = new Authorize
1089 val respond = new Respond
1090
f3ee11d @evnm [split] Fix deprecated link to ServerSet documentation in README.
evnm authored
1091 val myService: Service[HttpRequest, HttpResponse]
f74d889 @mccue Changing contents of README.md to Finagle Developer Guide
mccue authored
1092 = handleExceptions andThen authorize andThen respond
1093
1094 val server: Server = ServerBuilder()
1095 .codec(Http)
1096 .bindTo(new InetSocketAddress(8080))
1097 .build(myService)
1098 }
388ddab streams
Nick Kallen authored
1099 }
1100
f74d889 @mccue Changing contents of README.md to Finagle Developer Guide
mccue authored
1101 In this example, the `HandleExceptions` filter is executed before the `authorize` filter. All filters are executed before the service. The server is robust not because of its complexity; rather, it is robust because it uses filters to remove issues before the service executes.
1102
1103 [Top](#Top)
391f93d corrected readme
Nick Kallen authored
1104
f74d889 @mccue Changing contents of README.md to Finagle Developer Guide
mccue authored
1105 <a name="Building a Robust Client"></a>
391f93d corrected readme
Nick Kallen authored
1106
f74d889 @mccue Changing contents of README.md to Finagle Developer Guide
mccue authored
1107 ## Building a Robust Client
1108
f3ee11d @evnm [split] Fix deprecated link to ServerSet documentation in README.
evnm authored
1109 A robust client has little to do with the lines of code (SLOC) that goes into it; rather, the robustness depends on how you configure the client and the testing you put into it. Consider the following HTTP client:
f74d889 @mccue Changing contents of README.md to Finagle Developer Guide
mccue authored
1110
1111 val client = ClientBuilder()
1112 .codec(Http)
1113 .hosts("localhost:10000,localhost:10001,localhost:10003")
1114 .connectionTimeout(1.second) // max time to spend establishing a TCP connection.
1115 .retries(2) // (1) per-request retries
1116 .reportTo(new OstrichStatsReceiver) // export host-level load data to ostrich
1117 .logger(Logger.getLogger("http"))
1118 .build()
1119
1120 The `ClientBuilder` object creates and configures a load balanced HTTP client that balances requests among 3 (local) endpoints. The Finagle balancing strategy is to pick the endpoint with the least number of outstanding requests, which is similar to a *least connections* strategy in other load balancers. The Finagle load balancer deliberately introduces jitter to avoid synchronicity (and thundering herds) in a distributed system. It also supports failover.
1121
1122 The following examples show how to invoke this client from Scala and Java, respectively:
1123
1124 ##### Scala Client Invocation
391f93d corrected readme
Nick Kallen authored
1125
f74d889 @mccue Changing contents of README.md to Finagle Developer Guide
mccue authored
1126 val request: HttpRequest = new DefaultHttpRequest(HTTP_1_1, Get, "/")
1127 val futureResponse: Future[HttpResponse] = client(request)
391f93d corrected readme
Nick Kallen authored
1128
f74d889 @mccue Changing contents of README.md to Finagle Developer Guide
mccue authored
1129 ##### Java Client Invocation
391f93d corrected readme
Nick Kallen authored
1130
f74d889 @mccue Changing contents of README.md to Finagle Developer Guide
mccue authored
1131 HttpRequest request = new DefaultHttpRequest(HTTP_1_1, Get, "/")
1132 Future<HttpResponse> futureResponse = client.apply(request)
391f93d corrected readme
Nick Kallen authored
1133
f74d889 @mccue Changing contents of README.md to Finagle Developer Guide
mccue authored
1134 For information about using `Future` objects with Java, see <a href="#Using Future Objects With Java">Using Future Objects With Java</a>.
391f93d corrected readme
Nick Kallen authored
1135
f74d889 @mccue Changing contents of README.md to Finagle Developer Guide
mccue authored
1136 [Top](#Top)
388ddab streams
Nick Kallen authored
1137
f74d889 @mccue Changing contents of README.md to Finagle Developer Guide
mccue authored
1138 <a name="Creating Filters to Transform Requests and Responses"></a>
1139
1140 ## Creating Filters to Transform Requests and Responses
1141
f3ee11d @evnm [split] Fix deprecated link to ServerSet documentation in README.
evnm authored
1142 The following example extends the `Filter` class to authenticate requests. The request is transformed into an HTTP response before being handled by the `AuthResult` service. In this case, the `RequireAuthentication` filter does not transform the resulting HTTP response:
f74d889 @mccue Changing contents of README.md to Finagle Developer Guide
mccue authored
1143
1144 class RequireAuthentication(val p: ...)
1145 extends Filter[Request, HttpResponse, AuthenticatedRequest, HttpResponse]
1146 {
1147 def apply(request: Request, service: Service[AuthenticatedRequest, HttpResponse]) = {
1148 p.authenticate(request) flatMap {
1149 case AuthResult(AuthResultCode.OK, Some(passport: OAuthPassport), _, _) =>
1150 service(AuthenticatedRequest(request, passport))
1151 case AuthResult(AuthResultCode.OK, Some(passport: SessionPassport), _, _) =>
1152 service(AuthenticatedRequest(request, passport))
1153 case ar: AuthResult =>
1154 Trace.record("Authentication failed with " + ar)
1155 Future.exception(new RequestUnauthenticated(ar.resultCode))
1156 }
1157 }
388ddab streams
Nick Kallen authored
1158 }
1159
f74d889 @mccue Changing contents of README.md to Finagle Developer Guide
mccue authored
1160 In this example, the `flatMap` object enables pipelining of the requests.
d1e2a51 @mariusae opensource finagle-serversets, now that dependencies are
mariusae authored
1161
f74d889 @mccue Changing contents of README.md to Finagle Developer Guide
mccue authored
1162 [Top](#Top)
d1e2a51 @mariusae opensource finagle-serversets, now that dependencies are
mariusae authored
1163
f74d889 @mccue Changing contents of README.md to Finagle Developer Guide
mccue authored
1164 <!--
d1e2a51 @mariusae opensource finagle-serversets, now that dependencies are
mariusae authored
1165
f74d889 @mccue Changing contents of README.md to Finagle Developer Guide
mccue authored
1166 <a name="Creating Combinators to Distribute Processing Tasks"></a>
d1e2a51 @mariusae opensource finagle-serversets, now that dependencies are
mariusae authored
1167
f74d889 @mccue Changing contents of README.md to Finagle Developer Guide
mccue authored
1168 ## Creating Combinators to Distribute Processing Tasks
d1e2a51 @mariusae opensource finagle-serversets, now that dependencies are
mariusae authored
1169
f74d889 @mccue Changing contents of README.md to Finagle Developer Guide
mccue authored
1170 // TODO
d1e2a51 @mariusae opensource finagle-serversets, now that dependencies are
mariusae authored
1171
f74d889 @mccue Changing contents of README.md to Finagle Developer Guide
mccue authored
1172 [Top](#Top)
d1e2a51 @mariusae opensource finagle-serversets, now that dependencies are
mariusae authored
1173
f74d889 @mccue Changing contents of README.md to Finagle Developer Guide
mccue authored
1174 -->
1175
1176 <a name="Using ServerSet Objects"></a>
1177
1178 ## Using ServerSet Objects
1179
f3ee11d @evnm [split] Fix deprecated link to ServerSet documentation in README.
evnm authored
1180 `finagle-serversets` is an implementation of the Finagle Cluster interface using `com.twitter.com.zookeeper` [ServerSets](http://twitter.github.com/commons/apidocs/#com.twitter.common.zookeeper.ServerSet).
f74d889 @mccue Changing contents of README.md to Finagle Developer Guide
mccue authored
1181
1182 You can instantiate a `ServerSet` object as follows:
1183
1184 val serverSet = new ServerSetImpl(zookeeperClient, "/twitter/services/...")
d1e2a51 @mariusae opensource finagle-serversets, now that dependencies are
mariusae authored
1185 val cluster = new ZookeeperServerSetCluster(serverSet)
1186
f74d889 @mccue Changing contents of README.md to Finagle Developer Guide
mccue authored
1187 Servers join a cluster, as in the following example:
d1e2a51 @mariusae opensource finagle-serversets, now that dependencies are
mariusae authored
1188
1189 val serviceAddress = new InetSocketAddress(...)
1190 val server = ServerBuilder()
1191 .bindTo(serviceAddress)
1192 .build()
1193
1194 cluster.join(serviceAddress)
1195
f74d889 @mccue Changing contents of README.md to Finagle Developer Guide
mccue authored
1196 A client can access a cluster, as follows:
d1e2a51 @mariusae opensource finagle-serversets, now that dependencies are
mariusae authored
1197
1198 val client = ClientBuilder()
f74d889 @mccue Changing contents of README.md to Finagle Developer Guide
mccue authored
1199 .cluster(cluster)
d1e2a51 @mariusae opensource finagle-serversets, now that dependencies are
mariusae authored
1200 .codec(new StringCodec)
1201 .build()
1202
f74d889 @mccue Changing contents of README.md to Finagle Developer Guide
mccue authored
1203 [Top](#Top)
1204
1205 <a name="Additional Samples"></a>
1206
1207 ## Additional Samples
1208
1209 * [Echo](https://github.com/twitter/finagle/tree/master/finagle-example/src/main/scala/com/twitter/finagle/example/echo) - A simple echo client and server using a newline-delimited protocol. Illustrates the basics of asynchronous control-flow.
1210 * [Http](https://github.com/twitter/finagle/tree/master/finagle-example/src/main/scala/com/twitter/finagle/example/http) - An advanced HTTP client and server that illustrates the use of Filters to compositionally organize your code. Filters are used here to isolate authentication and error handling concerns.
1211 * [Memcached Proxy](https://github.com/twitter/finagle/tree/master/finagle-example/src/main/scala/com/twitter/finagle/example/memcachedproxy) - A simple proxy supporting the Memcached protocol.
1212 * [Stream](https://github.com/twitter/finagle/tree/master/finagle-example/src/main/scala/com/twitter/finagle/example/stream) - An illustration of Channels, the abstraction for Streaming protocols.
1213 * [Spritzer 2 Kestrel](https://github.com/twitter/finagle/tree/master/finagle-example/src/main/scala/com/twitter/finagle/example/spritzer2kestrel) - An illustration of Channels, the abstraction for Streaming protocols. Here the Twitter Firehose is "piped" into a Kestrel message queue, illustrating some of the compositionality of Channels.
1214 * [Stress](https://github.com/twitter/finagle/tree/master/finagle-example/src/main/scala/com/twitter/finagle/example/stress) - A high-throughput HTTP client for driving stressful traffic to an HTTP server. Illustrates more advanced asynchronous control-flow.
1215 * [Thrift](https://github.com/twitter/finagle/tree/master/finagle-example/src/main/scala/com/twitter/finagle/example/thrift) - A simple client and server for a Thrift protocol.
1216
1217 [Top](#Top)
1218
1219 <a name="API Reference Documentation"></a>
1220
1221 ## API Reference Documentation
1222
d1ba060 @mariusae [split] finagle·doc: fix up API ref links.
mariusae authored
1223 * [Builders](http://twitter.github.com/finagle/api/finagle-core/com/twitter/finagle/builder/package.html)
1224 * [Service](http://twitter.github.com/finagle/api/finagle-core/com/twitter/finagle/Service.html)
f74d889 @mccue Changing contents of README.md to Finagle Developer Guide
mccue authored
1225 * [Future](http://twitter.github.com/util/util-core/target/site/doc/main/api/com/twitter/util/Future.html)
d1ba060 @mariusae [split] finagle·doc: fix up API ref links.
mariusae authored
1226 * [Complete Core Project Scaladoc](http://twitter.github.com/finagle/api/finagle-core/)
f74d889 @mccue Changing contents of README.md to Finagle Developer Guide
mccue authored
1227 * [Complete Util Project Scaladoc](http://twitter.github.com/util/util-core/target/site/doc/main/api/)
1228
d1ba060 @mariusae [split] finagle·doc: fix up API ref links.
mariusae authored
1229 See the [finagle homepage](http://twitter.github.com/finagle/) for more information.
1230
f74d889 @mccue Changing contents of README.md to Finagle Developer Guide
mccue authored
1231 [Top](#Top)
d3f0050 @mariusae include changelog in README
mariusae authored
1232
Something went wrong with that request. Please try again.