diff --git a/src/Gateway/Connection.php b/src/Gateway/Connection.php index 147c395..d3a66a5 100644 --- a/src/Gateway/Connection.php +++ b/src/Gateway/Connection.php @@ -78,7 +78,10 @@ public function __construct( $payload = $this->mapper->map($parsedMessage, Payload::class); - $this->raw->emit((string) $payload->op, [$this, $payload, $this->logger]); + $this->loop->futureTick(function () use ($payload) { + // Moving this to future tick improves stability + $this->raw->emit((string) $payload->op, [$this, $payload, $this->logger]); + }); }); $this->websocket->on(WebsocketEvents::CLOSE, $this->handleClose(...)); diff --git a/tests/Gateway/ConnectionTest.php b/tests/Gateway/ConnectionTest.php index c2de949..165c5ef 100644 --- a/tests/Gateway/ConnectionTest.php +++ b/tests/Gateway/ConnectionTest.php @@ -38,7 +38,7 @@ class ConnectionTest extends MockeryTestCase public function testGetDefaultUrl(): void { $connection = new Connection( - Mockery::mock(LoopInterface::class), + $this->getLoop(), '::token::', new Bitwise(), new DataMapper(new NullLogger()), @@ -51,7 +51,7 @@ public function testGetDefaultUrl(): void public function testSequence(): void { $connection = new Connection( - Mockery::mock(LoopInterface::class), + $this->getLoop(), '::token::', new Bitwise(), new DataMapper(new NullLogger()), @@ -67,7 +67,7 @@ public function testSequence(): void public function testConnect(): void { $connection = new Connection( - Mockery::mock(LoopInterface::class), + $this->getLoop(), '::token::', new Bitwise(), new DataMapper(new NullLogger()), @@ -90,7 +90,7 @@ public function testConnect(): void public function testDisconnect(): void { $connection = new Connection( - Mockery::mock(LoopInterface::class), + $this->getLoop(), '::token::', new Bitwise(), new DataMapper(new NullLogger()), @@ -112,7 +112,7 @@ public function testDisconnect(): void public function testSessionId(): void { $connection = new Connection( - Mockery::mock(LoopInterface::class), + $this->getLoop(), '::token::', new Bitwise(), new DataMapper(new NullLogger()), @@ -128,7 +128,7 @@ public function testSessionId(): void public function testResumeUrl(): void { $connection = new Connection( - Mockery::mock(LoopInterface::class), + $this->getLoop(), '::token::', new Bitwise(), new DataMapper(new NullLogger()), @@ -307,7 +307,7 @@ public function testItCanSendHeartbeatsAutomatically(): void public function testItReturnsEventHandlers(): void { $connection = new Connection( - Mockery::mock(LoopInterface::class), + $this->getLoop(), '::token::', new Bitwise(), new DataMapper(new NullLogger()), @@ -320,7 +320,7 @@ public function testItReturnsEventHandlers(): void public function testItIdentifies(): void { $connection = new Connection( - Mockery::mock(LoopInterface::class), + $this->getLoop(), '::token::', new Bitwise(123), new DataMapper(new NullLogger()), @@ -348,7 +348,7 @@ public function testItIdentifies(): void public function testItIdentifiesWithShards(): void { $connection = new Connection( - Mockery::mock(LoopInterface::class), + $this->getLoop(), '::token::', new Bitwise(123), new DataMapper(new NullLogger()), @@ -379,7 +379,7 @@ public function testItIdentifiesWithShards(): void public function testItResumes(): void { $connection = new Connection( - Mockery::mock(LoopInterface::class), + $this->getLoop(), '::token::', new Bitwise(123), new DataMapper(new NullLogger()), @@ -426,7 +426,7 @@ public function testItResumes(): void public function testOpen(): void { $connection = new Connection( - Mockery::mock(LoopInterface::class), + $this->getLoop(), '::token::', new Bitwise(), new DataMapper(new NullLogger()), @@ -463,7 +463,7 @@ public function testItEmitsGatewayMessagesAsEvents(): void ->withAnyArgs(); $connection = new Connection( - Mockery::mock(LoopInterface::class), + $this->getLoop(), '::token::', new Bitwise(), new DataMapper(new NullLogger()), @@ -496,7 +496,7 @@ public function testItEmitsGatewayMessagesAsEvents(): void public function testItSendsPresenceUpdates() { $connection = new Connection( - Mockery::mock(LoopInterface::class), + $this->getLoop(), '::token::', new Bitwise(123), new DataMapper(new NullLogger()), @@ -545,7 +545,7 @@ public function testItReconnectsWhenWebsocketConnectionClosedWithCertainCodes(in ->twice(); new Connection( - Mockery::mock(LoopInterface::class), + $this->getLoop(), '::token::', new Bitwise(1), DataMapperFake::get(), @@ -592,7 +592,7 @@ public function testItResumesWhenWebsocketConnectionClosedWithCertainCodes(int $ ->once(); $connection = new Connection( - Mockery::mock(LoopInterface::class), + $this->getLoop(), '::token::', new Bitwise(1), DataMapperFake::get(), @@ -628,7 +628,7 @@ public function testItReconnectsIfMissingResumeUrl(int $code) ->twice(); $connection = new Connection( - Mockery::mock(LoopInterface::class), + $this->getLoop(), '::token::', new Bitwise(1), DataMapperFake::get(), @@ -663,7 +663,7 @@ public function testItReconnectsIfMissingSessionId(int $code) ->twice(); $connection = new Connection( - Mockery::mock(LoopInterface::class), + $this->getLoop(), '::token::', new Bitwise(1), DataMapperFake::get(), @@ -679,6 +679,18 @@ public function testItReconnectsIfMissingSessionId(int $code) $this->assertEquals([Connection::DEFAULT_WEBSOCKET_URL . '?v=' . Connection::DISCORD_VERSION], $websocket->openings); } + private function getLoop(): LoopInterface + { + $loop = Mockery::mock(LoopInterface::class); + + $loop->shouldReceive('futureTick') + ->andReturnUsing(function (callable $callback) { + $callback(); + }); + + return $loop; + } + public static function resumeCloseCodesProvider(): array { return [