Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Adds basic file watcher #1013

Merged
merged 168 commits into from
Oct 7, 2024
Merged

Adds basic file watcher #1013

merged 168 commits into from
Oct 7, 2024

Conversation

AlliBalliBaba
Copy link
Contributor

This PR adds a basic version of a file watcher to reload workers when changing files. The watcher is based on github.com/fsnotify/fsnotify since it's already a downstream dependency of the caddfy module.

Some notes:

  • fsnotify doesn't yet officially support recursive watching, so the watcher.go implements it itself via filepath.Walk
  • The watcher also supports file patterns, the following is valid:
{
    frankenphp {
        watch /path/to/app/folder1             # watches all subdirectories
        watch /path/to/app/folder2/*.php       # watches only php files in the app directory
        watch /path/to/app/folder3/**/*.php    # watches only php files in the app directory and subdirectories
    }
}
  • if a worker gets stuck in a request, the watcher will wait for the worker to finish before performing another reload (don't know if there's a better way to do this)
  • I wasn't quite sure how to best test the watcher integration. There seems to be a race condition that sometimes makes the watcher_test.go fail, which I don't yet quite understand (it's related to the workersReadyWG)
  • I'm still learning go, so the implementation might not be ideal 😊

@AlliBalliBaba
Copy link
Contributor Author

Actually the test needs to create a file while running in the pipeline (to trigger the file watcher), but it looks like it's not allowed to do so due to permissions.

@dunglas
Copy link
Owner

dunglas commented Sep 2, 2024

Hi @AlliBalliBaba,

thank you very much for working on this feature! This is a must-have.

I also started the work on my side and created https://github.com/dunglas/go-fswatch for this purpose some weeks ago.

My bindings rely on cgo, but as we need cgo anyway, I don't think that's an issue. The benefits of the C/C++ fswatch library is that it has more features (including recursive watchers) and supports more platforms.

Would you consider switching to this library?

@AlliBalliBaba
Copy link
Contributor Author

Hey yeah, I'll try swapping to https://github.com/dunglas/go-fswatch, having recursive watching out of the box is great!

@AlliBalliBaba
Copy link
Contributor Author

I switched to your watcher and it works great 👍
Some questions @dunglas :

  • I installed fswatch from the tar in the dev.Dockerfile and tests are running locally. Not sure of all the other places where it would need to be installed
  • I saw that the library allows regex as filters, does it also allow a wildcard pattern? Wild card patterns are probably more user-friendly, it would allow removing the logic I currently implemented via filepath.Match

@dunglas
Copy link
Owner

dunglas commented Sep 2, 2024

Awesome!!

In addition to dev.Dockerfile, we'll have to compile the dynamic library in the builder stage of the Dockerfile and alpine.Dockerfile and to copy the .so in the runner stage.

We'll also avec to modify build-static.sh to compile the lib statically. (I'm not sure exactly how)

I can do this part when I'll have some time (likely after the API Platform Conference) if you want.

Regarding wildcards (globs?), I don't think that it's natively supported, but regexp are more powerful anyway.

My idea was to let users define custom regexp, but defaults to a regexp that will work for standard installations of Laravel and Symfony (and maybe other popular projects such as WordPress and Drupal) so most users will not have to figure out the regexp (or the glob) by themselves. WDYT about this approach?

@AlliBalliBaba
Copy link
Contributor Author

So I tried installing fswatch in the Dockerfiles and it works for debian, but alpine throws a dependency error
Error loading shared library libstdc++.so.6: No such file or directory

During testing I also noticed that there will sometimes be a segfault with low watcher latencies (<100ms)

expand go test SIGSEGV: segmentation violation PC=0x7f2666817f9b m=5 sigcode=2 addr=0x7f263c000ef4 signal arrived during cgo execution

goroutine 7103 gp=0xc000510c40 m=5 mp=0xc000100008 [syscall]:
runtime.cgocall(0x790d60, 0xc0115e5778)
/usr/local/go/src/runtime/cgocall.go:157 +0x4b fp=0xc0115e5750 sp=0xc0115e5718 pc=0x408d2b
github.com/dunglas/go-fswatch._Cfunc_fsw_start_monitor(0x7f2514000b70)
_cgo_gotypes.go:345 +0x47 fp=0xc0115e5778 sp=0xc0115e5750 pc=0x71eca7
github.com/dunglas/frankenphp.initWatcher.gowrap1.(*Session).Start.1(0xc0115e57d0?)
/go/pkg/mod/github.com/dunglas/[email protected]/fswatch.go:32 +0x3e fp=0xc0115e57b8 sp=0xc0115e5778 pc=0x76105e
github.com/dunglas/go-fswatch.(*Session).Start(...)
/go/pkg/mod/github.com/dunglas/[email protected]/fswatch.go:32
github.com/dunglas/frankenphp.initWatcher.gowrap1()
/go/src/app/watcher.go:32 +0x25 fp=0xc0115e57e0 sp=0xc0115e57b8 pc=0x760fe5
runtime.goexit({})
/usr/local/go/src/runtime/asm_amd64.s:1695 +0x1 fp=0xc0115e57e8 sp=0xc0115e57e0 pc=0x478ac1
created by github.com/dunglas/frankenphp.initWatcher in goroutine 7368
/go/src/app/watcher.go:32 +0x95

goroutine 1 gp=0xc0000061c0 m=nil [chan receive]:
runtime.gopark(0xc000c88750?, 0xc000c887d8?, 0x50?, 0x87?, 0x7ebac0?)
/usr/local/go/src/runtime/proc.go:402 +0xce fp=0xc0000f59c0 sp=0xc0000f59a0 pc=0x44198e
runtime.chanrecv(0xc011bb6000, 0xc0000f5aa7, 0x1)
/usr/local/go/src/runtime/chan.go:583 +0x3bf fp=0xc0000f5a38 sp=0xc0000f59c0 pc=0x40b3bf
runtime.chanrecv1(0xb83240?, 0x7bf8c0?)
/usr/local/go/src/runtime/chan.go:442 +0x12 fp=0xc0000f5a60 sp=0xc0000f5a38 pc=0x40aff2
testing.(*T).Run(0xc0000d8680, {0x85fe33?, 0x0?}, 0x8869c0)
/usr/local/go/src/testing/testing.go:1750 +0x3ab fp=0xc0000f5b20 sp=0xc0000f5a60 pc=0x50b0cb
testing.runTests.func1(0xc0000d8680)
/usr/local/go/src/testing/testing.go:2161 +0x37 fp=0xc0000f5b60 sp=0xc0000f5b20 pc=0x50d217
testing.tRunner(0xc0000d8680, 0xc000035c70)
/usr/local/go/src/testing/testing.go:1689 +0xfb fp=0xc0000f5bb0 sp=0xc0000f5b60 pc=0x50a1fb
testing.runTests(0xc000012dc8, {0xb44280, 0x41, 0x41}, {0x1?, 0x4e98ee?, 0xb83b20?})
/usr/local/go/src/testing/testing.go:2159 +0x445 fp=0xc0000f5ca0 sp=0xc0000f5bb0 pc=0x50d105
testing.(*M).Run(0xc00003b360)
/usr/local/go/src/testing/testing.go:2027 +0x68b fp=0xc0000f5ed0 sp=0xc0000f5ca0 pc=0x50bb0b
main.main()
_testmain.go:183 +0x16c fp=0xc0000f5f50 sp=0xc0000f5ed0 pc=0x78e4ac
runtime.main()
/usr/local/go/src/runtime/proc.go:271 +0x29d fp=0xc0000f5fe0 sp=0xc0000f5f50 pc=0x44153d
runtime.goexit({})
/usr/local/go/src/runtime/asm_amd64.s:1695 +0x1 fp=0xc0000f5fe8 sp=0xc0000f5fe0 pc=0x478ac1

goroutine 2 gp=0xc000006c40 m=nil [force gc (idle)]:
runtime.gopark(0x0?, 0x0?, 0x0?, 0x0?, 0x0?)
/usr/local/go/src/runtime/proc.go:402 +0xce fp=0xc00007afa8 sp=0xc00007af88 pc=0x44198e
runtime.goparkunlock(...)
/usr/local/go/src/runtime/proc.go:408
runtime.forcegchelper()
/usr/local/go/src/runtime/proc.go:326 +0xb3 fp=0xc00007afe0 sp=0xc00007afa8 pc=0x4417f3
runtime.goexit({})
/usr/local/go/src/runtime/asm_amd64.s:1695 +0x1 fp=0xc00007afe8 sp=0xc00007afe0 pc=0x478ac1
created by runtime.init.6 in goroutine 1
/usr/local/go/src/runtime/proc.go:314 +0x1a

