Skip to content

Commit e89ae33

Browse files
committed
Add new public callAsync() method
1 parent 194370d commit e89ae33

File tree

3 files changed

+103
-13
lines changed

3 files changed

+103
-13
lines changed

README.md

+42-1
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@ It enables you to set and query its data or use its PubSub topics to react to in
4747
* [RedisClient](#redisclient)
4848
* [__construct()](#__construct)
4949
* [__call()](#__call)
50+
* [callAsync()](#callasync)
5051
* [end()](#end)
5152
* [close()](#close)
5253
* [error event](#error-event)
@@ -124,7 +125,8 @@ Each method call matches the respective [Redis command](https://redis.io/command
124125
For example, the `$redis->get()` method will invoke the [`GET` command](https://redis.io/commands/get).
125126

126127
All [Redis commands](https://redis.io/commands) are automatically available as
127-
public methods via the magic [`__call()` method](#__call).
128+
public methods via the magic [`__call()` method](#__call) or through the more
129+
explicit [`callAsync()` method].
128130
Listing all available commands is out of scope here, please refer to the
129131
[Redis command reference](https://redis.io/commands).
130132

@@ -432,6 +434,8 @@ $redis->get($key)->then(function (?string $value) {
432434

433435
All [Redis commands](https://redis.io/commands) are automatically available as
434436
public methods via this magic `__call()` method.
437+
Note that some static analysis tools may not understand this magic method, so
438+
you may also the [`callAsync()` method](#callasync) as a more explicit alternative.
435439
Listing all available commands is out of scope here, please refer to the
436440
[Redis command reference](https://redis.io/commands).
437441

@@ -445,6 +449,43 @@ Each of these commands supports async operation and returns a [Promise](#promise
445449
that eventually *fulfills* with its *results* on success or *rejects* with an
446450
`Exception` on error. See also [promises](#promises) for more details.
447451

452+
#### callAsync()
453+
454+
The `callAsync(string $command, string ...$args): PromiseInterface<mixed>` method can be used to
455+
invoke a Redis command.
456+
457+
```php
458+
$redis->callAsync('GET', 'name')->then(function (?string $name): void {
459+
echo 'Name: ' . ($name ?? 'Unknown') . PHP_EOL;
460+
}, function (Throwable $e): void {
461+
echo 'Error: ' . $e->getMessage() . PHP_EOL;
462+
});
463+
```
464+
465+
The `string $command` parameter can be any valid Redis command. All
466+
[Redis commands](https://redis.io/commands/) are available through this
467+
method. As an alternative, you may also use the magic
468+
[`__call()` method](#__call), but note that not all static analysis tools
469+
may understand this magic method. Listing all available commands is out
470+
of scope here, please refer to the
471+
[Redis command reference](https://redis.io/commands).
472+
473+
The optional `string ...$args` parameter can be used to pass any
474+
additional arguments to the Redis command. Some commands may require or
475+
support additional arguments that this method will simply forward as is.
476+
Internally, Redis requires all arguments to be coerced to `string` values,
477+
but you may also rely on PHP's type-juggling semantics and pass `int` or
478+
`float` values:
479+
480+
```php
481+
$redis->callAsync('SET', 'name', 'Alice', 'EX', 600);
482+
```
483+
484+
This method supports async operation and returns a [Promise](#promises)
485+
that eventually *fulfills* with its *results* on success or *rejects*
486+
with an `Exception` on error. See also [promises](#promises) for more
487+
details.
488+
448489
#### end()
449490

450491
The `end():void` method can be used to

examples/cli.php

+8-8
Original file line numberDiff line numberDiff line change
@@ -23,20 +23,20 @@
2323
return;
2424
}
2525

26-
$params = explode(' ', $line);
27-
$method = array_shift($params);
28-
29-
assert(is_callable([$redis, $method]));
30-
$promise = $redis->$method(...$params);
26+
$args = explode(' ', $line);
27+
$command = strtolower(array_shift($args));
3128

3229
// special method such as end() / close() called
33-
if (!$promise instanceof React\Promise\PromiseInterface) {
30+
if (in_array($command, ['end', 'close'])) {
31+
$redis->$command();
3432
return;
3533
}
3634

37-
$promise->then(function ($data) {
35+
$promise = $redis->callAsync($command, ...$args);
36+
37+
$promise->then(function ($data): void {
3838
echo '# reply: ' . json_encode($data) . PHP_EOL;
39-
}, function ($e) {
39+
}, function (Throwable $e): void {
4040
echo '# error reply: ' . $e->getMessage() . PHP_EOL;
4141
});
4242
});

src/RedisClient.php

+53-4
Original file line numberDiff line numberDiff line change
@@ -160,16 +160,65 @@ private function client(): PromiseInterface
160160
}
161161

162162
/**
163-
* Invoke the given command and return a Promise that will be resolved when the request has been replied to
163+
* Invoke the given command and return a Promise that will be resolved when the command has been replied to
164164
*
165165
* This is a magic method that will be invoked when calling any redis
166-
* command on this instance.
166+
* command on this instance. See also `RedisClient::callAsync()`.
167167
*
168168
* @param string $name
169169
* @param string[] $args
170170
* @return PromiseInterface<mixed>
171+
* @see self::callAsync()
171172
*/
172173
public function __call(string $name, array $args): PromiseInterface
174+
{
175+
return $this->callAsync($name, ...$args);
176+
}
177+
178+
/**
179+
* Invoke a Redis command.
180+
*
181+
* For example, the [`GET` command](https://redis.io/commands/get) can be invoked
182+
* like this:
183+
*
184+
* ```php
185+
* $redis->callAsync('GET', 'name')->then(function (?string $name): void {
186+
* echo 'Name: ' . ($name ?? 'Unknown') . PHP_EOL;
187+
* }, function (Throwable $e): void {
188+
* echo 'Error: ' . $e->getMessage() . PHP_EOL;
189+
* });
190+
* ```
191+
*
192+
* The `string $command` parameter can be any valid Redis command. All
193+
* [Redis commands](https://redis.io/commands/) are available through this
194+
* method. As an alternative, you may also use the magic
195+
* [`__call()` method](#__call), but note that not all static analysis tools
196+
* may understand this magic method. Listing all available commands is out
197+
* of scope here, please refer to the
198+
* [Redis command reference](https://redis.io/commands).
199+
*
200+
* The optional `string ...$args` parameter can be used to pass any
201+
* additional arguments to the Redis command. Some commands may require or
202+
* support additional arguments that this method will simply forward as is.
203+
* Internally, Redis requires all arguments to be coerced to `string` values,
204+
* but you may also rely on PHP's type-juggling semantics and pass `int` or
205+
* `float` values:
206+
*
207+
* ```php
208+
* $redis->callAsync('SET', 'name', 'Alice', 'EX', 600);
209+
* ```
210+
*
211+
* This method supports async operation and returns a [Promise](#promises)
212+
* that eventually *fulfills* with its *results* on success or *rejects*
213+
* with an `Exception` on error. See also [promises](#promises) for more
214+
* details.
215+
*
216+
* @param string $command
217+
* @param string ...$args
218+
* @return PromiseInterface<mixed>
219+
* @throws void
220+
*/
221+
public function callAsync(string $command, string ...$args): PromiseInterface
173222
{
174223
if ($this->closed) {
175224
return reject(new \RuntimeException(
@@ -178,9 +227,9 @@ public function __call(string $name, array $args): PromiseInterface
178227
));
179228
}
180229

181-
return $this->client()->then(function (StreamingClient $redis) use ($name, $args): PromiseInterface {
230+
return $this->client()->then(function (StreamingClient $redis) use ($command, $args): PromiseInterface {
182231
$this->awake();
183-
return $redis->callAsync($name, ...$args)->then(
232+
return $redis->callAsync($command, ...$args)->then(
184233
function ($result) {
185234
$this->idle();
186235
return $result;

0 commit comments

Comments
 (0)