@@ -27,6 +27,7 @@ It enables you to set and query its data or use its PubSub topics to react to in
2727* [ Usage] ( #usage )
2828 * [ Factory] ( #factory )
2929 * [ createClient()] ( #createclient )
30+ * [ createLazyClient()] ( #createlazyclient )
3031 * [ Client] ( #client )
3132 * [ Commands] ( #commands )
3233 * [ Promises] ( #promises )
@@ -46,23 +47,22 @@ local Redis server and send some requests:
4647$loop = React\EventLoop\Factory::create();
4748$factory = new Factory($loop);
4849
49- $factory->createClient('localhost')->then(function (Client $client) use ($loop) {
50- $client->set('greeting', 'Hello world');
51- $client->append('greeting', '!');
52-
53- $client->get('greeting')->then(function ($greeting) {
54- // Hello world!
55- echo $greeting . PHP_EOL;
56- });
57-
58- $client->incr('invocation')->then(function ($n) {
59- echo 'This is invocation #' . $n . PHP_EOL;
60- });
61-
62- // end connection once all pending requests have been resolved
63- $client->end();
50+ $client = $factory->createLazyClient('localhost');
51+ $client->set('greeting', 'Hello world');
52+ $client->append('greeting', '!');
53+
54+ $client->get('greeting')->then(function ($greeting) {
55+ // Hello world!
56+ echo $greeting . PHP_EOL;
57+ });
58+
59+ $client->incr('invocation')->then(function ($n) {
60+ echo 'This is invocation #' . $n . PHP_EOL;
6461});
6562
63+ // end connection once all pending requests have been resolved
64+ $client->end();
65+
6666$loop->run();
6767```
6868
@@ -100,7 +100,7 @@ $factory = new Factory($loop, $connector);
100100
101101#### createClient()
102102
103- The ` createClient($redisUri): PromiseInterface<Client,Exception> ` method can be used to
103+ The ` createClient(string $redisUri): PromiseInterface<Client,Exception> ` method can be used to
104104create a new [ ` Client ` ] ( #client ) .
105105
106106It helps with establishing a plain TCP/IP or secure TLS connection to Redis
@@ -195,6 +195,139 @@ authentication. You can explicitly pass a custom timeout value in seconds
195195$factory->createClient('localhost?timeout=0.5');
196196```
197197
198+ #### createLazyClient()
199+
200+ The ` createLazyClient(string $redisUri): Client ` method can be used to
201+ create a new [ ` Client ` ] ( #client ) .
202+
203+ It helps with establishing a plain TCP/IP or secure TLS connection to Redis
204+ and optionally authenticating (AUTH) and selecting the right database (SELECT).
205+
206+ ``` php
207+ $client = $factory->createLazyClient('redis://localhost:6379');
208+
209+ $client->incr('hello');
210+ $client->end();
211+ ```
212+
213+ This method immediately returns a "virtual" connection implementing the
214+ [ ` Client ` ] ( #client ) that can be used to interface with your Redis database.
215+ Internally, it lazily creates the underlying database connection only on
216+ demand once the first request is invoked on this instance and will queue
217+ all outstanding requests until the underlying connection is ready.
218+ Additionally, it will only keep this underlying connection in an "idle" state
219+ for 60s by default and will automatically close the underlying connection when
220+ it is no longer needed.
221+
222+ From a consumer side this means that you can start sending commands to the
223+ database right away while the underlying connection may still be
224+ outstanding. Because creating this underlying connection may take some
225+ time, it will enqueue all oustanding commands and will ensure that all
226+ commands will be executed in correct order once the connection is ready.
227+ In other words, this "virtual" connection behaves just like a "real"
228+ connection as described in the ` Client ` interface and frees you from having
229+ to deal with its async resolution.
230+
231+ If the underlying database connection fails, it will reject all
232+ outstanding commands and will return to the initial "idle" state. This
233+ means that you can keep sending additional commands at a later time which
234+ will again try to open a new underlying connection. Note that this may
235+ require special care if you're using transactions (` MULTI ` /` EXEC ` ) that are kept
236+ open for longer than the idle period.
237+
238+ While using PubSub channels (see ` SUBSCRIBE ` and ` PSUBSCRIBE ` commands), this client
239+ will never reach an "idle" state and will keep pending forever (or until the
240+ underlying database connection is lost). Additionally, if the underlying
241+ database connection drops, it will automatically send the appropriate ` unsubscribe `
242+ and ` punsubscribe ` events for all currently active channel and pattern subscriptions.
243+ This allows you to react to these events and restore your subscriptions by
244+ creating a new underlying connection repeating the above commands again.
245+
246+ Note that creating the underlying connection will be deferred until the
247+ first request is invoked. Accordingly, any eventual connection issues
248+ will be detected once this instance is first used. You can use the
249+ ` end() ` method to ensure that the "virtual" connection will be soft-closed
250+ and no further commands can be enqueued. Similarly, calling ` end() ` on
251+ this instance when not currently connected will succeed immediately and
252+ will not have to wait for an actual underlying connection.
253+
254+ Depending on your particular use case, you may prefer this method or the
255+ underlying ` createClient() ` which resolves with a promise. For many
256+ simple use cases it may be easier to create a lazy connection.
257+
258+ The ` $redisUri ` can be given in the
259+ [ standard] ( https://www.iana.org/assignments/uri-schemes/prov/redis ) form
260+ ` [redis[s]://][:auth@]host[:port][/db] ` .
261+ You can omit the URI scheme and port if you're connecting to the default port 6379:
262+
263+ ``` php
264+ // both are equivalent due to defaults being applied
265+ $factory->createLazyClient('localhost');
266+ $factory->createLazyClient('redis://localhost:6379');
267+ ```
268+
269+ Redis supports password-based authentication (` AUTH ` command). Note that Redis'
270+ authentication mechanism does not employ a username, so you can pass the
271+ password ` h@llo ` URL-encoded (percent-encoded) as part of the URI like this:
272+
273+ ``` php
274+ // all forms are equivalent
275+ $factory->createLazyClient('redis://:h%40llo@localhost');
276+ $factory->createLazyClient('redis://ignored:h%40llo@localhost');
277+ $factory->createLazyClient('redis://localhost?password=h%40llo');
278+ ```
279+
280+ You can optionally include a path that will be used to select (SELECT command) the right database:
281+
282+ ``` php
283+ // both forms are equivalent
284+ $factory->createLazyClient('redis://localhost/2');
285+ $factory->createLazyClient('redis://localhost?db=2');
286+ ```
287+
288+ You can use the [ standard] ( https://www.iana.org/assignments/uri-schemes/prov/rediss )
289+ ` rediss:// ` URI scheme if you're using a secure TLS proxy in front of Redis:
290+
291+ ``` php
292+ $factory->createLazyClient('rediss://redis.example.com:6340');
293+ ```
294+
295+ You can use the ` redis+unix:// ` URI scheme if your Redis instance is listening
296+ on a Unix domain socket (UDS) path:
297+
298+ ``` php
299+ $factory->createLazyClient('redis+unix:///tmp/redis.sock');
300+
301+ // the URI MAY contain `password` and `db` query parameters as seen above
302+ $factory->createLazyClient('redis+unix:///tmp/redis.sock?password=secret&db=2');
303+
304+ // the URI MAY contain authentication details as userinfo as seen above
305+ // should be used with care, also note that database can not be passed as path
306+ $factory->createLazyClient('redis+unix://:secret@/tmp/redis.sock');
307+ ```
308+
309+ This method respects PHP's ` default_socket_timeout ` setting (default 60s)
310+ as a timeout for establishing the underlying connection and waiting for
311+ successful authentication. You can explicitly pass a custom timeout value
312+ in seconds (or use a negative number to not apply a timeout) like this:
313+
314+ ``` php
315+ $factory->createLazyClient('localhost?timeout=0.5');
316+ ```
317+
318+ By default, this method will keep "idle" connection open for 60s and will
319+ then end the underlying connection. The next request after an "idle"
320+ connection ended will automatically create a new underlying connection.
321+ This ensure you always get a "fresh" connection and as such should not be
322+ confused with a "keepalive" or "heartbeat" mechanism, as this will not
323+ actively try to probe the connection. You can explicitly pass a custom
324+ idle timeout value in seconds (or use a negative number to not apply a
325+ timeout) like this:
326+
327+ ``` php
328+ $factory->createLazyClient('localhost?idle=0.1');
329+ ```
330+
198331### Client
199332
200333The ` Client ` is responsible for exchanging messages with Redis
0 commit comments