goroutine 3 gp=0xc000007180 m=nil [GC sweep wait]:
runtime.gopark(0xb83201?, 0x0?, 0x0?, 0x0?, 0x0?)
/usr/local/go/src/runtime/proc.go:402 +0xce fp=0xc00007b780 sp=0xc00007b760 pc=0x44198e
runtime.goparkunlock(...)
/usr/local/go/src/runtime/proc.go:408
runtime.bgsweep(0xc00002e070)
/usr/local/go/src/runtime/mgcsweep.go:318 +0xdf fp=0xc00007b7c8 sp=0xc00007b780 pc=0x42ab3f
runtime.gcenable.gowrap1()
/usr/local/go/src/runtime/mgc.go:203 +0x25 fp=0xc00007b7e0 sp=0xc00007b7c8 pc=0x41f445
runtime.goexit({})
/usr/local/go/src/runtime/asm_amd64.s:1695 +0x1 fp=0xc00007b7e8 sp=0xc00007b7e0 pc=0x478ac1
created by runtime.gcenable in goroutine 1
/usr/local/go/src/runtime/mgc.go:203 +0x66

goroutine 4 gp=0xc000007340 m=nil [GC scavenge wait]:
runtime.gopark(0x10000?, 0x5d91fb?, 0x0?, 0x0?, 0x0?)
/usr/local/go/src/runtime/proc.go:402 +0xce fp=0xc00007bf78 sp=0xc00007bf58 pc=0x44198e
runtime.goparkunlock(...)
/usr/local/go/src/runtime/proc.go:408
runtime.(*scavengerState).park(0xb83cc0)
/usr/local/go/src/runtime/mgcscavenge.go:425 +0x49 fp=0xc00007bfa8 sp=0xc00007bf78 pc=0x4284e9
runtime.bgscavenge(0xc00002e070)
/usr/local/go/src/runtime/mgcscavenge.go:658 +0x59 fp=0xc00007bfc8 sp=0xc00007bfa8 pc=0x428a99
runtime.gcenable.gowrap2()
/usr/local/go/src/runtime/mgc.go:204 +0x25 fp=0xc00007bfe0 sp=0xc00007bfc8 pc=0x41f3e5
runtime.goexit({})
/usr/local/go/src/runtime/asm_amd64.s:1695 +0x1 fp=0xc00007bfe8 sp=0xc00007bfe0 pc=0x478ac1
created by runtime.gcenable in goroutine 1
/usr/local/go/src/runtime/mgc.go:204 +0xa5

goroutine 5 gp=0xc000007c00 m=nil [finalizer wait]:
runtime.gopark(0x0?, 0x886b30?, 0x0?, 0x40?, 0x1000000010?)
/usr/local/go/src/runtime/proc.go:402 +0xce fp=0xc00007a620 sp=0xc00007a600 pc=0x44198e
runtime.runfinq()
/usr/local/go/src/runtime/mfinal.go:194 +0x107 fp=0xc00007a7e0 sp=0xc00007a620 pc=0x41e487
runtime.goexit({})
/usr/local/go/src/runtime/asm_amd64.s:1695 +0x1 fp=0xc00007a7e8 sp=0xc00007a7e0 pc=0x478ac1
created by runtime.createfing in goroutine 1
/usr/local/go/src/runtime/mfinal.go:164 +0x3d

goroutine 6 gp=0xc0001861c0 m=nil [sync.Cond.Wait]:
runtime.gopark(0x774942?, 0xc00007c628?, 0x4?, 0x42?, 0xc000892100?)
/usr/local/go/src/runtime/proc.go:402 +0xce fp=0xc00007c5f8 sp=0xc00007c5d8 pc=0x44198e
runtime.goparkunlock(...)
/usr/local/go/src/runtime/proc.go:408
sync.runtime_notifyListWait(0xc0000000d8, 0x4)
/usr/local/go/src/runtime/sema.go:569 +0x159 fp=0xc00007c648 sp=0xc00007c5f8 pc=0x474f39
sync.(*Cond).Wait(0xc00007c710?)
/usr/local/go/src/sync/cond.go:70 +0x85 fp=0xc00007c688 sp=0xc00007c648 pc=0x4807c5
github.com/maypok86/otter/internal/queue.(*Growable[...]).Pop(0x8fa440)
/go/pkg/mod/github.com/maypok86/[email protected]/internal/queue/growable.go:71 +0x74 fp=0xc00007c720 sp=0xc00007c688 pc=0x7728d4
github.com/maypok86/otter/internal/core.(*Cache[...]).process(0x8ffa20)
/go/pkg/mod/github.com/maypok86/[email protected]/internal/core/cache.go:454 +0x4d fp=0xc00007c7c0 sp=0xc00007c720 pc=0x7712cd
github.com/maypok86/otter/internal/core.NewCache[...].gowrap2()
/go/pkg/mod/github.com/maypok86/[email protected]/internal/core/cache.go:188 +0x25 fp=0xc00007c7e0 sp=0xc00007c7c0 pc=0x76a845
runtime.goexit({})
/usr/local/go/src/runtime/asm_amd64.s:1695 +0x1 fp=0xc00007c7e8 sp=0xc00007c7e0 pc=0x478ac1
created by github.com/maypok86/otter/internal/core.NewCache[...] in goroutine 1
/go/pkg/mod/github.com/maypok86/[email protected]/internal/core/cache.go:188 +0x837

goroutine 220 gp=0xc000186a80 m=nil [GC worker (idle)]:
runtime.gopark(0xc0000d9a00?, 0x0?, 0x0?, 0x0?, 0x7bfb00?)
/usr/local/go/src/runtime/proc.go:402 +0xce fp=0xc0001c7750 sp=0xc0001c7730 pc=0x44198e
runtime.gcBgMarkWorker()
/usr/local/go/src/runtime/mgc.go:1310 +0xe5 fp=0xc0001c77e0 sp=0xc0001c7750 pc=0x421525
runtime.goexit({})
/usr/local/go/src/runtime/asm_amd64.s:1695 +0x1 fp=0xc0001c77e8 sp=0xc0001c77e0 pc=0x478ac1
created by runtime.gcBgMarkStartWorkers in goroutine 138
/usr/local/go/src/runtime/mgc.go:1234 +0x1c

goroutine 273 gp=0xc000187dc0 m=nil [GC worker (idle)]:
runtime.gopark(0x28c636a37dca?, 0x1?, 0xe2?, 0x76?, 0x0?)
/usr/local/go/src/runtime/proc.go:402 +0xce fp=0xc0001f3750 sp=0xc0001f3730 pc=0x44198e
runtime.gcBgMarkWorker()
/usr/local/go/src/runtime/mgc.go:1310 +0xe5 fp=0xc0001f37e0 sp=0xc0001f3750 pc=0x421525
runtime.goexit({})
/usr/local/go/src/runtime/asm_amd64.s:1695 +0x1 fp=0xc0001f37e8 sp=0xc0001f37e0 pc=0x478ac1
created by runtime.gcBgMarkStartWorkers in goroutine 138
/usr/local/go/src/runtime/mgc.go:1234 +0x1c

goroutine 271 gp=0xc0001c2000 m=nil [GC worker (idle)]:
runtime.gopark(0x28c5fc4e3c5b?, 0x1?, 0x5a?, 0xab?, 0x7bfb00?)
/usr/local/go/src/runtime/proc.go:402 +0xce fp=0xc0001f2750 sp=0xc0001f2730 pc=0x44198e
runtime.gcBgMarkWorker()
/usr/local/go/src/runtime/mgc.go:1310 +0xe5 fp=0xc0001f27e0 sp=0xc0001f2750 pc=0x421525
runtime.goexit({})
/usr/local/go/src/runtime/asm_amd64.s:1695 +0x1 fp=0xc0001f27e8 sp=0xc0001f27e0 pc=0x478ac1
created by runtime.gcBgMarkStartWorkers in goroutine 138
/usr/local/go/src/runtime/mgc.go:1234 +0x1c

goroutine 272 gp=0xc0001c21c0 m=nil [GC worker (idle)]:
runtime.gopark(0xbe61a0?, 0x1?, 0xa2?, 0x9b?, 0x0?)
/usr/local/go/src/runtime/proc.go:402 +0xce fp=0xc0001f2f50 sp=0xc0001f2f30 pc=0x44198e
runtime.gcBgMarkWorker()
/usr/local/go/src/runtime/mgc.go:1310 +0xe5 fp=0xc0001f2fe0 sp=0xc0001f2f50 pc=0x421525
runtime.goexit({})
/usr/local/go/src/runtime/asm_amd64.s:1695 +0x1 fp=0xc0001f2fe8 sp=0xc0001f2fe0 pc=0x478ac1
created by runtime.gcBgMarkStartWorkers in goroutine 138
/usr/local/go/src/runtime/mgc.go:1234 +0x1c

