Comments (6)
Hey @greendrake
You're not wrong, the error message could be a bit more precise. If you already have some ideas we're always happy about pull requests. 👍
from async.
I am having the same error: Value of type null is not callable in src/SimpleFiber.php
react/async/src/SimpleFiber.php:74
.
Tried to do what @greendrake told: wrap into async
but it does not work.
Does anyone have the solution code to share?
from async.
@mowses can you share any code that triggers this?
from async.
Update: right now I am reading your blog at https://blog.wyrihaximus.net/2021/12/async-and-await-at-the-edge-with-reactphp/
@WyriHaximus sure. I am testing my laravel-websockets
functionality. Here's the code.
ConnectionTest.php
<?php
namespace Modules\Lobby\Tests\Unit\Sockets;
class ConnectionTest extends SocketTestCase
{
public function test_debugging_error()
{
$this->startServer(function () {
$this->connect("/app/INVALID-APP-KEY/room/INVALID-ROOM-ID", function () {
dump('connection #1');
$this->assertTrue(true);
});
});
$this->startServer(function () {
$this->connect("/app/INVALID-APP-KEY/room/INVALID-ROOM-ID", function () {
dump('connection #2');
$this->assertTrue(true);
});
});
dd('CONNECTION #1 IS OK. BUT SCRIPT FAILS CONNECTING #2 BECAUSE OF THE `await($promise)` ERROR: Value of type null is not callable in src/SimpleFiber.php IN react/async/src/SimpleFiber.php:74');
}
}
SocketTestCase.php
<?php
namespace Modules\Lobby\Tests\Unit\Sockets;
use BeyondCode\LaravelWebSockets\Apps\App;
use BeyondCode\LaravelWebSockets\Apps\AppProvider;
use BeyondCode\LaravelWebSockets\Facades\WebSocketsRouter;
use BeyondCode\LaravelWebSockets\Server\Logger\WebsocketsLogger;
use BeyondCode\LaravelWebSockets\Server\Router;
use BeyondCode\LaravelWebSockets\Server\WebSocketServerFactory;
use Closure;
use Mockery;
use Mockery\MockInterface;
use Modules\Lobby\Interfaces\RoomSocketHandlerInterface;
use Modules\Lobby\Sockets\RoomSocketHandler;
use Orchestra\Testbench\TestCase;
use Ratchet\Client\WebSocket;
use Ratchet\Server\IoServer;
use Symfony\Component\Console\Output\BufferedOutput;
use Tests\CreatesApplication;
abstract class SocketTestCase extends TestCase
{
use CreatesApplication;
protected function startServer(Closure $closure = null): IoServer
{
/** @var WebSocketServerFactory $server */
$server = app(WebSocketServerFactory::class);
/** @var Router $route */
$route = WebSocketsRouter::getFacadeRoot();
$route->customRoutes(); // make custom routes available by calling ->getRoutes()
$ioServer = $server
->setHost(config('broadcasting.connections.pusher.options.host'))
->setPort(config('broadcasting.connections.pusher.options.port'))
->useRoutes($route->getRoutes())
->createServer();
if ($closure !== null) {
try {
$closure($ioServer);
} finally {
$ioServer->socket->close();
}
}
return $ioServer;
}
protected function connect(string $path, Closure $closure = null): void
{
$promise = \Ratchet\Client\connect($this->getFullConnectionString($path))
->then(
function (WebSocket $conn) use ($closure) {
try {
if ($closure !== null) {
$closure($conn);
}
} finally {
$conn->close();
}
}
);
/** @noinspection PhpUnhandledExceptionInspection */
\React\Async\await($promise);
}
protected function getFullConnectionString(string $path): string
{
return sprintf('%s://%s:%s/%s',
config('broadcasting.connections.pusher.options.scheme'),
config('broadcasting.connections.pusher.options.host'),
config('broadcasting.connections.pusher.options.port'),
$path
);
}
protected function getAppBasePath(string $appId): string
{
return sprintf('/app/%s',
$this->getLobbyAppConfig($appId)->key ?? ''
);
}
protected function getLobbyAppConfig(string $appId): ?App
{
/** @var AppProvider $provider */
$provider = app(config('websockets.app_provider'));
return $provider->findById($appId);
}
}
Method connect
creates a promise of a Ratchet client and then awaits for the promise to be resolved.
- Once resolved, the closure from the test method is called
- the connection is immediately closed
- await unblocks
- the next connection test block starts
The error is triggered when called the next await
function.
As far I debugged, the second time await runs, the variable $this->$scheduler
is no more null
in the SimpleFiber.php
which is then called the start()
assigning value of null
to $ret
.
from async.
I managed to handle my problem. For the people who had the same issue, here's what I did to solve:
- Created a new
Loop
instance and passed as the fourth parameter ofconnect()
function; - Wrapped the promise in an
async
function; - Manually run
$loop->run();
- Manually run
$loop->stop();
after the request was resolved/rejected;
Here is the modified method:
protected function connect(string $path, Closure $closure = null): void
{
$loop = Loop::get();
$promise = function () use ($path, $closure, $loop): void {
$request = connect($this->getFullConnectionString($path), [], [], $loop)
->then(
function (WebSocket $conn) use ($closure, $loop) {
try {
if ($closure !== null) {
$closure($conn);
}
} finally {
$conn->close();
$loop->stop();
}
},
function (Throwable $e) use ($loop) {
$loop->stop();
throw $e;
}
);
await($request);
};
async($promise)();
$loop->run();
}
from async.
@mowses Thanks for your input on this 👍
Like I said above, the current error message is confusing and we want to give this a more meaningful content. @clue and I invested a few hours into a potential fix in the past, but we quickly ran into some overlaps with #65. It seems like we first need to file a new pull request in https://github.com/reactphp/event-loop in order to fix this here. We also have to define the expected behavior and write additional test cases.
Stopping the loop like you described in your example above doesn't really fix the problem here. Additionally, you shouldn't use $loop->stop()
as described in https://github.com/reactphp/event-loop#stop:
This method is considered advanced usage and should be used with care. As a rule of thumb, it is usually recommended to let the loop stop only automatically when it no longer has anything to do.
We'll give an update once we filed the necessary pull requests and renamed this message to be more meaningful.
from async.
Related Issues (14)
- await() error in SimpleFiber.php HOT 17
- Fibers + Cancellation HOT 2
- Use 0.x versions HOT 5
- Error: event_base_loop reentrant invocation HOT 9
- await() doesn't work with streaming HTTP response body HOT 9
- Allow `iterable` instead of `array` for `parallel()`, `series()` and `waterfall()` HOT 1
- Cancellation semantics for `async()` and `coroutine()` HOT 2
- Support Promise v3 HOT 1
- Using await in a destructor HOT 7
- Struggling with the simplest example HOT 1
- Basic question 'bout reactphp HOT 9
- reactphp/async
- \React\Async\async did not invokes in on('data') event HOT 2
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from async.