mirror of
https://github.com/dunglas/frankenphp.git
synced 2025-12-24 13:38:11 +08:00
@@ -35,8 +35,8 @@ import (
|
||||
"syscall"
|
||||
"time"
|
||||
"unsafe"
|
||||
// debug on Linux
|
||||
//_ "github.com/ianlancetaylor/cgosymbolizer"
|
||||
|
||||
"golang.org/x/sync/semaphore"
|
||||
)
|
||||
|
||||
type contextKeyStruct struct{}
|
||||
@@ -307,9 +307,11 @@ func Init(options ...Option) error {
|
||||
return err
|
||||
}
|
||||
|
||||
regularRequestChan = make(chan contextHolder, opt.numThreads-workerThreadCount)
|
||||
regularThreads = make([]*phpThread, 0, opt.numThreads-workerThreadCount)
|
||||
for i := 0; i < opt.numThreads-workerThreadCount; i++ {
|
||||
numRegularThreads := opt.numThreads - workerThreadCount
|
||||
regularRequestChan = make(chan contextHolder)
|
||||
regularSemaphore = semaphore.NewWeighted(int64(numRegularThreads))
|
||||
regularThreads = make([]*phpThread, 0, numRegularThreads)
|
||||
for i := 0; i < numRegularThreads; i++ {
|
||||
convertToRegularThread(getInactivePHPThread())
|
||||
}
|
||||
|
||||
|
||||
1
go.mod
1
go.mod
@@ -13,6 +13,7 @@ require (
|
||||
go.uber.org/zap v1.27.0
|
||||
go.uber.org/zap/exp v0.3.0
|
||||
golang.org/x/net v0.47.0
|
||||
golang.org/x/sync v0.18.0
|
||||
)
|
||||
|
||||
require (
|
||||
|
||||
@@ -2,7 +2,10 @@ package frankenphp
|
||||
|
||||
import (
|
||||
"context"
|
||||
"runtime"
|
||||
"sync"
|
||||
|
||||
"golang.org/x/sync/semaphore"
|
||||
)
|
||||
|
||||
// representation of a non-worker PHP thread
|
||||
@@ -19,6 +22,7 @@ var (
|
||||
regularThreads []*phpThread
|
||||
regularThreadMu = &sync.RWMutex{}
|
||||
regularRequestChan chan contextHolder
|
||||
regularSemaphore *semaphore.Weighted // FIFO admission control
|
||||
)
|
||||
|
||||
func convertToRegularThread(thread *phpThread) {
|
||||
@@ -100,6 +104,16 @@ func (handler *regularThread) afterRequest() {
|
||||
func handleRequestWithRegularPHPThreads(ch contextHolder) error {
|
||||
metrics.StartRequest()
|
||||
|
||||
// yield to ensure this goroutine doesn't end up on the same P queue
|
||||
runtime.Gosched()
|
||||
|
||||
// Enforce FIFO ordering of requests
|
||||
if err := regularSemaphore.Acquire(ch.ctx, 1); err != nil {
|
||||
ch.frankenPHPContext.reject(err)
|
||||
return err
|
||||
}
|
||||
defer regularSemaphore.Release(1)
|
||||
|
||||
select {
|
||||
case regularRequestChan <- ch:
|
||||
// a thread was available to handle the request immediately
|
||||
|
||||
Reference in New Issue
Block a user