goroutine 270 gp=0xc0001c2380 m=nil [GC worker (idle)]:
runtime.gopark(0xbe61a0?, 0x1?, 0x97?, 0x80?, 0x7bfb00?)
/usr/local/go/src/runtime/proc.go:402 +0xce fp=0xc0001f5f50 sp=0xc0001f5f30 pc=0x44198e
runtime.gcBgMarkWorker()
/usr/local/go/src/runtime/mgc.go:1310 +0xe5 fp=0xc0001f5fe0 sp=0xc0001f5f50 pc=0x421525
runtime.goexit({})
/usr/local/go/src/runtime/asm_amd64.s:1695 +0x1 fp=0xc0001f5fe8 sp=0xc0001f5fe0 pc=0x478ac1
created by runtime.gcBgMarkStartWorkers in goroutine 138
/usr/local/go/src/runtime/mgc.go:1234 +0x1c

goroutine 268 gp=0xc0001c2540 m=nil [GC worker (idle)]:
runtime.gopark(0xc0000d9a00?, 0x0?, 0x0?, 0x0?, 0x7bfb00?)
/usr/local/go/src/runtime/proc.go:402 +0xce fp=0xc0001d5f50 sp=0xc0001d5f30 pc=0x44198e
runtime.gcBgMarkWorker()
/usr/local/go/src/runtime/mgc.go:1310 +0xe5 fp=0xc0001d5fe0 sp=0xc0001d5f50 pc=0x421525
runtime.goexit({})
/usr/local/go/src/runtime/asm_amd64.s:1695 +0x1 fp=0xc0001d5fe8 sp=0xc0001d5fe0 pc=0x478ac1
created by runtime.gcBgMarkStartWorkers in goroutine 138
/usr/local/go/src/runtime/mgc.go:1234 +0x1c

goroutine 267 gp=0xc0001c2700 m=nil [GC worker (idle)]:
runtime.gopark(0xc0000d9a00?, 0x0?, 0x0?, 0x0?, 0x7bfb00?)
/usr/local/go/src/runtime/proc.go:402 +0xce fp=0xc0001d6750 sp=0xc0001d6730 pc=0x44198e
runtime.gcBgMarkWorker()
/usr/local/go/src/runtime/mgc.go:1310 +0xe5 fp=0xc0001d67e0 sp=0xc0001d6750 pc=0x421525
runtime.goexit({})
/usr/local/go/src/runtime/asm_amd64.s:1695 +0x1 fp=0xc0001d67e8 sp=0xc0001d67e0 pc=0x478ac1
created by runtime.gcBgMarkStartWorkers in goroutine 138
/usr/local/go/src/runtime/mgc.go:1234 +0x1c

goroutine 219 gp=0xc0001c2fc0 m=nil [GC worker (idle)]:
runtime.gopark(0xc0000d9a00?, 0x0?, 0x0?, 0x0?, 0x7bfb00?)
/usr/local/go/src/runtime/proc.go:402 +0xce fp=0xc0001c6f50 sp=0xc0001c6f30 pc=0x44198e
runtime.gcBgMarkWorker()
/usr/local/go/src/runtime/mgc.go:1310 +0xe5 fp=0xc0001c6fe0 sp=0xc0001c6f50 pc=0x421525
runtime.goexit({})
/usr/local/go/src/runtime/asm_amd64.s:1695 +0x1 fp=0xc0001c6fe8 sp=0xc0001c6fe0 pc=0x478ac1
created by runtime.gcBgMarkStartWorkers in goroutine 138
/usr/local/go/src/runtime/mgc.go:1234 +0x1c

goroutine 221 gp=0xc0001c3340 m=nil [GC worker (idle)]:
runtime.gopark(0x28c5e3c5d482?, 0x1?, 0xe8?, 0xcc?, 0x7bfb00?)
/usr/local/go/src/runtime/proc.go:402 +0xce fp=0xc0001c7f50 sp=0xc0001c7f30 pc=0x44198e
runtime.gcBgMarkWorker()
/usr/local/go/src/runtime/mgc.go:1310 +0xe5 fp=0xc0001c7fe0 sp=0xc0001c7f50 pc=0x421525
runtime.goexit({})
/usr/local/go/src/runtime/asm_amd64.s:1695 +0x1 fp=0xc0001c7fe8 sp=0xc0001c7fe0 pc=0x478ac1
created by runtime.gcBgMarkStartWorkers in goroutine 138
/usr/local/go/src/runtime/mgc.go:1234 +0x1c

goroutine 269 gp=0xc0001cea80 m=nil [GC worker (idle)]:
runtime.gopark(0x28c6371f3c61?, 0x1?, 0xb1?, 0x9d?, 0x7bfb00?)
/usr/local/go/src/runtime/proc.go:402 +0xce fp=0xc0001d2750 sp=0xc0001d2730 pc=0x44198e
runtime.gcBgMarkWorker()
/usr/local/go/src/runtime/mgc.go:1310 +0xe5 fp=0xc0001d27e0 sp=0xc0001d2750 pc=0x421525
runtime.goexit({})
/usr/local/go/src/runtime/asm_amd64.s:1695 +0x1 fp=0xc0001d27e8 sp=0xc0001d27e0 pc=0x478ac1
created by runtime.gcBgMarkStartWorkers in goroutine 138
/usr/local/go/src/runtime/mgc.go:1234 +0x1c

goroutine 218 gp=0xc0001cf340 m=nil [GC worker (idle)]:
runtime.gopark(0xc0000d9a00?, 0x0?, 0x0?, 0x0?, 0x7bfb00?)
/usr/local/go/src/runtime/proc.go:402 +0xce fp=0xc0001c6750 sp=0xc0001c6730 pc=0x44198e
runtime.gcBgMarkWorker()
/usr/local/go/src/runtime/mgc.go:1310 +0xe5 fp=0xc0001c67e0 sp=0xc0001c6750 pc=0x421525
runtime.goexit({})
/usr/local/go/src/runtime/asm_amd64.s:1695 +0x1 fp=0xc0001c67e8 sp=0xc0001c67e0 pc=0x478ac1
created by runtime.gcBgMarkStartWorkers in goroutine 138
/usr/local/go/src/runtime/mgc.go:1234 +0x1c

goroutine 223 gp=0xc0001cfc00 m=nil [GC worker (idle)]:
runtime.gopark(0x28c603ab12e0?, 0x1?, 0x3c?, 0x30?, 0x0?)
/usr/local/go/src/runtime/proc.go:402 +0xce fp=0xc0001caf50 sp=0xc0001caf30 pc=0x44198e
runtime.gcBgMarkWorker()
/usr/local/go/src/runtime/mgc.go:1310 +0xe5 fp=0xc0001cafe0 sp=0xc0001caf50 pc=0x421525
runtime.goexit({})
/usr/local/go/src/runtime/asm_amd64.s:1695 +0x1 fp=0xc0001cafe8 sp=0xc0001cafe0 pc=0x478ac1
created by runtime.gcBgMarkStartWorkers in goroutine 138
/usr/local/go/src/runtime/mgc.go:1234 +0x1c

goroutine 235 gp=0xc0001d88c0 m=nil [GC worker (idle)]:
runtime.gopark(0xc0000d9a00?, 0x0?, 0x0?, 0x0?, 0x7bfb00?)
/usr/local/go/src/runtime/proc.go:402 +0xce fp=0xc0001e8750 sp=0xc0001e8730 pc=0x44198e
runtime.gcBgMarkWorker()
/usr/local/go/src/runtime/mgc.go:1310 +0xe5 fp=0xc0001e87e0 sp=0xc0001e8750 pc=0x421525
runtime.goexit({})
/usr/local/go/src/runtime/asm_amd64.s:1695 +0x1 fp=0xc0001e87e8 sp=0xc0001e87e0 pc=0x478ac1
created by runtime.gcBgMarkStartWorkers in goroutine 138
/usr/local/go/src/runtime/mgc.go:1234 +0x1c

goroutine 254 gp=0xc0001d8a80 m=nil [GC worker (idle)]:
runtime.gopark(0x28c636a37d6f?, 0x1?, 0xd7?, 0x4c?, 0x0?)
/usr/local/go/src/runtime/proc.go:402 +0xce fp=0xc0001d7f50 sp=0xc0001d7f30 pc=0x44198e
runtime.gcBgMarkWorker()
/usr/local/go/src/runtime/mgc.go:1310 +0xe5 fp=0xc0001d7fe0 sp=0xc0001d7f50 pc=0x421525
runtime.goexit({})
/usr/local/go/src/runtime/asm_amd64.s:1695 +0x1 fp=0xc0001d7fe8 sp=0xc0001d7fe0 pc=0x478ac1
created by runtime.gcBgMarkStartWorkers in goroutine 138
/usr/local/go/src/runtime/mgc.go:1234 +0x1c

goroutine 252 gp=0xc0001d8c40 m=nil [GC worker (idle)]:
runtime.gopark(0xc0000d9a00?, 0x0?, 0x0?, 0x0?, 0x7bfb00?)
/usr/local/go/src/runtime/proc.go:402 +0xce fp=0xc0001d0f50 sp=0xc0001d0f30 pc=0x44198e
runtime.gcBgMarkWorker()
/usr/local/go/src/runtime/mgc.go:1310 +0xe5 fp=0xc0001d0fe0 sp=0xc0001d0f50 pc=0x421525
runtime.goexit({})
/usr/local/go/src/runtime/asm_amd64.s:1695 +0x1 fp=0xc0001d0fe8 sp=0xc0001d0fe0 pc=0x478ac1
created by runtime.gcBgMarkStartWorkers in goroutine 138
/usr/local/go/src/runtime/mgc.go:1234 +0x1c

