1
1
[[future_mode]]
2
2
== Future Mode
3
3
4
- The client offers a mode called "future" or "async" mode. This allows batch processing of requests (sent in parallel
5
- to the cluster), which can have a dramatic impact on performance and throughput.
4
+ The client offers a mode called "future" or "async" mode. This allows batch
5
+ processing of requests (sent in parallel to the cluster), which can have a
6
+ dramatic impact on performance and throughput.
6
7
7
- PHP is fundamentally single-threaded, however libcurl provides functionality called the "multi interface". This allows
8
- languages like PHP to gain concurrency by providing a batch of requests to process. The batch is executed in a parallel
9
- by the underlying multithreaded libcurl library, and the batch of responses is then returned to PHP.
8
+ PHP is fundamentally single-threaded, however, libcurl provides a functionality
9
+ called the "multi interface". This functionality allows languages like PHP to
10
+ gain concurrency by providing a batch of requests to process. The batch is
11
+ executed in parallel by the underlying multithreaded libcurl library, and the
12
+ batch of responses is then returned to PHP.
10
13
11
- In a single-threaded environment, the time to execute `n` requests is the sum of those `n` request's latencies. With
12
- the multi interface, the time to execute `n` requests is the latency of the slowest request (assuming enough handles
13
- are available to execute all requests in parallel).
14
+ In a single-threaded environment, the time to execute `n` requests is the sum of
15
+ those `n` request's latencies. With the multi interface, the time to execute `n`
16
+ requests is the latency of the slowest request (assuming enough handles are
17
+ available to execute all requests in parallel).
18
+
19
+ Furthermore, the multi-interface allows requests to different hosts
20
+ simultaneously, which means the Elasticsearch-PHP client can more effectively
21
+ utilize your full cluster.
14
22
15
- Furthermore, the multi-interface allows requests to different hosts simultaneously, which means the Elasticsearch-PHP
16
- client can more effectively utilize your full cluster.
17
23
18
24
=== Using Future Mode
19
25
20
- Utilizing this feature is relatively straightforward, but it does introduce more responsibility into your code. To enable
21
- future mode, set the `future` flag in the client options to `'lazy'`:
26
+ Utilizing this feature is straightforward, but it does introduce more
27
+ responsibility into your code. To enable future mode, set the `future` flag in
28
+ the client options to `'lazy'`:
22
29
23
30
[source,php]
24
31
----
@@ -35,17 +42,22 @@ $params = [
35
42
$future = $client->get($params);
36
43
----
37
44
38
- This will return a _future_, rather than the actual response. A future represents a _future computation_ and acts like
39
- a placeholder. You can pass a future around your code like a regular object. When you need the result values, you
40
- can _resolve_ the future. If the future has already resolved (due to some other activity), the values will be immediately
41
- available. If the future has not resolved yet, the resolution will block until those values have become available (e.g.
45
+ This returns a _future_, rather than the actual response. A future represents a
46
+ _future computation_ and acts like a placeholder. You can pass a future around
47
+ your code like a regular object. When you need the result values, you can
48
+ _resolve_ the future. If the future has already resolved (due to some other
49
+ activity), the values are immediately available. If the future has not resolved
50
+ yet, the resolution blocks until those values become available (for example,
42
51
after the API call completes).
43
52
44
- In practice, this means you can queue up a batch of requests by using `future: lazy` and they will pend until you resolve
45
- the futures, at which time all requests will be sent in parallel to the cluster and return asynchronously to curl.
53
+ In practice, this means you can queue up a batch of requests by using
54
+ `future: lazy` and they pend until you resolve the futures, at which time all
55
+ requests will be sent in parallel to the cluster and return asynchronously to
56
+ curl.
46
57
47
- This sounds tricky, but it is actually very simple thanks to RingPHP's `FutureArray` interface, which makes the future
48
- act like a simple associative array. For example:
58
+ This sounds tricky, but it is actually simple thanks to RingPHP's `FutureArray`
59
+ interface, which makes the future act like a simple associative array. For
60
+ example:
49
61
50
62
[source,php]
51
63
----
@@ -61,11 +73,12 @@ $params = [
61
73
62
74
$future = $client->get($params);
63
75
64
- $doc = $future['_source']; // This call will block and force the future to resolve
76
+ $doc = $future['_source']; // This call blocks and forces the future to resolve
65
77
----
66
78
67
- Interacting with the future as an associative array, just like a normal response, will cause the future to resolve
68
- that particular value (which in turn resolves all pending requests and values). This allows patterns such as:
79
+ Interacting with the future as an associative array, just like a normal
80
+ response, causes the future to resolve that particular value (which in turn
81
+ resolves all pending requests and values). This allows patterns such as:
69
82
70
83
[source,php]
71
84
----
@@ -91,11 +104,11 @@ foreach ($futures as $future) {
91
104
}
92
105
----
93
106
94
- The queued requests will execute in parallel and populate their futures after execution. Batch size defaults to
95
- 100 requests-per- batch.
107
+ The queued requests will execute in parallel and populate their futures after
108
+ execution. Batch size defaults to 100 requests/ batch.
96
109
97
- If you wish to force future resolution, but don't actually need the values immediately, you can call `wait()` on the future
98
- to force resolution too:
110
+ If you wish to force future resolution, but don't need the values immediately,
111
+ you can call `wait()` on the future to force resolution, too:
99
112
100
113
[source,php]
101
114
----
@@ -120,9 +133,10 @@ $futures[999]->wait();
120
133
121
134
=== Changing batch size
122
135
123
- The default batch size is 100, meaning 100 requests will queue up before the client forces futures to begin resolving
124
- (e.g. initiate a `curl_multi` call). The batch size can be changed depending on your preferences. The batch size
125
- is controllable via the `max_handles` setting when configuring the handler:
136
+ The default batch size is 100, meaning 100 requests queue up before the client
137
+ forces futures to begin resolving (for example, initiate a `curl_multi` call).
138
+ The batch size can be changed depending on your preferences. The batch size can
139
+ be set via the `max_handles` setting when configuring the handler:
126
140
127
141
[source,php]
128
142
----
@@ -137,10 +151,11 @@ $client = ClientBuilder::create()
137
151
->build();
138
152
----
139
153
140
- This will change the behavior to wait on 500 queued requests before sending the batch. Note, however, that forcing a
141
- future to resolve will cause the underlying curl batch to execute, regardless of if the batch is "full" or not. In this
142
- example, only 499 requests are added to the queue...but the final future resolution will force the batch to flush
143
- anyway:
154
+ This changes the behavior to wait on 500 queued requests before sending the
155
+ batch. Note, however, that forcing a future to resolve causes the underlying
156
+ curl batch to execute, regardless of if the batch is "full" or not. In this
157
+ example, only 499 requests are added to the queue, but the final future
158
+ resolution forces the batch to flush anyway:
144
159
145
160
[source,php]
146
161
----
@@ -172,10 +187,11 @@ for ($i = 0; $i < 499; $i++) {
172
187
$body = $future[499]['body'];
173
188
----
174
189
190
+
175
191
=== Heterogeneous batches are OK
176
192
177
- It is possible to queue up heterogeneous batches of requests. For example, you can queue up several GETs, indexing requests
178
- and a search:
193
+ It is possible to queue up heterogeneous batches of requests. For example, you
194
+ can queue up several GETs, indexing requests, and a search:
179
195
180
196
[source,php]
181
197
----
@@ -228,24 +244,30 @@ $searchResults = $futures['searchRequest']['hits'];
228
244
$doc = $futures['getRequest']['_source'];
229
245
----
230
246
247
+
231
248
=== Caveats to Future mode
232
249
233
- There are a few caveats to using future mode. The biggest is also the most obvious: you need to deal with resolving the
234
- future yourself. This is usually trivial, but can sometimes introduce unexpected complications.
250
+ There are a few caveats to using future mode. The biggest is also the most
251
+ obvious: you need to deal with resolving the future yourself. This is usually
252
+ trivial, but can sometimes introduce unexpected complications.
235
253
236
- For example, if you resolve manually using `wait()`, you may need to call `wait()` several times if there were retries.
237
- This is because each retry will introduce another layer of wrapped futures, and each needs to be resolved to get the
238
- final result.
254
+ For example, if you resolve manually using `wait()`, you may need to call
255
+ `wait()` several times if there were retries. This is because each retry
256
+ introduces another layer of wrapped futures, and each needs to be resolved to
257
+ get the final result.
239
258
240
- This is not needed if you access values via the ArrayInterface however (e.g. `$response['hits']['hits']`), since
241
- FutureArrayInterface will automatically and fully resolve the future to provide values.
259
+ However, this is not needed if you access values via the ArrayInterface (for
260
+ example, `$response['hits']['hits']`) since FutureArrayInterface automatically
261
+ and fully resolves the future to provide values.
242
262
243
- Another caveat is that certain APIs will lose their "helper" functionality. For example, "exists" APIs (e.g.
244
- `$client->exists()`, `$client->indices()->exists`, `$client->indices->templateExists()`, etc) typically return a true
245
- or false under normal operation.
263
+ Another caveat is that certain APIs will lose their "helper" functionality. For
264
+ example, "exists" APIs (`$client->exists()`, `$client->indices()->exists`,
265
+ `$client->indices->templateExists()`, and so on) typically return a true or
266
+ false under normal operation.
246
267
247
- When operated in future mode, unwrapping of the future is left to your application,
248
- which means the client can no longer inspect the response and return a simple true/false. Instead, you'll see the raw
249
- response from Elasticsearch and will have to take action appropriately.
268
+ When operated in future mode, the unwrapping of the future is left to your
269
+ application, which means the client can no longer inspect the response and
270
+ return a simple true/false. Instead, you'll see the raw response from {es} and
271
+ will have to take action appropriately.
250
272
251
273
This also applies to `ping()`.
0 commit comments