@@ -4,9 +4,10 @@ Drift Client is a simple library for creating Thrift clients using annotations.
4
4
5
5
## Implementing a Client
6
6
7
- In Drift, a Thrift client is simply a Java interface annotated with ` @ThriftService ` . In
7
+ In Drift, a Thrift client is simply a Java interface annotated with ` @ThriftService ` . In
8
8
addition to annotating the interface directly, Drift supports annotations on super interfaces.
9
9
For example, the following describes a Scribe client:
10
+
10
11
``` java
11
12
@ThriftService
12
13
public interface Scribe
@@ -15,8 +16,10 @@ public interface Scribe
15
16
ResultCode log (List<LogEntry > messages );
16
17
}
17
18
```
19
+
18
20
To make the client method asynchronous, simply change the return type of the
19
21
corresponding method to a ` ListenableFuture ` , as shown here:
22
+
20
23
``` java
21
24
@ThriftService
22
25
public interface Scribe
@@ -25,6 +28,7 @@ public interface Scribe
25
28
ListenableFuture<List<Integer > > getValues ();
26
29
}
27
30
```
31
+
28
32
The future will be completed when the server returns a value. When adding listeners
29
33
that do non-trivial work when the future is completed, keep in mind that if you do not
30
34
provide an executor for listeners to run on, they will run on the NIO threads, and
@@ -38,6 +42,7 @@ parameters are numbered starting with `1`. If you do not specify a name, Drift
38
42
will attempt to determine the names automatically. For this to work, the code
39
43
must be compiled with parameter names enabled (pass the ` -parameters ` option to ` javac ` ).
40
44
If you want to use a different ID or name, simply annotate the parameter as follows:
45
+
41
46
``` java
42
47
@ThriftService
43
48
public interface Scribe
@@ -54,6 +59,7 @@ zero being a standard return and exceptions be stored in higher number fields.
54
59
If the Java method throws only one exception annotated with ` @ThriftStruct ` ,
55
60
Drift will assume the result struct field id is ` 1 ` . Otherwise, you will need to
56
61
add the extremely verbose ` @ThriftException ` annotations as follows:
62
+
57
63
``` java
58
64
@ThriftMethod (exception = {
59
65
@ThriftException (type = MyException . class, id = 1 ),
@@ -67,7 +73,7 @@ void doSomething() throws MyException, MyOther;
67
73
A Drift client is thread safe and concurrent, so it can be used by multiple threads
68
74
at the same time. The user of the client simply calls methods on the interface and Drift
69
75
manages address selection and connection pooling. For example:
70
-
76
+
71
77
``` java
72
78
// create client factory (only create this expensive object once)
73
79
DriftClientFactory clientFactory = // see below
@@ -76,27 +82,35 @@ DriftClientFactory clientFactory = // see below
76
82
Scribe scribe = clientFactory. createDriftClient(Scribe . class);
77
83
78
84
// use client
79
- scribe. log(Arrays . asList (new LogEntry (" category" , " message" )));
85
+ scribe. log(ImmutableList . of (new LogEntry (" category" , " message" )));
80
86
```
81
87
82
88
A Drift client can either be created manually using a static factory or injected using Guice.
83
89
84
90
## Static Drift Client Factory
85
91
86
- The following code manually constructs a ` DriftClientFactory ` using the Netty transport:
92
+ The following code manually constructs a ` DriftClientFactory ` using the Netty transport:
93
+
87
94
``` java
95
+ // server address
96
+ List<HostAndPort > addresses = ImmutableList . of(HostAndPort . fromParts(" localhost" , 1234 ));
97
+
88
98
// expensive services that should only be created once
89
99
ThriftCodecManager codecManager = new ThriftCodecManager ();
90
- AddressSelector addressSelector = new SimpleAddressSelector (scribeHostAddresses );
100
+ AddressSelector addressSelector = new SimpleAddressSelector (addresses );
91
101
DriftNettyClientConfig config = new DriftNettyClientConfig ();
92
- // methodInvokerFactory must be closed
93
- DriftNettyMethodInvokerFactory<?> methodInvokerFactory = DriftNettyMethodInvokerFactory . createStaticDriftNettyMethodInvokerFactory(config);
102
+
103
+ // methodInvokerFactory must be closed
104
+ DriftNettyMethodInvokerFactory<?> methodInvokerFactory = DriftNettyMethodInvokerFactory
105
+ .createStaticDriftNettyMethodInvokerFactory(config);
106
+
107
+ // client factory
94
108
DriftClientFactory clientFactory = new DriftClientFactory (codecManager, methodInvokerFactory, addressSelector);
95
109
```
96
110
97
- As you can see, the construction of a ` DriftClientFactory ` requires a few supporting
111
+ As you can see, the construction of a ` DriftClientFactory ` requires a few supporting
98
112
services, which are described below.
99
-
113
+
100
114
### ThriftCodecManager
101
115
102
116
A ` ThriftCodecManager ` caches the description of every Thrift type used by the clients. Extracting
@@ -105,7 +119,7 @@ all the clients you will need.
105
119
106
120
### AddressSelector
107
121
108
- An ` AddressSelector ` selects host addresses for the client to connect to. Typically,
122
+ An ` AddressSelector ` selects host addresses for the client to connect to. Typically,
109
123
this service tracks all hosts running the service and selects a random subset to try
110
124
for an invocation. The ` AddressSelector ` is also notified of addresses that failed to
111
125
connect, allowing it to perform simple tracking of host state.
@@ -119,36 +133,31 @@ method is typically provided to shutdown the pools.
119
133
120
134
There are currently two transport implementations of ` MethodInvokerFactory ` . Drift Netty, which
121
135
is used in the example above, provides ` DriftNettyMethodInvokerFactory ` , and Apache Thrift provides
122
- ` ApacheThriftMethodInvokerFactory ` . Each transport requires sightly different configuration,
136
+ ` ApacheThriftMethodInvokerFactory ` . Each transport requires sightly different configuration,
123
137
so each transport provides a different configuration class.
124
138
125
139
## Guice Support
126
140
127
141
Drift includes optional support for binding clients into Guice.
128
142
129
- To bind a client, add the ` ThriftClientModule ` and a transport implementation module (e.g.,
130
- ` DriftNettyClientModule ` or ` ApacheThriftClientModule ` ), and bind the clients with the fluent
131
- ` DriftClientBinder ` . The following binds a ` Scribe ` client that will connect to
132
- ` example.com:1234 ` by default.
143
+ To bind a client, add a transport implementation module (e.g., ` DriftNettyClientModule ` or
144
+ ` ApacheThriftClientModule ` ), and bind the clients with the fluent ` DriftClientBinder ` .
145
+ The following binds a ` Scribe ` client that will connect to ` example.com:1234 ` by default:
133
146
134
147
``` java
148
+ // server address
149
+ List<HostAndPort > addresses = ImmutableList . of(HostAndPort . fromParts(" localhost" , 1234 ));
150
+
135
151
// see io.airlift.bootstrap.Bootstrap for a simpler system to create Guice services with configuration
136
152
Injector injector = Guice . createInjector(Stage . PRODUCTION ,
137
- new ConfigurationModule (new ConfigurationFactory (ImmutableMap . <> of())),
138
- new ThriftCodecModule (),
153
+ new ConfigurationModule (new ConfigurationFactory (ImmutableMap . of())),
139
154
new DriftNettyClientModule (),
140
- new Module ()
141
- {
142
- @Override
143
- public void configure(Binder binder)
144
- {
145
- driftClientBinder(binder). bindDriftClient(Scribe . class)
146
- .withAddressSelector(simpleAddressSelector(HostAndPort . fromParts(" example.com" , 1234 )));
147
- }
148
- });
155
+ binder - > driftClientBinder(binder). bindDriftClient(Scribe . class)
156
+ .withAddressSelector(simpleAddressSelector(addresses)));
149
157
```
150
158
151
- Then, Guice can inject a Thrift client implementation. For example:
159
+ Then, Guice can inject a Thrift client implementation:
160
+
152
161
``` java
153
162
@Inject
154
163
public MyClass(Scribe scribeClient)
0 commit comments