goroutine 255 gp=0xc0001d9180 m=nil [GC worker (idle)]:
runtime.gopark(0x28c5e799f9ad?, 0x1?, 0x7a?, 0x63?, 0x0?)
/usr/local/go/src/runtime/proc.go:402 +0xce fp=0xc0001d6f50 sp=0xc0001d6f30 pc=0x44198e
runtime.gcBgMarkWorker()
/usr/local/go/src/runtime/mgc.go:1310 +0xe5 fp=0xc0001d6fe0 sp=0xc0001d6f50 pc=0x421525
runtime.goexit({})
/usr/local/go/src/runtime/asm_amd64.s:1695 +0x1 fp=0xc0001d6fe8 sp=0xc0001d6fe0 pc=0x478ac1
created by runtime.gcBgMarkStartWorkers in goroutine 138
/usr/local/go/src/runtime/mgc.go:1234 +0x1c

goroutine 251 gp=0xc0001d9a40 m=nil [GC worker (idle)]:
runtime.gopark(0xc0000d9a00?, 0x0?, 0x0?, 0x0?, 0x7bfb00?)
/usr/local/go/src/runtime/proc.go:402 +0xce fp=0xc0001dbf50 sp=0xc0001dbf30 pc=0x44198e
runtime.gcBgMarkWorker()
/usr/local/go/src/runtime/mgc.go:1310 +0xe5 fp=0xc0001dbfe0 sp=0xc0001dbf50 pc=0x421525
runtime.goexit({})
/usr/local/go/src/runtime/asm_amd64.s:1695 +0x1 fp=0xc0001dbfe8 sp=0xc0001dbfe0 pc=0x478ac1
created by runtime.gcBgMarkStartWorkers in goroutine 138
/usr/local/go/src/runtime/mgc.go:1234 +0x1c

goroutine 253 gp=0xc0001e2c40 m=nil [GC worker (idle)]:
runtime.gopark(0x28c636a37e71?, 0x1?, 0x24?, 0xd?, 0x7bfb00?)
/usr/local/go/src/runtime/proc.go:402 +0xce fp=0xc0001d0750 sp=0xc0001d0730 pc=0x44198e
runtime.gcBgMarkWorker()
/usr/local/go/src/runtime/mgc.go:1310 +0xe5 fp=0xc0001d07e0 sp=0xc0001d0750 pc=0x421525
runtime.goexit({})
/usr/local/go/src/runtime/asm_amd64.s:1695 +0x1 fp=0xc0001d07e8 sp=0xc0001d07e0 pc=0x478ac1
created by runtime.gcBgMarkStartWorkers in goroutine 138
/usr/local/go/src/runtime/mgc.go:1234 +0x1c

goroutine 222 gp=0xc0001ece00 m=nil [GC worker (idle)]:
runtime.gopark(0x28c6033ba561?, 0x1?, 0x75?, 0x14?, 0x0?)
/usr/local/go/src/runtime/proc.go:402 +0xce fp=0xc0001ca750 sp=0xc0001ca730 pc=0x44198e
runtime.gcBgMarkWorker()
/usr/local/go/src/runtime/mgc.go:1310 +0xe5 fp=0xc0001ca7e0 sp=0xc0001ca750 pc=0x421525
runtime.goexit({})
/usr/local/go/src/runtime/asm_amd64.s:1695 +0x1 fp=0xc0001ca7e8 sp=0xc0001ca7e0 pc=0x478ac1
created by runtime.gcBgMarkStartWorkers in goroutine 138
/usr/local/go/src/runtime/mgc.go:1234 +0x1c

goroutine 224 gp=0xc0001ed500 m=nil [GC worker (idle)]:
runtime.gopark(0x28c604f96015?, 0x1?, 0x1d?, 0xdd?, 0x7bfb00?)
/usr/local/go/src/runtime/proc.go:402 +0xce fp=0xc0001cb750 sp=0xc0001cb730 pc=0x44198e
runtime.gcBgMarkWorker()
/usr/local/go/src/runtime/mgc.go:1310 +0xe5 fp=0xc0001cb7e0 sp=0xc0001cb750 pc=0x421525
runtime.goexit({})
/usr/local/go/src/runtime/asm_amd64.s:1695 +0x1 fp=0xc0001cb7e8 sp=0xc0001cb7e0 pc=0x478ac1
created by runtime.gcBgMarkStartWorkers in goroutine 138
/usr/local/go/src/runtime/mgc.go:1234 +0x1c

goroutine 132 gp=0xc0004028c0 m=nil [select, locked to thread]:
runtime.gopark(0xc000253e08?, 0x2?, 0x60?, 0x98?, 0xc000253dcc?)
/usr/local/go/src/runtime/proc.go:402 +0xce fp=0xc000253c60 sp=0xc000253c40 pc=0x44198e
runtime.selectgo(0xc000253e08, 0xc000253dc8, 0x0?, 0x0, 0xc0004028c0?, 0x1)
/usr/local/go/src/runtime/select.go:327 +0x725 fp=0xc000253d80 sp=0xc000253c60 pc=0x453725
github.com/dunglas/frankenphp.go_handle_request()
/go/src/app/frankenphp.go:474 +0x9b fp=0xc000253e48 sp=0xc000253d80 pc=0x765efb
_cgoexp_a4e4414eb6e0_go_handle_request(0x7f25ec7f7d2f)
_cgo_gotypes.go:916 +0x14 fp=0xc000253e58 sp=0xc000253e48 pc=0x76b114
runtime.cgocallbackg1(0x76b100, 0x7f25ec7f7d2f, 0x0)
/usr/local/go/src/runtime/cgocall.go:420 +0x2a5 fp=0xc000253f18 sp=0xc000253e58 pc=0x409485
runtime.cgocallbackg(0x76b100, 0x7f25ec7f7d2f, 0x0)
/usr/local/go/src/runtime/cgocall.go:339 +0x136 fp=0xc000253f90 sp=0xc000253f18 pc=0x409136
runtime.cgocallbackg(0x76b100, 0x7f25ec7f7d2f, 0x0)
:1 +0x29 fp=0xc000253fb8 sp=0xc000253f90 pc=0x47aee9
runtime.cgocallback(0x0, 0x0, 0x0)
/usr/local/go/src/runtime/asm_amd64.s:1079 +0xcc fp=0xc000253fe0 sp=0xc000253fb8 pc=0x47886c
runtime.goexit({})
/usr/local/go/src/runtime/asm_amd64.s:1695 +0x1 fp=0xc000253fe8 sp=0xc000253fe0 pc=0x478ac1

goroutine 190 gp=0xc000273500 m=nil [select, locked to thread]:
runtime.gopark(0xc00012be08?, 0x2?, 0x60?, 0x15?, 0xc00012bdcc?)
/usr/local/go/src/runtime/proc.go:402 +0xce fp=0xc00012bc60 sp=0xc00012bc40 pc=0x44198e
runtime.selectgo(0xc00012be08, 0xc00012bdc8, 0x0?, 0x0, 0xc000273500?, 0x1)
/usr/local/go/src/runtime/select.go:327 +0x725 fp=0xc00012bd80 sp=0xc00012bc60 pc=0x453725
github.com/dunglas/frankenphp.go_handle_request()
/go/src/app/frankenphp.go:474 +0x9b fp=0xc00012be48 sp=0xc00012bd80 pc=0x765efb
_cgoexp_a4e4414eb6e0_go_handle_request(0x7f25f8ff8d2f)
_cgo_gotypes.go:916 +0x14 fp=0xc00012be58 sp=0xc00012be48 pc=0x76b114
runtime.cgocallbackg1(0x76b100, 0x7f25f8ff8d2f, 0x0)
/usr/local/go/src/runtime/cgocall.go:420 +0x2a5 fp=0xc00012bf18 sp=0xc00012be58 pc=0x409485
runtime.cgocallbackg(0x76b100, 0x7f25f8ff8d2f, 0x0)
/usr/local/go/src/runtime/cgocall.go:339 +0x136 fp=0xc00012bf90 sp=0xc00012bf18 pc=0x409136
runtime.cgocallbackg(0x76b100, 0x7f25f8ff8d2f, 0x0)
:1 +0x29 fp=0xc00012bfb8 sp=0xc00012bf90 pc=0x47aee9
runtime.cgocallback(0x0, 0x0, 0x0)
/usr/local/go/src/runtime/asm_amd64.s:1079 +0xcc fp=0xc00012bfe0 sp=0xc00012bfb8 pc=0x47886c
runtime.goexit({})
/usr/local/go/src/runtime/asm_amd64.s:1695 +0x1 fp=0xc00012bfe8 sp=0xc00012bfe0 pc=0x478ac1

