Skip to content

Commit 12d3e08

Browse files
committed
redis_pool: rename binding->pool, drop unused wrapper; English test comments
Refactor: rename the binding's owning-pool field rp -> pool, and remove the dead 'wrapper' field (getPool() is unimplemented; the async pool can mint its own PHP wrapper on demand via ZEND_ASYNC_NEW_POOL_OBJ). Update the struct in TRUE_ASYNC_POOL.md to match. Translate all code comments in tests/async (.phpt + helper) and the README to English.
1 parent beba233 commit 12d3e08

9 files changed

Lines changed: 40 additions & 48 deletions

TRUE_ASYNC_POOL.md

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -102,7 +102,7 @@ Mirror `pdo_pool_binding_t` / the `pdo_dbh_t` pool fields.
102102
/* Per-coroutine binding. Analogue of pdo_pool_binding_t. */
103103
typedef struct {
104104
zend_async_event_callback_t event; /* coroutine-finalize callback */
105-
redis_async_pool *rp; /* owning pool, NULL once destroyed */
105+
redis_async_pool *pool; /* owning pool, NULL once destroyed */
106106
RedisSock *conn; /* checked-out conn, or NULL */
107107
zend_ulong coro_key;
108108
bool has_coro_callback;
@@ -113,7 +113,6 @@ struct _redis_async_pool {
113113
zend_async_pool_t *async_pool; /* physical RedisSock resources */
114114
HashTable *bindings; /* coro_key -> redis_pool_binding_t* */
115115
HashTable *opts; /* dup'd ctor options; factory replays */
116-
zend_object *wrapper; /* PHP pool wrapper (getPool()), lazy */
117116
long db_default; /* configured DB; drift pins the conn */
118117
uint32_t mux_reserve; /* connections reserved for multiplexing */
119118
};

redis_pool.c

Lines changed: 8 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -29,17 +29,16 @@ extern zend_class_entry *redis_exception_ce;
2929
*/
3030
typedef struct {
3131
zend_async_event_callback_t event; /* must be first for the callback cast */
32-
redis_async_pool *rp; /* owning pool, NULL once destroyed */
32+
redis_async_pool *pool; /* owning pool, NULL once destroyed */
3333
RedisSock *conn; /* checked-out conn, NULL if released */
34-
zend_ulong coro_key; /* key in rp->bindings */
34+
zend_ulong coro_key; /* key in pool->bindings */
3535
bool has_coro_callback; /* registered with the coroutine event */
3636
} redis_pool_binding_t;
3737

3838
struct _redis_async_pool {
3939
zend_async_pool_t *async_pool; /* physical RedisSock resources */
4040
HashTable *bindings; /* coro_key -> redis_pool_binding_t* */
4141
HashTable *opts; /* dup'd ctor options; factory re-applies */
42-
zend_object *wrapper; /* PHP pool wrapper (getPool()), lazy */
4342
long db_default; /* configured DB; drift pins the conn */
4443
uint32_t mux_reserve; /* connections reserved for multiplexing */
4544
};
@@ -205,19 +204,19 @@ static void redis_pool_binding_on_coroutine_finish(
205204
redis_pool_binding_t *binding = (redis_pool_binding_t *)callback;
206205

207206
/* Pool already destroyed — nothing to do. */
208-
if (binding->rp == NULL) {
207+
if (binding->pool == NULL) {
209208
return;
210209
}
211210

212211
if (binding->conn != NULL) {
213212
zval conn_zval;
214213
ZVAL_PTR(&conn_zval, binding->conn);
215-
ZEND_ASYNC_POOL_RELEASE(binding->rp->async_pool, &conn_zval);
214+
ZEND_ASYNC_POOL_RELEASE(binding->pool->async_pool, &conn_zval);
216215
binding->conn = NULL;
217216
}
218217

219-
if (binding->rp->bindings != NULL) {
220-
zend_hash_index_del(binding->rp->bindings, binding->coro_key);
218+
if (binding->pool->bindings != NULL) {
219+
zend_hash_index_del(binding->pool->bindings, binding->coro_key);
221220
}
222221
}
223222

@@ -300,7 +299,6 @@ int redis_pool_create(redis_object *redis, HashTable *opts)
300299
rp->opts = zend_array_dup(opts);
301300
rp->db_default = redis->sock ? redis->sock->dbNumber : 0;
302301
rp->mux_reserve = (uint32_t)mux;
303-
rp->wrapper = NULL;
304302

305303
redis->pool = rp;
306304
return SUCCESS;
@@ -329,7 +327,7 @@ void redis_pool_destroy(redis_object *redis)
329327
efree(binding);
330328
} else {
331329
/* Coroutine callback will no-op; dispose frees the binding. */
332-
binding->rp = NULL;
330+
binding->pool = NULL;
333331
}
334332
} ZEND_HASH_FOREACH_END();
335333

@@ -338,11 +336,6 @@ void redis_pool_destroy(redis_object *redis)
338336
rp->bindings = NULL;
339337
}
340338

