From c1f0f9cd8d5dad8ec5d0197ae131416cc08f0235 Mon Sep 17 00:00:00 2001 From: m3m0r7 Date: Wed, 5 May 2021 11:29:45 +0900 Subject: [PATCH 1/4] Reference same coroutine id in same request --- src/Coroutine/Context.php | 18 +++++++++++++++--- tests/Coroutine/ContextTest.php | 25 +++++++++++++++++++++++++ 2 files changed, 40 insertions(+), 3 deletions(-) diff --git a/src/Coroutine/Context.php b/src/Coroutine/Context.php index 2ea8a20c..29d823b3 100644 --- a/src/Coroutine/Context.php +++ b/src/Coroutine/Context.php @@ -7,6 +7,8 @@ class Context { + protected const MAX_RECURSE_CONTEXT_ID = 50; + /** * The app containers in different coroutine environment. * @@ -90,10 +92,20 @@ public static function clear() } /** - * Get current coroutine id. + * Get current requesting coroutine id. */ - public static function getCoroutineId() + public static function getCoroutineId(): int { - return Coroutine::getuid(); + $currentId = Coroutine::getuid(); + if ($currentId === -1) { + return -1; + } + + $counter = 0; + while (($topCoroutineId = Coroutine::getPcid($currentId)) !== -1 && $counter <= self::MAX_RECURSE_CONTEXT_ID) { + $currentId = $topCoroutineId; + $counter++; + } + return $currentId; } } diff --git a/tests/Coroutine/ContextTest.php b/tests/Coroutine/ContextTest.php index a9ef6800..8e267543 100644 --- a/tests/Coroutine/ContextTest.php +++ b/tests/Coroutine/ContextTest.php @@ -52,6 +52,31 @@ public function testGetDataKeys() $this->assertSame(['foo', 'sea'], Context::getDataKeys()); } + public function testGetDataKeyInCoroutine() + { + $data1 = null; + $data2 = null; + $coroutineId1 = null; + $coroutineId2 = null; + \Swoole\Coroutine\run(function () use (&$data1, &$data2, &$coroutineId1, &$coroutineId2) { + Context::setData('foo', 'bar'); + + $data1 = Context::getData('foo'); + $data2 = 'baz'; + $coroutineId1 = Context::getCoroutineId(); + $coroutineId2 = -1; + + go(function () use (&$data2, &$coroutineId2) { + $data2 = Context::getData('foo'); + $coroutineId2 = Context::getCoroutineId(); + }); + }); + + $this->assertSame('bar', $data1); + $this->assertSame($data1, $data2); + $this->assertSame($coroutineId1, $coroutineId2); + } + public function testClear() { Context::setApp(m::mock(Container::class)); From fffaf16c6f6e7fb35bd4cf064f50b5d481d85a9c Mon Sep 17 00:00:00 2001 From: m3m0r7 Date: Wed, 5 May 2021 11:30:26 +0900 Subject: [PATCH 2/4] Rename const --- src/Coroutine/Context.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Coroutine/Context.php b/src/Coroutine/Context.php index 29d823b3..c88f88a1 100644 --- a/src/Coroutine/Context.php +++ b/src/Coroutine/Context.php @@ -7,7 +7,7 @@ class Context { - protected const MAX_RECURSE_CONTEXT_ID = 50; + protected const MAX_RECURSE_COROUTINE_ID = 50; /** * The app containers in different coroutine environment. @@ -102,7 +102,7 @@ public static function getCoroutineId(): int } $counter = 0; - while (($topCoroutineId = Coroutine::getPcid($currentId)) !== -1 && $counter <= self::MAX_RECURSE_CONTEXT_ID) { + while (($topCoroutineId = Coroutine::getPcid($currentId)) !== -1 && $counter <= self::MAX_RECURSE_COROUTINE_ID) { $currentId = $topCoroutineId; $counter++; } From fd75cd3cbbe10a0741d1060545e94cae46fa700a Mon Sep 17 00:00:00 2001 From: m3m0r7 Date: Wed, 5 May 2021 11:44:04 +0900 Subject: [PATCH 3/4] Refactor --- src/Coroutine/Context.php | 29 +++++++++++++++++------------ tests/Coroutine/ContextTest.php | 4 ++-- 2 files changed, 19 insertions(+), 14 deletions(-) diff --git a/src/Coroutine/Context.php b/src/Coroutine/Context.php index c88f88a1..3117ef55 100644 --- a/src/Coroutine/Context.php +++ b/src/Coroutine/Context.php @@ -28,7 +28,7 @@ class Context */ public static function getApp() { - return static::$apps[static::getCoroutineId()] ?? null; + return static::$apps[static::getRequestedCoroutineId()] ?? null; } /** @@ -38,7 +38,7 @@ public static function getApp() */ public static function setApp(Container $app) { - static::$apps[static::getCoroutineId()] = $app; + static::$apps[static::getRequestedCoroutineId()] = $app; } /** @@ -50,7 +50,7 @@ public static function setApp(Container $app) */ public static function getData(string $key) { - return static::$data[static::getCoroutineId()][$key] ?? null; + return static::$data[static::getRequestedCoroutineId()][$key] ?? null; } /** @@ -61,7 +61,7 @@ public static function getData(string $key) */ public static function setData(string $key, $value) { - static::$data[static::getCoroutineId()][$key] = $value; + static::$data[static::getRequestedCoroutineId()][$key] = $value; } /** @@ -71,7 +71,7 @@ public static function setData(string $key, $value) */ public static function removeData(string $key) { - unset(static::$data[static::getCoroutineId()][$key]); + unset(static::$data[static::getRequestedCoroutineId()][$key]); } /** @@ -79,7 +79,7 @@ public static function removeData(string $key) */ public static function getDataKeys() { - return array_keys(static::$data[static::getCoroutineId()] ?? []); + return array_keys(static::$data[static::getRequestedCoroutineId()] ?? []); } /** @@ -87,22 +87,27 @@ public static function getDataKeys() */ public static function clear() { - unset(static::$apps[static::getCoroutineId()]); - unset(static::$data[static::getCoroutineId()]); + unset(static::$apps[static::getRequestedCoroutineId()]); + unset(static::$data[static::getRequestedCoroutineId()]); + } + + public static function getCoroutineId(): int + { + return Coroutine::getuid(); } /** - * Get current requesting coroutine id. + * Get current coroutine id. */ - public static function getCoroutineId(): int + public static function getRequestedCoroutineId(): int { - $currentId = Coroutine::getuid(); + $currentId = static::getCoroutineId(); if ($currentId === -1) { return -1; } $counter = 0; - while (($topCoroutineId = Coroutine::getPcid($currentId)) !== -1 && $counter <= self::MAX_RECURSE_COROUTINE_ID) { + while (($topCoroutineId = Coroutine::getPcid($currentId)) !== -1 && $counter <= static::MAX_RECURSE_COROUTINE_ID) { $currentId = $topCoroutineId; $counter++; } diff --git a/tests/Coroutine/ContextTest.php b/tests/Coroutine/ContextTest.php index 8e267543..fcc29b5c 100644 --- a/tests/Coroutine/ContextTest.php +++ b/tests/Coroutine/ContextTest.php @@ -63,12 +63,12 @@ public function testGetDataKeyInCoroutine() $data1 = Context::getData('foo'); $data2 = 'baz'; - $coroutineId1 = Context::getCoroutineId(); + $coroutineId1 = Context::getRequestedCoroutineId(); $coroutineId2 = -1; go(function () use (&$data2, &$coroutineId2) { $data2 = Context::getData('foo'); - $coroutineId2 = Context::getCoroutineId(); + $coroutineId2 = Context::getRequestedCoroutineId(); }); }); From d089754bdb30d1f68278cc4606cc43dedb2a8001 Mon Sep 17 00:00:00 2001 From: m3m0r7 Date: Wed, 5 May 2021 11:48:45 +0900 Subject: [PATCH 4/4] Fix test --- tests/Coroutine/ContextTest.php | 20 ++++++++++++++++++-- 1 file changed, 18 insertions(+), 2 deletions(-) diff --git a/tests/Coroutine/ContextTest.php b/tests/Coroutine/ContextTest.php index fcc29b5c..9d9e99f7 100644 --- a/tests/Coroutine/ContextTest.php +++ b/tests/Coroutine/ContextTest.php @@ -56,25 +56,41 @@ public function testGetDataKeyInCoroutine() { $data1 = null; $data2 = null; + $data3 = null; + $coroutineId1 = null; $coroutineId2 = null; - \Swoole\Coroutine\run(function () use (&$data1, &$data2, &$coroutineId1, &$coroutineId2) { + $coroutineId3 = null; + + \Swoole\Coroutine\run(function () use (&$data1, &$data2, &$data3, &$coroutineId1, &$coroutineId2, &$coroutineId3) { Context::setData('foo', 'bar'); $data1 = Context::getData('foo'); $data2 = 'baz'; + $data2 = 'swoole'; + $coroutineId1 = Context::getRequestedCoroutineId(); $coroutineId2 = -1; + $coroutineId3 = -1; - go(function () use (&$data2, &$coroutineId2) { + go(function () use (&$data2, &$data3, &$coroutineId2, &$coroutineId3) { $data2 = Context::getData('foo'); $coroutineId2 = Context::getRequestedCoroutineId(); + + // test nested coroutine + go(function () use (&$data3, &$coroutineId3) { + $data3 = Context::getData('foo'); + $coroutineId3 = Context::getRequestedCoroutineId(); + }); }); }); $this->assertSame('bar', $data1); $this->assertSame($data1, $data2); + $this->assertSame($data2, $data3); $this->assertSame($coroutineId1, $coroutineId2); + $this->assertSame($coroutineId2, $coroutineId3); + } public function testClear()