goroutine 198 gp=0xc00064cfc0 m=nil [select, locked to thread]:
runtime.gopark(0xc000db3e08?, 0x2?, 0xe0?, 0x44?, 0xc000db3dcc?)
/usr/local/go/src/runtime/proc.go:402 +0xce fp=0xc000db3c60 sp=0xc000db3c40 pc=0x44198e
runtime.selectgo(0xc000db3e08, 0xc000db3dc8, 0x0?, 0x0, 0xc00064cfc0?, 0x1)
/usr/local/go/src/runtime/select.go:327 +0x725 fp=0xc000db3d80 sp=0xc000db3c60 pc=0x453725
github.com/dunglas/frankenphp.go_handle_request()
/go/src/app/frankenphp.go:474 +0x9b fp=0xc000db3e48 sp=0xc000db3d80 pc=0x765efb
_cgoexp_a4e4414eb6e0_go_handle_request(0x7f25f9ffad2f)
_cgo_gotypes.go:916 +0x14 fp=0xc000db3e58 sp=0xc000db3e48 pc=0x76b114
runtime.cgocallbackg1(0x76b100, 0x7f25f9ffad2f, 0x0)
/usr/local/go/src/runtime/cgocall.go:420 +0x2a5 fp=0xc000db3f18 sp=0xc000db3e58 pc=0x409485
runtime.cgocallbackg(0x76b100, 0x7f25f9ffad2f, 0x0)
/usr/local/go/src/runtime/cgocall.go:339 +0x136 fp=0xc000db3f90 sp=0xc000db3f18 pc=0x409136
runtime.cgocallbackg(0x76b100, 0x7f25f9ffad2f, 0x0)
:1 +0x29 fp=0xc000db3fb8 sp=0xc000db3f90 pc=0x47aee9
runtime.cgocallback(0x0, 0x0, 0x0)
/usr/local/go/src/runtime/asm_amd64.s:1079 +0xcc fp=0xc000db3fe0 sp=0xc000db3fb8 pc=0x47886c
runtime.goexit({})
/usr/local/go/src/runtime/asm_amd64.s:1695 +0x1 fp=0xc000db3fe8 sp=0xc000db3fe0 pc=0x478ac1

goroutine 199 gp=0xc00064d6c0 m=nil [select, locked to thread]:
runtime.gopark(0xc000525e08?, 0x2?, 0x20?, 0x24?, 0xc000525dcc?)
/usr/local/go/src/runtime/proc.go:402 +0xce fp=0xc000525c60 sp=0xc000525c40 pc=0x44198e
runtime.selectgo(0xc000525e08, 0xc000525dc8, 0x0?, 0x0, 0xc00064d6c0?, 0x1)
/usr/local/go/src/runtime/select.go:327 +0x725 fp=0xc000525d80 sp=0xc000525c60 pc=0x453725
github.com/dunglas/frankenphp.go_handle_request()
/go/src/app/frankenphp.go:474 +0x9b fp=0xc000525e48 sp=0xc000525d80 pc=0x765efb
_cgoexp_a4e4414eb6e0_go_handle_request(0x7f25f97f9d2f)
_cgo_gotypes.go:916 +0x14 fp=0xc000525e58 sp=0xc000525e48 pc=0x76b114
runtime.cgocallbackg1(0x76b100, 0x7f25f97f9d2f, 0x0)
/usr/local/go/src/runtime/cgocall.go:420 +0x2a5 fp=0xc000525f18 sp=0xc000525e58 pc=0x409485
runtime.cgocallbackg(0x76b100, 0x7f25f97f9d2f, 0x0)
/usr/local/go/src/runtime/cgocall.go:339 +0x136 fp=0xc000525f90 sp=0xc000525f18 pc=0x409136
runtime.cgocallbackg(0x76b100, 0x7f25f97f9d2f, 0x0)
:1 +0x29 fp=0xc000525fb8 sp=0xc000525f90 pc=0x47aee9
runtime.cgocallback(0x0, 0x0, 0x0)
/usr/local/go/src/runtime/asm_amd64.s:1079 +0xcc fp=0xc000525fe0 sp=0xc000525fb8 pc=0x47886c
runtime.goexit({})
/usr/local/go/src/runtime/asm_amd64.s:1695 +0x1 fp=0xc000525fe8 sp=0xc000525fe0 pc=0x478ac1

goroutine 203 gp=0xc00067f340 m=nil [select, locked to thread]:
runtime.gopark(0xc000ae1e08?, 0x2?, 0xc0?, 0x12?, 0xc000ae1dcc?)
/usr/local/go/src/runtime/proc.go:402 +0xce fp=0xc000ae1c60 sp=0xc000ae1c40 pc=0x44198e
runtime.selectgo(0xc000ae1e08, 0xc000ae1dc8, 0x0?, 0x0, 0xc00067f340?, 0x1)
/usr/local/go/src/runtime/select.go:327 +0x725 fp=0xc000ae1d80 sp=0xc000ae1c60 pc=0x453725
github.com/dunglas/frankenphp.go_handle_request()
/go/src/app/frankenphp.go:474 +0x9b fp=0xc000ae1e48 sp=0xc000ae1d80 pc=0x765efb
_cgoexp_a4e4414eb6e0_go_handle_request(0x7f25efffed2f)
_cgo_gotypes.go:916 +0x14 fp=0xc000ae1e58 sp=0xc000ae1e48 pc=0x76b114
runtime.cgocallbackg1(0x76b100, 0x7f25efffed2f, 0x0)
/usr/local/go/src/runtime/cgocall.go:420 +0x2a5 fp=0xc000ae1f18 sp=0xc000ae1e58 pc=0x409485
runtime.cgocallbackg(0x76b100, 0x7f25efffed2f, 0x0)
/usr/local/go/src/runtime/cgocall.go:339 +0x136 fp=0xc000ae1f90 sp=0xc000ae1f18 pc=0x409136
runtime.cgocallbackg(0x76b100, 0x7f25efffed2f, 0x0)
:1 +0x29 fp=0xc000ae1fb8 sp=0xc000ae1f90 pc=0x47aee9
runtime.cgocallback(0x0, 0x0, 0x0)
/usr/local/go/src/runtime/asm_amd64.s:1079 +0xcc fp=0xc000ae1fe0 sp=0xc000ae1fb8 pc=0x47886c
runtime.goexit({})
/usr/local/go/src/runtime/asm_amd64.s:1695 +0x1 fp=0xc000ae1fe8 sp=0xc000ae1fe0 pc=0x478ac1

goroutine 206 gp=0xc000760700 m=nil [select, locked to thread]:
runtime.gopark(0xc011b87e08?, 0x2?, 0xe0?, 0xf0?, 0xc011b87dcc?)
/usr/local/go/src/runtime/proc.go:402 +0xce fp=0xc011b87c60 sp=0xc011b87c40 pc=0x44198e
runtime.selectgo(0xc011b87e08, 0xc011b87dc8, 0x0?, 0x0, 0xc000760700?, 0x1)
/usr/local/go/src/runtime/select.go:327 +0x725 fp=0xc011b87d80 sp=0xc011b87c60 pc=0x453725
github.com/dunglas/frankenphp.go_handle_request()
/go/src/app/frankenphp.go:474 +0x9b fp=0xc011b87e48 sp=0xc011b87d80 pc=0x765efb
_cgoexp_a4e4414eb6e0_go_handle_request(0x7f2618e0ed2f)
_cgo_gotypes.go:916 +0x14 fp=0xc011b87e58 sp=0xc011b87e48 pc=0x76b114
runtime.cgocallbackg1(0x76b100, 0x7f2618e0ed2f, 0x0)
/usr/local/go/src/runtime/cgocall.go:420 +0x2a5 fp=0xc011b87f18 sp=0xc011b87e58 pc=0x409485
runtime.cgocallbackg(0x76b100, 0x7f2618e0ed2f, 0x0)
/usr/local/go/src/runtime/cgocall.go:339 +0x136 fp=0xc011b87f90 sp=0xc011b87f18 pc=0x409136
runtime.cgocallbackg(0x76b100, 0x7f2618e0ed2f, 0x0)
:1 +0x29 fp=0xc011b87fb8 sp=0xc011b87f90 pc=0x47aee9
runtime.cgocallback(0x0, 0x0, 0x0)
/usr/local/go/src/runtime/asm_amd64.s:1079 +0xcc fp=0xc011b87fe0 sp=0xc011b87fb8 pc=0x47886c
runtime.goexit({})
/usr/local/go/src/runtime/asm_amd64.s:1695 +0x1 fp=0xc011b87fe8 sp=0xc011b87fe0 pc=0x478ac1