341-
if (rp->wrapper != NULL) {
342-
OBJ_RELEASE(rp->wrapper);
343-
rp->wrapper = NULL;
344-
}
345-
346339
if (rp->async_pool != NULL) {
347340
ZEND_ASYNC_POOL_CLOSE(rp->async_pool);
348341
ZEND_ASYNC_EVENT_RELEASE(&rp->async_pool->event);
@@ -397,7 +390,7 @@ RedisSock *redis_pool_acquire_conn(redis_object *redis, int no_throw)
397390
binding->event.callback = redis_pool_binding_on_coroutine_finish;
398391
binding->event.dispose = redis_pool_binding_dispose;
399392
binding->event.ref_count = 1;
400-
binding->rp = rp;
393+
binding->pool = rp;
401394
binding->conn = Z_PTR(resource);
402395
binding->coro_key = coro_key;
403396

tests/async/001-pool_construct.phpt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ $redis = AsyncRedisPoolTest::poolFactory(max: 4);
1313
$pool = $redis->getPool();
1414

1515
echo "Has pool: " . ($pool !== null ? "yes" : "no") . "\n";
16-
echo "Count: " . $pool->count() . "\n"; // ещё ничего не выдано
16+
echo "Count: " . $pool->count() . "\n"; // nothing handed out yet
1717
echo "Idle: " . $pool->idleCount() . "\n";
1818
echo "Active: " . $pool->activeCount() . "\n";
1919
echo "Done\n";

tests/async/003-pool_concurrent_coroutines.phpt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,8 @@ use function Async\await;
1414

1515
$redis = AsyncRedisPoolTest::poolFactory(max: 4);
1616

17-
/* Инвариант (chaos-стиль): при любой интерливинге каждая корутина читает
18-
* именно своё значение — общий $redis не перемешивает ответы. */
17+
/* Invariant (chaos-style): under any interleaving each coroutine reads its own
18+
* value — the shared $redis never mixes up replies. */
1919
$N = 8;
2020
$coros = [];
2121
for ($i = 0; $i < $N; $i++) {

tests/async/004-pool_backpressure.phpt

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -12,24 +12,24 @@ require_once __DIR__ . '/inc/async_redis_pool_test.inc';
1212
use function Async\spawn;
1313
use function Async\await;
1414

15-
/* Порт ext/async/tests/pool/029: при max=1 второй потребитель обязан
16-
* запарковаться, пока первый держит соединение (в транзакции — пиннинг). */
15+
/* Port of ext/async/tests/pool/029: with max=1 the second consumer must park
16+
* while the first holds the connection (pinned by the transaction). */
1717
$redis = AsyncRedisPoolTest::poolFactory(max: 1);
1818
$k = AsyncRedisPoolTest::key('bp');
1919

2020
$c2Blocked = false;
2121

2222
$c1 = spawn(function() use ($redis, $k) {
23-
$redis->multi(); // пиннит единственное соединение
23+
$redis->multi(); // pins the only connection
2424
$redis->set($k, '1');
2525
\Async\suspend();
2626
\Async\suspend();
27-
$redis->exec(); // отпускает соединение в пул
27+
$redis->exec(); // releases the connection back to the pool
2828
});
2929

3030
$c2 = spawn(function() use ($redis, $k, &$c2Blocked) {
3131
$c2Blocked = ($redis->getPool()->idleCount() === 0);
32-
$v = $redis->get($k); // ждёт, пока c1 не освободит conn
32+
$v = $redis->get($k); // waits until c1 frees the conn
3333
$redis->del($k);
3434
return $v;
3535
});

tests/async/005-pool_transaction_pins.phpt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ $co = spawn(function() use ($redis, $k) {
2020
$redis->set($k, 'a');
2121
$redis->append($k, 'b');
2222
$redis->get($k);
23-
$res = $redis->exec(); // транзакция атомарна на одном соединении
23+
$res = $redis->exec(); // transaction is atomic on a single connection
2424
$redis->del($k);
2525
return $res;
2626
});

tests/async/006-pool_concurrent_multi_isolation.phpt

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -12,16 +12,16 @@ require_once __DIR__ . '/inc/async_redis_pool_test.inc';
1212
use function Async\spawn;
1313
use function Async\await;
1414

15-
/* Две корутины ведут транзакции параллельно. Каждая пиннит СВОЁ физическое
16-
* соединение (нужно max>=2), команды не перемешиваются между транзакциями. */
15+
/* Two coroutines run transactions in parallel. Each pins its OWN physical
16+
* connection (needs max>=2); commands do not interleave between transactions. */
1717
$redis = AsyncRedisPoolTest::poolFactory(max: 2);
1818

1919
$mk = function(string $tag) use ($redis) {
2020
return function() use ($redis, $tag) {
2121
$k = AsyncRedisPoolTest::key("iso:$tag");
2222
$redis->multi();
2323
$redis->set($k, $tag);
24-
\Async\suspend(); // отдаём управление другой корутине
24+
\Async\suspend(); // yield to the other coroutine
2525
$redis->append($k, $tag);
2626
$out = $redis->exec();
2727
$v = $redis->get($k);
@@ -36,8 +36,8 @@ $b = spawn($mk('B'));
3636
$va = await($a);
3737
$vb = await($b);
3838

39-
echo "A: $va\n"; // должно быть "AA", не перемешано с B
40-
echo "B: $vb\n"; // должно быть "BB"
39+
echo "A: $va\n"; // must be "AA", not mixed with B
40+
echo "B: $vb\n"; // must be "BB"
4141
echo "Done\n";
4242
?>
4343
--EXPECT--

tests/async/README.md

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,22 @@
11
# TrueAsync pool tests
22

3-
Тесты пула соединений phpredis под TrueAsync. Формат — `.phpt` (как
4-
`php-src/ext/async/tests`), корутины через `Async\spawn` / `Async\await`.
5-
НЕ синхронный `tests/TestRedis.php`.
3+
Tests for the phpredis connection pool under TrueAsync. Format: `.phpt` (like
4+
`php-src/ext/async/tests`), coroutines via `Async\spawn` / `Async\await`. NOT the
5+
synchronous `tests/TestRedis.php` framework.
66

7-
Статус: **исполняемая спецификация**. Фича из `TRUE_ASYNC_POOL.md` ещё не
8-
реализована — пока тесты падают/скипаются. По мере реализации Stage 1/2 должны
9-
зеленеть.
7+
Status: **executable specification**. Tests that depend on already-implemented
8+
behaviour pass; those depending on not-yet-implemented parts (e.g. `getPool()`)
9+
fail until those land.
1010

11-
## Запуск
11+
## Running
1212

13-
Нужен build php-src с `--enable-zts` и подключённым TrueAsync-реактором +
14-
собранный phpredis против него, и живой Redis (по умолчанию `127.0.0.1:6379`,
15-
переопределяется `REDIS_TEST_HOST` / `REDIS_TEST_PORT`).
13+
Needs a php-src build with `--enable-zts` and the TrueAsync reactor, phpredis
14+
built against it, and a live Redis (default `127.0.0.1:6379`, overridable via
15+
`REDIS_TEST_HOST` / `REDIS_TEST_PORT`).
1616

1717
```sh
1818
REDIS_TEST_HOST=127.0.0.1 REDIS_TEST_PORT=6379 \
1919
php run-tests.php -p $(which php) tests/async
2020
```
2121

22-
Хелпер `inc/async_redis_pool_test.inc` даёт `skipIf*` и `poolFactory()`.
22+
The helper `inc/async_redis_pool_test.inc` provides `skipIf*` and `poolFactory()`.

tests/async/inc/async_redis_pool_test.inc

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
<?php
2-
/* Хелпер для async pool тестов phpredis. По образцу
2+
/* Helper for phpredis async pool tests. Modeled on
33
* php-src/ext/async/tests/pdo_mysql/inc/async_pdo_mysql_test.inc */
44

55
use function Async\spawn;
@@ -10,21 +10,21 @@ class AsyncRedisPoolTest
1010
static function host(): string { return getenv('REDIS_TEST_HOST') ?: '127.0.0.1'; }
1111
static function port(): int { return (int)(getenv('REDIS_TEST_PORT') ?: 6379); }
1212

13-
/* Скип, если TrueAsync-рантайм недоступен. */
13+
/* Skip if the TrueAsync runtime is unavailable. */
1414
static function skipIfNoAsync(): void {
1515
if (!function_exists('Async\\spawn')) {
1616
die("skip TrueAsync runtime not available\n");
1717
}
1818
}
1919

20-
/* Скип, если расширение redis не загружено. */
20+
/* Skip if the redis extension is not loaded. */
2121
static function skipIfNoRedis(): void {
2222
if (!extension_loaded('redis')) {
2323
die("skip redis extension not loaded\n");
2424
}
2525
}
2626

27-
/* Скип, если живой Redis недоступен. */
27+
/* Skip if no live Redis server is reachable. */
2828
static function skipIfNoServer(): void {
2929
$r = new Redis();
3030
if (!@$r->connect(self::host(), self::port(), 1.0)) {
@@ -39,7 +39,7 @@ class AsyncRedisPoolTest
3939
self::skipIfNoServer();
4040
}
4141

42-
/* Pool-enabled Redis (template-режим). Конфиг пуласм. TRUE_ASYNC_POOL.md §6. */
42+
/* Pool-enabled Redis (template mode). Pool configsee TRUE_ASYNC_POOL.md §6. */
4343
static function poolFactory(int $max = 4, int $mux = 0, int $min = 0): Redis {
4444
return new Redis([
4545
'host' => self::host(),
@@ -53,7 +53,7 @@ class AsyncRedisPoolTest
5353
]);
5454
}
5555

56-
/* Уникальный префикс ключей, чтобы тесты не топтали друг друга. */
56+
/* Unique key prefix so tests do not clobber each other. */
5757
static function key(string $name): string {
5858
return 'phpredis:async:test:' . $name;
5959
}

0 commit comments

Comments
 (0)