Skip to content

Commit

Permalink
test: prove that Fibers work if not calling Go
Browse files Browse the repository at this point in the history
  • Loading branch information
dunglas committed Sep 28, 2023
1 parent 29be0c0 commit 69416cc
Show file tree
Hide file tree
Showing 4 changed files with 62 additions and 0 deletions.
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ containing [PHP 8.2](https://www.php.net/releases/8.2/en.php) and most popular P
* [Docker images](docs/docker.md)
* [Compile from sources](docs/compile.md)
* [Create static binaries](docs/static.md)
* [Known issues](docs/known-issues.md)
* [Demo app (Symfony) and benchmarks](https://github.com/dunglas/frankenphp-demo)
* [Go library documentation](https://pkg.go.dev/github.com/dunglas/frankenphp)
* [Contributing and debugging](CONTRIBUTING.md)
Expand Down
32 changes: 32 additions & 0 deletions docs/known-issues.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
# Known Issues

## Fibers

Calling PHP functions and language constructs that themselves call [cgo](https://go.dev/blog/cgo) in [Fibers](https://www.php.net/manual/en/language.fibers.php) is known to cause crashes.

This issue [is being worked on by the Go project](https://github.com/golang/go/issues/62130).


In the meantime, one solution is not to use constructs (like `echo`) and functions (like `header()`) that delegate to Go from inside Fibers.

This code will likely crash because it uses `echo` in the Fiber:

```php
$fiber = new Fiber(function() {
echo 'In the Fiber'.PHP_EOL;
echo 'Still inside'.PHP_EOL;
});
$fiber->start();
```

Instead, return the value from the Fiber and use it outside:

```php
$fiber = new Fiber(function() {
Fiber::suspend('In the Fiber'.PHP_EOL));
Fiber::suspend('Still inside'.PHP_EOL));
});
echo $fiber->start();
echo $fiber->resume();
$fiber->resume();
```
17 changes: 17 additions & 0 deletions frankenphp_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -571,3 +571,20 @@ func ExampleServeHTTP() {
})
log.Fatal(http.ListenAndServe(":8080", nil))
}

func TestFiberNoCgo_module(t *testing.T) { testFiberNoCgo(t, &testOptions{}) }
func TestFiberNonCgo_worker(t *testing.T) {
testFiberNoCgo(t, &testOptions{workerScript: "fiber-no-cgo.php"})
}
func testFiberNoCgo(t *testing.T, opts *testOptions) {
runTest(t, func(handler func(http.ResponseWriter, *http.Request), _ *httptest.Server, i int) {
req := httptest.NewRequest("GET", fmt.Sprintf("http://example.com/fiber-no-cgo.php?i=%d", i), nil)
w := httptest.NewRecorder()
handler(w, req)

resp := w.Result()
body, _ := io.ReadAll(resp.Body)

assert.Equal(t, string(body), fmt.Sprintf("Fiber %d", i))
}, opts)
}
12 changes: 12 additions & 0 deletions testdata/fiber-no-cgo.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
<?php
require_once __DIR__.'/_executor.php';

return function() {
$fiber = new Fiber(function() {
Fiber::suspend('Fiber '.($_GET['i'] ?? ''));
});
echo $fiber->start();

$fiber->resume();
};

0 comments on commit 69416cc

Please sign in to comment.