goroutine 208 gp=0xc000511180 m=nil [select, locked to thread]:
runtime.gopark(0xc00011faf8?, 0x2?, 0x0?, 0x0?, 0xc00011f89c?)
/usr/local/go/src/runtime/proc.go:402 +0xce fp=0xc00011f738 sp=0xc00011f718 pc=0x44198e
runtime.selectgo(0xc00011faf8, 0xc00011f898, 0x1?, 0x0, 0xc00011fa08?, 0x1)
/usr/local/go/src/runtime/select.go:327 +0x725 fp=0xc00011f858 sp=0xc00011f738 pc=0x453725
github.com/dunglas/frankenphp.go_frankenphp_worker_handle_request_start(0x2e42)
/go/src/app/worker.go:173 +0x293 fp=0xc00011fb70 sp=0xc00011f858 pc=0x769a73
_cgoexp_a4e4414eb6e0_go_frankenphp_worker_handle_request_start(0x7f25affb53c0)
_cgo_gotypes.go:1023 +0x1e fp=0xc00011fb88 sp=0xc00011fb70 pc=0x76b49e
runtime.cgocallbackg1(0x76b480, 0x7f25affb53c0, 0x0)
/usr/local/go/src/runtime/cgocall.go:420 +0x2a5 fp=0xc00011fc48 sp=0xc00011fb88 pc=0x409485
runtime.cgocallbackg(0x76b480, 0x7f25affb53c0, 0x0)
/usr/local/go/src/runtime/cgocall.go:339 +0x136 fp=0xc00011fcc0 sp=0xc00011fc48 pc=0x409136
runtime.cgocallbackg(0x76b480, 0x7f25affb53c0, 0x0)
:1 +0x29 fp=0xc00011fce8 sp=0xc00011fcc0 pc=0x47aee9
runtime.cgocallback(0xc00011fd48, 0x408d55, 0x78e9e0)
/usr/local/go/src/runtime/asm_amd64.s:1079 +0xcc fp=0xc00011fd10 sp=0xc00011fce8 pc=0x47886c
runtime.systemstack_switch()
/usr/local/go/src/runtime/asm_amd64.s:474 +0x8 fp=0xc00011fd20 sp=0xc00011fd10 pc=0x476aa8
runtime.cgocall(0x78e9e0, 0xc00011fd80)
/usr/local/go/src/runtime/cgocall.go:175 +0x75 fp=0xc00011fd58 sp=0xc00011fd20 pc=0x408d55
github.com/dunglas/frankenphp._Cfunc_frankenphp_execute_script(0x7f25fc001350)
_cgo_gotypes.go:792 +0x47 fp=0xc00011fd80 sp=0xc00011fd58 pc=0x7631c7
github.com/dunglas/frankenphp.go_handle_request()
/go/src/app/frankenphp.go:496 +0x279 fp=0xc00011fe48 sp=0xc00011fd80 pc=0x7660d9
_cgoexp_a4e4414eb6e0_go_handle_request(0x7f25affb6d2f)
_cgo_gotypes.go:916 +0x14 fp=0xc00011fe58 sp=0xc00011fe48 pc=0x76b114
runtime.cgocallbackg1(0x76b100, 0x7f25affb6d2f, 0x0)
/usr/local/go/src/runtime/cgocall.go:420 +0x2a5 fp=0xc00011ff18 sp=0xc00011fe58 pc=0x409485
runtime.cgocallbackg(0x76b100, 0x7f25affb6d2f, 0x0)
/usr/local/go/src/runtime/cgocall.go:339 +0x136 fp=0xc00011ff90 sp=0xc00011ff18 pc=0x409136
runtime.cgocallbackg(0x76b100, 0x7f25affb6d2f, 0x0)
:1 +0x29 fp=0xc00011ffb8 sp=0xc00011ff90 pc=0x47aee9
runtime.cgocallback(0x0, 0x0, 0x0)
/usr/local/go/src/runtime/asm_amd64.s:1079 +0xcc fp=0xc00011ffe0 sp=0xc00011ffb8 pc=0x47886c
runtime.goexit({})
/usr/local/go/src/runtime/asm_amd64.s:1695 +0x1 fp=0xc00011ffe8 sp=0xc00011ffe0 pc=0x478ac1

goroutine 211 gp=0xc000562700 m=nil [select, locked to thread]:
runtime.gopark(0xc0008d1e08?, 0x2?, 0x80?, 0xfc?, 0xc0008d1dcc?)
/usr/local/go/src/runtime/proc.go:402 +0xce fp=0xc0008d1c60 sp=0xc0008d1c40 pc=0x44198e
runtime.selectgo(0xc0008d1e08, 0xc0008d1dc8, 0x0?, 0x0, 0xc000562700?, 0x1)
/usr/local/go/src/runtime/select.go:327 +0x725 fp=0xc0008d1d80 sp=0xc0008d1c60 pc=0x453725
github.com/dunglas/frankenphp.go_handle_request()
/go/src/app/frankenphp.go:474 +0x9b fp=0xc0008d1e48 sp=0xc0008d1d80 pc=0x765efb
_cgoexp_a4e4414eb6e0_go_handle_request(0x7f25b07f7d2f)
_cgo_gotypes.go:916 +0x14 fp=0xc0008d1e58 sp=0xc0008d1e48 pc=0x76b114
runtime.cgocallbackg1(0x76b100, 0x7f25b07f7d2f, 0x0)
/usr/local/go/src/runtime/cgocall.go:420 +0x2a5 fp=0xc0008d1f18 sp=0xc0008d1e58 pc=0x409485
runtime.cgocallbackg(0x76b100, 0x7f25b07f7d2f, 0x0)
/usr/local/go/src/runtime/cgocall.go:339 +0x136 fp=0xc0008d1f90 sp=0xc0008d1f18 pc=0x409136
runtime.cgocallbackg(0x76b100, 0x7f25b07f7d2f, 0x0)
:1 +0x29 fp=0xc0008d1fb8 sp=0xc0008d1f90 pc=0x47aee9
runtime.cgocallback(0x0, 0x0, 0x0)
/usr/local/go/src/runtime/asm_amd64.s:1079 +0xcc fp=0xc0008d1fe0 sp=0xc0008d1fb8 pc=0x47886c
runtime.goexit({})
/usr/local/go/src/runtime/asm_amd64.s:1695 +0x1 fp=0xc0008d1fe8 sp=0xc0008d1fe0 pc=0x478ac1

goroutine 212 gp=0xc000562e00 m=nil [select, locked to thread]:
runtime.gopark(0xc0008cfe08?, 0x2?, 0x20?, 0x13?, 0xc0008cfdcc?)
/usr/local/go/src/runtime/proc.go:402 +0xce fp=0xc0008cfc60 sp=0xc0008cfc40 pc=0x44198e
runtime.selectgo(0xc0008cfe08, 0xc0008cfdc8, 0x0?, 0x0, 0xc000562e00?, 0x1)
/usr/local/go/src/runtime/select.go:327 +0x725 fp=0xc0008cfd80 sp=0xc0008cfc60 pc=0x453725
github.com/dunglas/frankenphp.go_handle_request()
/go/src/app/frankenphp.go:474 +0x9b fp=0xc0008cfe48 sp=0xc0008cfd80 pc=0x765efb
_cgoexp_a4e4414eb6e0_go_handle_request(0x7f25fb7fdd2f)
_cgo_gotypes.go:916 +0x14 fp=0xc0008cfe58 sp=0xc0008cfe48 pc=0x76b114
runtime.cgocallbackg1(0x76b100, 0x7f25fb7fdd2f, 0x0)
/usr/local/go/src/runtime/cgocall.go:420 +0x2a5 fp=0xc0008cff18 sp=0xc0008cfe58 pc=0x409485
runtime.cgocallbackg(0x76b100, 0x7f25fb7fdd2f, 0x0)
/usr/local/go/src/runtime/cgocall.go:339 +0x136 fp=0xc0008cff90 sp=0xc0008cff18 pc=0x409136
runtime.cgocallbackg(0x76b100, 0x7f25fb7fdd2f, 0x0)
:1 +0x29 fp=0xc0008cffb8 sp=0xc0008cff90 pc=0x47aee9
runtime.cgocallback(0x0, 0x0, 0x0)
/usr/local/go/src/runtime/asm_amd64.s:1079 +0xcc fp=0xc0008cffe0 sp=0xc0008cffb8 pc=0x47886c
runtime.goexit({})
/usr/local/go/src/runtime/asm_amd64.s:1695 +0x1 fp=0xc0008cffe8 sp=0xc0008cffe0 pc=0x478ac1

