Skip to content

Commit c1f0f9c

Browse files
committed
Reference same coroutine id in same request
1 parent ebc5859 commit c1f0f9c

File tree

2 files changed

+40
-3
lines changed

2 files changed

+40
-3
lines changed

src/Coroutine/Context.php

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@
77

88
class Context
99
{
10+
protected const MAX_RECURSE_CONTEXT_ID = 50;
11+
1012
/**
1113
* The app containers in different coroutine environment.
1214
*
@@ -90,10 +92,20 @@ public static function clear()
9092
}
9193

9294
/**
93-
* Get current coroutine id.
95+
* Get current requesting coroutine id.
9496
*/
95-
public static function getCoroutineId()
97+
public static function getCoroutineId(): int
9698
{
97-
return Coroutine::getuid();
99+
$currentId = Coroutine::getuid();
100+
if ($currentId === -1) {
101+
return -1;
102+
}
103+
104+
$counter = 0;
105+
while (($topCoroutineId = Coroutine::getPcid($currentId)) !== -1 && $counter <= self::MAX_RECURSE_CONTEXT_ID) {
106+
$currentId = $topCoroutineId;
107+
$counter++;
108+
}
109+
return $currentId;
98110
}
99111
}

tests/Coroutine/ContextTest.php

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,31 @@ public function testGetDataKeys()
5252
$this->assertSame(['foo', 'sea'], Context::getDataKeys());
5353
}
5454

55+
public function testGetDataKeyInCoroutine()
56+
{
57+
$data1 = null;
58+
$data2 = null;
59+
$coroutineId1 = null;
60+
$coroutineId2 = null;
61+
\Swoole\Coroutine\run(function () use (&$data1, &$data2, &$coroutineId1, &$coroutineId2) {
62+
Context::setData('foo', 'bar');
63+
64+
$data1 = Context::getData('foo');
65+
$data2 = 'baz';
66+
$coroutineId1 = Context::getCoroutineId();
67+
$coroutineId2 = -1;
68+
69+
go(function () use (&$data2, &$coroutineId2) {
70+
$data2 = Context::getData('foo');
71+
$coroutineId2 = Context::getCoroutineId();
72+
});
73+
});
74+
75+
$this->assertSame('bar', $data1);
76+
$this->assertSame($data1, $data2);
77+
$this->assertSame($coroutineId1, $coroutineId2);
78+
}
79+
5580
public function testClear()
5681
{
5782
Context::setApp(m::mock(Container::class));

0 commit comments

Comments
 (0)