goroutine 213 gp=0xc000563500 m=nil [select, locked to thread]:
runtime.gopark(0xc000f95e08?, 0x2?, 0xc0?, 0xfb?, 0xc000f95dcc?)
/usr/local/go/src/runtime/proc.go:402 +0xce fp=0xc000f95c60 sp=0xc000f95c40 pc=0x44198e
runtime.selectgo(0xc000f95e08, 0xc000f95dc8, 0x0?, 0x0, 0xc000563500?, 0x1)
/usr/local/go/src/runtime/select.go:327 +0x725 fp=0xc000f95d80 sp=0xc000f95c60 pc=0x453725
github.com/dunglas/frankenphp.go_handle_request()
/go/src/app/frankenphp.go:474 +0x9b fp=0xc000f95e48 sp=0xc000f95d80 pc=0x765efb
_cgoexp_a4e4414eb6e0_go_handle_request(0x7f25faffcd2f)
_cgo_gotypes.go:916 +0x14 fp=0xc000f95e58 sp=0xc000f95e48 pc=0x76b114
runtime.cgocallbackg1(0x76b100, 0x7f25faffcd2f, 0x0)
/usr/local/go/src/runtime/cgocall.go:420 +0x2a5 fp=0xc000f95f18 sp=0xc000f95e58 pc=0x409485
runtime.cgocallbackg(0x76b100, 0x7f25faffcd2f, 0x0)
/usr/local/go/src/runtime/cgocall.go:339 +0x136 fp=0xc000f95f90 sp=0xc000f95f18 pc=0x409136
runtime.cgocallbackg(0x76b100, 0x7f25faffcd2f, 0x0)
:1 +0x29 fp=0xc000f95fb8 sp=0xc000f95f90 pc=0x47aee9
runtime.cgocallback(0x0, 0x0, 0x0)
/usr/local/go/src/runtime/asm_amd64.s:1079 +0xcc fp=0xc000f95fe0 sp=0xc000f95fb8 pc=0x47886c
runtime.goexit({})
/usr/local/go/src/runtime/asm_amd64.s:1695 +0x1 fp=0xc000f95fe8 sp=0xc000f95fe0 pc=0x478ac1

goroutine 214 gp=0xc000563c00 m=nil [select, locked to thread]:
runtime.gopark(0xc000dafe08?, 0x2?, 0x0?, 0xf2?, 0xc000dafdcc?)
/usr/local/go/src/runtime/proc.go:402 +0xce fp=0xc000dafc60 sp=0xc000dafc40 pc=0x44198e
runtime.selectgo(0xc000dafe08, 0xc000dafdc8, 0x0?, 0x0, 0xc000563c00?, 0x1)
/usr/local/go/src/runtime/select.go:327 +0x725 fp=0xc000dafd80 sp=0xc000dafc60 pc=0x453725
github.com/dunglas/frankenphp.go_handle_request()
/go/src/app/frankenphp.go:474 +0x9b fp=0xc000dafe48 sp=0xc000dafd80 pc=0x765efb
_cgoexp_a4e4414eb6e0_go_handle_request(0x7f25fa7fbd2f)
_cgo_gotypes.go:916 +0x14 fp=0xc000dafe58 sp=0xc000dafe48 pc=0x76b114
runtime.cgocallbackg1(0x76b100, 0x7f25fa7fbd2f, 0x0)
/usr/local/go/src/runtime/cgocall.go:420 +0x2a5 fp=0xc000daff18 sp=0xc000dafe58 pc=0x409485
runtime.cgocallbackg(0x76b100, 0x7f25fa7fbd2f, 0x0)
/usr/local/go/src/runtime/cgocall.go:339 +0x136 fp=0xc000daff90 sp=0xc000daff18 pc=0x409136
runtime.cgocallbackg(0x76b100, 0x7f25fa7fbd2f, 0x0)
:1 +0x29 fp=0xc000daffb8 sp=0xc000daff90 pc=0x47aee9
runtime.cgocallback(0x0, 0x0, 0x0)
/usr/local/go/src/runtime/asm_amd64.s:1079 +0xcc fp=0xc000daffe0 sp=0xc000daffb8 pc=0x47886c
runtime.goexit({})
/usr/local/go/src/runtime/asm_amd64.s:1695 +0x1 fp=0xc000daffe8 sp=0xc000daffe0 pc=0x478ac1

goroutine 7104 gp=0xc000403dc0 m=12 mp=0xc000580008 [syscall]:
runtime.cgocall(0x790d60, 0xc0002c7f78)
/usr/local/go/src/runtime/cgocall.go:157 +0x4b fp=0xc0002c7f50 sp=0xc0002c7f18 pc=0x408d2b
github.com/dunglas/go-fswatch._Cfunc_fsw_start_monitor(0x7f2514000b70)
_cgo_gotypes.go:345 +0x47 fp=0xc0002c7f78 sp=0xc0002c7f50 pc=0x71eca7
github.com/dunglas/frankenphp.initWatcher.gowrap2.(*Session).Start.1(0xc0002c7fd0?)
/go/pkg/mod/github.com/dunglas/[email protected]/fswatch.go:32 +0x3e fp=0xc0002c7fb8 sp=0xc0002c7f78 pc=0x760f7e
github.com/dunglas/go-fswatch.(*Session).Start(...)
/go/pkg/mod/github.com/dunglas/[email protected]/fswatch.go:32
github.com/dunglas/frankenphp.initWatcher.gowrap2()
/go/src/app/watcher.go:36 +0x25 fp=0xc0002c7fe0 sp=0xc0002c7fb8 pc=0x760f05
runtime.goexit({})
/usr/local/go/src/runtime/asm_amd64.s:1695 +0x1 fp=0xc0002c7fe8 sp=0xc0002c7fe0 pc=0x478ac1
created by github.com/dunglas/frankenphp.initWatcher in goroutine 7368
/go/src/app/watcher.go:36 +0x1d1

goroutine 7368 gp=0xc00042ca80 m=nil [semacquire]:
runtime.gopark(0xc000277cf0?, 0xc000277d28?, 0x60?, 0x6?, 0xc000277d08?)
/usr/local/go/src/runtime/proc.go:402 +0xce fp=0xc000277c98 sp=0xc000277c78 pc=0x44198e
runtime.goparkunlock(...)
/usr/local/go/src/runtime/proc.go:408
runtime.semacquire1(0xc000869108, 0x0, 0x1, 0x0, 0x12)
/usr/local/go/src/runtime/sema.go:160 +0x225 fp=0xc000277d00 sp=0xc000277c98 pc=0x454765
sync.runtime_Semacquire(0xc0005abcf8?)
/usr/local/go/src/runtime/sema.go:62 +0x25 fp=0xc000277d38 sp=0xc000277d00 pc=0x474bc5
sync.(*WaitGroup).Wait(0x8f56f0?)
/usr/local/go/src/sync/waitgroup.go:116 +0x48 fp=0xc000277d60 sp=0xc000277d38 pc=0x4833e8
github.com/dunglas/frankenphp_test.runTest(0xc011766340, 0xc011769c00, 0x24?)
/go/src/app/frankenphp_test.go:98 +0x6b2 fp=0xc000277ee8 sp=0xc000277d60 pc=0x77ca32
github.com/dunglas/frankenphp_test.TestWorkerShouldReloadOnMatchingPattern(0xc011766340)
/go/src/app/watcher_test.go:21 +0xbf fp=0xc000277f70 sp=0xc000277ee8 pc=0x78bb1f
testing.tRunner(0xc011766340, 0x8869c0)
/usr/local/go/src/testing/testing.go:1689 +0xfb fp=0xc000277fc0 sp=0xc000277f70 pc=0x50a1fb
testing.(*T).Run.gowrap1()
/usr/local/go/src/testing/testing.go:1742 +0x25 fp=0xc000277fe0 sp=0xc000277fc0 pc=0x50b225
runtime.goexit({})
/usr/local/go/src/runtime/asm_amd64.s:1695 +0x1 fp=0xc000277fe8 sp=0xc000277fe0 pc=0x478ac1
created by testing.(*T).Run in goroutine 1
/usr/local/go/src/testing/testing.go:1742 +0x390

goroutine 7369 gp=0xc000129dc0 m=nil [chan receive]:
runtime.gopark(0x2?, 0x0?, 0x0?, 0x0?, 0xc00092e0a0?)
/usr/local/go/src/runtime/proc.go:402 +0xce fp=0xc011b93b98 sp=0xc011b93b78 pc=0x44198e
runtime.chanrecv(0xc01173fd40, 0x0, 0x1)
/usr/local/go/src/runtime/chan.go:583 +0x3bf fp=0xc011b93c10 sp=0xc011b93b98 pc=0x40b3bf
runtime.chanrecv1(0xc011b93c98?, 0xc011b93c70?)
/usr/local/go/src/runtime/chan.go:442 +0x12 fp=0xc011b93c38 sp=0xc011b93c10 pc=0x40aff2
github.com/dunglas/frankenphp.ServeHTTP({0x0, 0x0}, 0xc0117750e0)
/go/src/app/frankenphp.go:466 +0x20e fp=0xc011b93cf8 sp=0xc011b93c38 pc=0x765d2e
github.com/dunglas/frankenphp.startWorkers.func1()
/go/src/app/worker.go:87 +0x3e6 fp=0xc011b93fe0 sp=0xc011b93cf8 pc=0x768ee6
runtime.goexit({})
/usr/local/go/src/runtime/asm_amd64.s:1695 +0x1 fp=0xc011b93fe8 sp=0xc011b93fe0 pc=0x478ac1
created by github.com/dunglas/frankenphp.startWorkers in goroutine 7368
/go/src/app/worker.go:65 +0x34e

goroutine 7105 gp=0xc0009be380 m=nil [runnable]:
runtime.gopark(0x2?, 0xc0118de360?, 0x2d?, 0x0?, 0xc000306d20?)
/usr/local/go/src/runtime/proc.go:402 +0xce fp=0xc000306cd0 sp=0xc000306cb0 pc=0x44198e
runtime.chanrecv(0xc000a11380, 0x0, 0x1)
/usr/local/go/src/runtime/chan.go:583 +0x3bf fp=0xc000306d48 sp=0xc000306cd0 pc=0x40b3bf
runtime.chanrecv1(0xc000306dd0?, 0xc000306da8?)
/usr/local/go/src/runtime/chan.go:442 +0x12 fp=0xc000306d70 sp=0xc000306d48 pc=0x40aff2
github.com/dunglas/frankenphp.ServeHTTP({0x8f68b0, 0xc011899380}, 0xc0118c5320)
/go/src/app/frankenphp.go:466 +0x20e fp=0xc000306e30 sp=0xc000306d70 pc=0x765d2e
github.com/dunglas/frankenphp_test.runTest.func1({0x8f68b0, 0xc011899380}, 0x86175e?)
/go/src/app/frankenphp_test.go:79 +0xc8 fp=0xc000306eb0 sp=0xc000306e30 pc=0x77cca8
github.com/dunglas/frankenphp_test.fetchBody({0x84d909?, 0x7?}, {0x86175e?, 0x769700?}, 0xc0118b51c0)
/go/src/app/watcher_test.go:60 +0xb6 fp=0xc000306f18 sp=0xc000306eb0 pc=0x78bfd6
github.com/dunglas/frankenphp_test.TestWorkerShouldReloadOnMatchingPattern.func1(0xc0118b51c0, 0x6666666666666666?, 0x6666666666666666?)
/go/src/app/watcher_test.go:23 +0x45 fp=0xc000306f98 sp=0xc000306f18 pc=0x78bb85
github.com/dunglas/frankenphp_test.runTest.func2(0xc0115e5f20?)
/go/src/app/frankenphp_test.go:93 +0x32 fp=0xc000306fc8 sp=0xc000306f98 pc=0x77cb52
github.com/dunglas/frankenphp_test.runTest.gowrap2()
/go/src/app/frankenphp_test.go:95 +0x24 fp=0xc000306fe0 sp=0xc000306fc8 pc=0x77cae4
runtime.goexit({})
/usr/local/go/src/runtime/asm_amd64.s:1695 +0x1 fp=0xc000306fe8 sp=0xc000306fe0 pc=0x478ac1
created by github.com/dunglas/frankenphp_test.runTest in goroutine 7368
/go/src/app/frankenphp_test.go:92 +0x5b4

rax 0x4
rbx 0x7f2514000c74
rcx 0x1
rdx 0x7f2514000c74
rdi 0x10
rsi 0x7f2604000ed0
rbp 0x7f2604000d70
rsp 0x7f261bcdbbb0
r8 0x7
r9 0x0
r10 0x7f26667e3100
r11 0x7f2666817ef0
r12 0xe000061
r13 0x7f263c000ef4
r14 0x38000184
r15 0x2
rip 0x7f2666817f9b
rflags 0x10202
cs 0x33
fs 0x0
gs 0x0
exit status 2

Additionally I can't modify the github workflows and fswatch would have to be installed everywhere there as well So I think it's better if you do it.

The dependency on fswatch definitely makes the whole building and testing process a lot more complicated compared to the pure go implementation of fsnotify. It does offer better compatibility though

@AlliBalliBaba
Copy link
Contributor Author

I wonder if it's possible to bundle up the fswatch binary into go-fswatch directly so we could skip all these build steps.

@AlliBalliBaba
Copy link
Contributor Author

And to adress your regex question, my original intention was to stay compatible with the wilcard syntax that chokidar also uses, like here in laravel octane:
https://github.com/laravel/octane/blob/eef1549eb6d9a277c26cba2ad97a71625158e25a/config/octane.php#L186-L196

But I'm also fine with regex if there are other ways to abstract that away, people just tend to shoot themselves in the foot with regex 😅

@dunglas
Copy link
Owner

dunglas commented Sep 3, 2024

Bundling the C lib in go-fswatch would be practical but will require huge CI work (similar to what we've done here for FrankenPHP) because we'll have to cross-compile the C lib.

Also, this is likely not what many users want as libfswatch is packaged by some distributions, including Debian (unfortunately, the current packaged version is too old to be used by go-fswatch, but it will likely be updated at some point).
It's quite uncommon that Go modules bundle C libraries for these reasons.

IMHO it would be easier to handle that part directly in FrankenPHP, as we have most of the needed infrastructure.

Regarding regexp, I wouldn't bother with Chokidar compatibility. Chokidar will continue to work in Octane (so existing setups will not be broken). I agree that regexp are harder to master, but they are also more powerful.

@AlliBalliBaba
Copy link
Contributor Author

Alright we can go with ./**/*.{php,yaml,yml,twig,env} since that should cover most Symfony and Laravel applications. I'll also document and test the the {case1,case2} pattern

@AlliBalliBaba
Copy link
Contributor Author

I guess we'll wait for #1038 to merge first? There will probably be conflicts

@withinboredom
Copy link
Collaborator

I did it with your changes in mind, so they should be pretty straightforward if you merge. Rebasing (I didn't take into account your change history) might be far more complicated.

@dunglas
Copy link
Owner

dunglas commented Oct 4, 2024

@AlliBalliBaba do you mind if I rebase and merge this one? (I would like to test it on Mac)

@AlliBalliBaba
Copy link
Contributor Author

Sounds good to me 👍

@dunglas
Copy link
Owner

dunglas commented Oct 5, 2024

I'm not sure of the interaction of workersAreReady introduced in this patch and the new fc.ready introduced by @withinboredom. Should we the former, the later or both?

@AlliBalliBaba
Copy link
Contributor Author

I dislike the Waitgoup.Add(1) here, that's why I removed it. Its only purpose is to not have the waitgroup go negative since we don't care about it anymore after startup anyways.

@AlliBalliBaba
Copy link
Contributor Author

I also plan to make a PR that stores a slice of php_thread structs on the go side. That makes it so we don't have to pass handles and can instead reference threads by their index in the slice. That's more performant and will also allow storing thread specific data on the go side, aka whether a specific thread is ready, busy, shutting down ect.

@dunglas
Copy link
Owner

dunglas commented Oct 5, 2024

Good idea for the thread slice!

Finally, would you mind merging main in your branch (or rebasing)? I'" not sure to be able to do it without introducing mistakes.

@withinboredom
Copy link
Collaborator

Do you mind if I go for the rebase?

@AlliBalliBaba
Copy link
Contributor Author

AlliBalliBaba commented Oct 6, 2024

@withinboredom I just merged it 😅, read your message a few minutes too late.

I adjusted the backoff constants a bit, since the server shouldn't crash immediately when editing the worker file itself, here's a video showing what I mean:
https://github.com/user-attachments/assets/9b202267-d0ec-40b7-b8d0-6cfb5565ae6c

Do you think 1sec maxBackoff + 60 retries is fine @withinboredom ?

Also I noticed that tests got a lot slower after merging 6s -> 15s. Not sure where that comes from.

@dunglas
Copy link
Owner

dunglas commented Oct 6, 2024

@withinboredom what do you think as merged this patch as soon as you reviewed it, so we can iterate (if needed) in follow-up PRs?

@withinboredom
Copy link
Collaborator

Also I noticed that tests got a lot slower after merging 6s -> 15s. Not sure where that comes from.

It's from failing-worker.php in the testdata directory. It's a worker that deliberately fails some % of time, while trying to process requests. By making the backoff longer, the test takes longer to stabilize and process the requests.

@withinboredom
Copy link
Collaborator

withinboredom commented Oct 6, 2024

Yeah, lets merge this @dunglas and any issues can be handled in PRs. LGTM

@dunglas dunglas self-requested a review October 7, 2024 11:15
@dunglas dunglas merged commit 8d9b6e7 into dunglas:main Oct 7, 2024
32 checks passed
@dunglas
Copy link
Owner

dunglas commented Oct 7, 2024

Thank you very much @AlliBalliBaba. Huge work!

@nickchomey
Copy link

nickchomey commented Oct 7, 2024

FYI, fsnotify has some initial support for recursion. It's only for Linux right now, and it isn't enabled yet. But the dev gave me some instructions here on how to enable it. Not sure if that could be helpful to simplify things here/reduce tech debt.

@AlliBalliBaba
Copy link
Contributor Author

@nickchomey thank you for the info! We definitely plan to switch to a pure go solution at some point since it will make compilation easier.
Probably once recursion and fanotify are officially supported 👍.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

7 participants