mirror of
https://github.com/dunglas/frankenphp.git
synced 2025-09-26 19:41:13 +08:00
chore!: update to golangci-lint-action 7 (#1508)
This commit is contained in:
2
.github/workflows/tests.yaml
vendored
2
.github/workflows/tests.yaml
vendored
@@ -68,7 +68,7 @@ jobs:
|
|||||||
- name: Run integrations tests
|
- name: Run integrations tests
|
||||||
run: ./reload_test.sh
|
run: ./reload_test.sh
|
||||||
- name: Lint Go code
|
- name: Lint Go code
|
||||||
uses: golangci/golangci-lint-action@v6
|
uses: golangci/golangci-lint-action@v7
|
||||||
if: matrix.php-versions == '8.4'
|
if: matrix.php-versions == '8.4'
|
||||||
with:
|
with:
|
||||||
version: latest
|
version: latest
|
||||||
|
@@ -44,7 +44,7 @@ func (admin *FrankenPHPAdmin) restartWorkers(w http.ResponseWriter, r *http.Requ
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (admin *FrankenPHPAdmin) threads(w http.ResponseWriter, r *http.Request) error {
|
func (admin *FrankenPHPAdmin) threads(w http.ResponseWriter, _ *http.Request) error {
|
||||||
debugState := frankenphp.DebugState()
|
debugState := frankenphp.DebugState()
|
||||||
prettyJson, err := json.MarshalIndent(debugState, "", " ")
|
prettyJson, err := json.MarshalIndent(debugState, "", " ")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
4
cgi.go
4
cgi.go
@@ -168,7 +168,7 @@ func packCgiVariable(key *C.zend_string, value string) C.ht_key_value_pair {
|
|||||||
return C.ht_key_value_pair{key, toUnsafeChar(value), C.size_t(len(value))}
|
return C.ht_key_value_pair{key, toUnsafeChar(value), C.size_t(len(value))}
|
||||||
}
|
}
|
||||||
|
|
||||||
func addHeadersToServer(thread *phpThread, fc *frankenPHPContext, trackVarsArray *C.zval) {
|
func addHeadersToServer(fc *frankenPHPContext, trackVarsArray *C.zval) {
|
||||||
for field, val := range fc.request.Header {
|
for field, val := range fc.request.Header {
|
||||||
if k := mainThread.commonHeaders[field]; k != nil {
|
if k := mainThread.commonHeaders[field]; k != nil {
|
||||||
v := strings.Join(val, ", ")
|
v := strings.Join(val, ", ")
|
||||||
@@ -197,7 +197,7 @@ func go_register_variables(threadIndex C.uintptr_t, trackVarsArray *C.zval) {
|
|||||||
fc := thread.getRequestContext()
|
fc := thread.getRequestContext()
|
||||||
|
|
||||||
addKnownVariablesToServer(thread, fc, trackVarsArray)
|
addKnownVariablesToServer(thread, fc, trackVarsArray)
|
||||||
addHeadersToServer(thread, fc, trackVarsArray)
|
addHeadersToServer(fc, trackVarsArray)
|
||||||
|
|
||||||
// The Prepared Environment is registered last and can overwrite any previous values
|
// The Prepared Environment is registered last and can overwrite any previous values
|
||||||
addPreparedEnvToServer(fc, trackVarsArray)
|
addPreparedEnvToServer(fc, trackVarsArray)
|
||||||
|
@@ -55,13 +55,13 @@ type contextKeyStruct struct{}
|
|||||||
var contextKey = contextKeyStruct{}
|
var contextKey = contextKeyStruct{}
|
||||||
|
|
||||||
var (
|
var (
|
||||||
InvalidRequestError = errors.New("not a FrankenPHP request")
|
ErrInvalidRequest = errors.New("not a FrankenPHP request")
|
||||||
AlreadyStartedError = errors.New("FrankenPHP is already started")
|
ErrAlreadyStarted = errors.New("FrankenPHP is already started")
|
||||||
InvalidPHPVersionError = errors.New("FrankenPHP is only compatible with PHP 8.2+")
|
ErrInvalidPHPVersion = errors.New("FrankenPHP is only compatible with PHP 8.2+")
|
||||||
MainThreadCreationError = errors.New("error creating the main thread")
|
ErrMainThreadCreation = errors.New("error creating the main thread")
|
||||||
RequestContextCreationError = errors.New("error during request context creation")
|
ErrRequestContextCreation = errors.New("error during request context creation")
|
||||||
ScriptExecutionError = errors.New("error during PHP script execution")
|
ErrScriptExecution = errors.New("error during PHP script execution")
|
||||||
NotRunningError = errors.New("FrankenPHP is not running. For proper configuration visit: https://frankenphp.dev/docs/config/#caddyfile-config")
|
ErrNotRunning = errors.New("FrankenPHP is not running. For proper configuration visit: https://frankenphp.dev/docs/config/#caddyfile-config")
|
||||||
|
|
||||||
isRunning bool
|
isRunning bool
|
||||||
|
|
||||||
@@ -189,7 +189,7 @@ func calculateMaxThreads(opt *opt) (int, int, int, error) {
|
|||||||
return opt.numThreads, numWorkers, opt.maxThreads, nil
|
return opt.numThreads, numWorkers, opt.maxThreads, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
if !numThreadsIsSet && !maxThreadsIsSet {
|
if !numThreadsIsSet {
|
||||||
if numWorkers >= maxProcs {
|
if numWorkers >= maxProcs {
|
||||||
// Start at least as many threads as workers, and keep a free thread to handle requests in non-worker mode
|
// Start at least as many threads as workers, and keep a free thread to handle requests in non-worker mode
|
||||||
opt.numThreads = numWorkers + 1
|
opt.numThreads = numWorkers + 1
|
||||||
@@ -218,7 +218,7 @@ func calculateMaxThreads(opt *opt) (int, int, int, error) {
|
|||||||
// Init starts the PHP runtime and the configured workers.
|
// Init starts the PHP runtime and the configured workers.
|
||||||
func Init(options ...Option) error {
|
func Init(options ...Option) error {
|
||||||
if isRunning {
|
if isRunning {
|
||||||
return AlreadyStartedError
|
return ErrAlreadyStarted
|
||||||
}
|
}
|
||||||
isRunning = true
|
isRunning = true
|
||||||
|
|
||||||
@@ -265,7 +265,7 @@ func Init(options ...Option) error {
|
|||||||
config := Config()
|
config := Config()
|
||||||
|
|
||||||
if config.Version.MajorVersion < 8 || (config.Version.MajorVersion == 8 && config.Version.MinorVersion < 2) {
|
if config.Version.MajorVersion < 8 || (config.Version.MajorVersion == 8 && config.Version.MinorVersion < 2) {
|
||||||
return InvalidPHPVersionError
|
return ErrInvalidPHPVersion
|
||||||
}
|
}
|
||||||
|
|
||||||
if config.ZTS {
|
if config.ZTS {
|
||||||
@@ -381,7 +381,7 @@ func updateServerContext(thread *phpThread, fc *frankenPHPContext, isWorkerReque
|
|||||||
)
|
)
|
||||||
|
|
||||||
if ret > 0 {
|
if ret > 0 {
|
||||||
return RequestContextCreationError
|
return ErrRequestContextCreation
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
@@ -390,12 +390,12 @@ func updateServerContext(thread *phpThread, fc *frankenPHPContext, isWorkerReque
|
|||||||
// ServeHTTP executes a PHP script according to the given context.
|
// ServeHTTP executes a PHP script according to the given context.
|
||||||
func ServeHTTP(responseWriter http.ResponseWriter, request *http.Request) error {
|
func ServeHTTP(responseWriter http.ResponseWriter, request *http.Request) error {
|
||||||
if !isRunning {
|
if !isRunning {
|
||||||
return NotRunningError
|
return ErrNotRunning
|
||||||
}
|
}
|
||||||
|
|
||||||
fc, ok := fromContext(request.Context())
|
fc, ok := fromContext(request.Context())
|
||||||
if !ok {
|
if !ok {
|
||||||
return InvalidRequestError
|
return ErrInvalidRequest
|
||||||
}
|
}
|
||||||
|
|
||||||
fc.responseWriter = responseWriter
|
fc.responseWriter = responseWriter
|
||||||
|
@@ -754,7 +754,7 @@ func testFileUpload(t *testing.T, opts *testOptions) {
|
|||||||
_, err := part.Write([]byte("bar"))
|
_, err := part.Write([]byte("bar"))
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
writer.Close()
|
require.NoError(t, writer.Close())
|
||||||
|
|
||||||
req := httptest.NewRequest("POST", "http://example.com/file-upload.php", requestBody)
|
req := httptest.NewRequest("POST", "http://example.com/file-upload.php", requestBody)
|
||||||
req.Header.Add("Content-Type", writer.FormDataContentType())
|
req.Header.Add("Content-Type", writer.FormDataContentType())
|
||||||
|
@@ -37,14 +37,15 @@ var failureMu = sync.Mutex{}
|
|||||||
var watcherIsActive = atomic.Bool{}
|
var watcherIsActive = atomic.Bool{}
|
||||||
|
|
||||||
var (
|
var (
|
||||||
|
ErrAlreadyStarted = errors.New("the watcher is already running")
|
||||||
|
ErrUnableToStartWatching = errors.New("unable to start the watcher")
|
||||||
|
|
||||||
// the currently active file watcher
|
// the currently active file watcher
|
||||||
activeWatcher *watcher
|
activeWatcher *watcher
|
||||||
// after stopping the watcher we will wait for eventual reloads to finish
|
// after stopping the watcher we will wait for eventual reloads to finish
|
||||||
reloadWaitGroup sync.WaitGroup
|
reloadWaitGroup sync.WaitGroup
|
||||||
// we are passing the logger from the main package to the watcher
|
// we are passing the logger from the main package to the watcher
|
||||||
logger *zap.Logger
|
logger *zap.Logger
|
||||||
AlreadyStartedError = errors.New("the watcher is already running")
|
|
||||||
UnableToStartWatching = errors.New("unable to start the watcher")
|
|
||||||
)
|
)
|
||||||
|
|
||||||
func InitWatcher(filePatterns []string, callback func(), zapLogger *zap.Logger) error {
|
func InitWatcher(filePatterns []string, callback func(), zapLogger *zap.Logger) error {
|
||||||
@@ -52,7 +53,7 @@ func InitWatcher(filePatterns []string, callback func(), zapLogger *zap.Logger)
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
if watcherIsActive.Load() {
|
if watcherIsActive.Load() {
|
||||||
return AlreadyStartedError
|
return ErrAlreadyStarted
|
||||||
}
|
}
|
||||||
watcherIsActive.Store(true)
|
watcherIsActive.Store(true)
|
||||||
logger = zapLogger
|
logger = zapLogger
|
||||||
@@ -142,7 +143,7 @@ func startSession(w *watchPattern) (C.uintptr_t, error) {
|
|||||||
}
|
}
|
||||||
logger.Error("couldn't start watching", zap.String("dir", w.dir))
|
logger.Error("couldn't start watching", zap.String("dir", w.dir))
|
||||||
|
|
||||||
return watchSession, UnableToStartWatching
|
return watchSession, ErrUnableToStartWatching
|
||||||
}
|
}
|
||||||
|
|
||||||
func stopSession(session C.uintptr_t) {
|
func stopSession(session C.uintptr_t) {
|
||||||
@@ -186,7 +187,6 @@ func listenForFileEvents(triggerWatcher chan string, stopWatcher chan struct{})
|
|||||||
for {
|
for {
|
||||||
select {
|
select {
|
||||||
case <-stopWatcher:
|
case <-stopWatcher:
|
||||||
break
|
|
||||||
case lastChangedFile = <-triggerWatcher:
|
case lastChangedFile = <-triggerWatcher:
|
||||||
timer.Reset(debounceDuration)
|
timer.Reset(debounceDuration)
|
||||||
case <-timer.C:
|
case <-timer.C:
|
||||||
|
11
metrics.go
11
metrics.go
@@ -11,7 +11,7 @@ import (
|
|||||||
const (
|
const (
|
||||||
StopReasonCrash = iota
|
StopReasonCrash = iota
|
||||||
StopReasonRestart
|
StopReasonRestart
|
||||||
StopReasonShutdown
|
//StopReasonShutdown
|
||||||
)
|
)
|
||||||
|
|
||||||
type StopReason int
|
type StopReason int
|
||||||
@@ -74,9 +74,9 @@ func (n nullMetrics) StartWorkerRequest(string) {
|
|||||||
func (n nullMetrics) Shutdown() {
|
func (n nullMetrics) Shutdown() {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (n nullMetrics) QueuedWorkerRequest(name string) {}
|
func (n nullMetrics) QueuedWorkerRequest(string) {}
|
||||||
|
|
||||||
func (n nullMetrics) DequeuedWorkerRequest(name string) {}
|
func (n nullMetrics) DequeuedWorkerRequest(string) {}
|
||||||
|
|
||||||
func (n nullMetrics) QueuedRequest() {}
|
func (n nullMetrics) QueuedRequest() {}
|
||||||
func (n nullMetrics) DequeuedRequest() {}
|
func (n nullMetrics) DequeuedRequest() {}
|
||||||
@@ -127,9 +127,10 @@ func (m *PrometheusMetrics) StopWorker(name string, reason StopReason) {
|
|||||||
m.totalWorkers.WithLabelValues(name).Dec()
|
m.totalWorkers.WithLabelValues(name).Dec()
|
||||||
m.readyWorkers.WithLabelValues(name).Dec()
|
m.readyWorkers.WithLabelValues(name).Dec()
|
||||||
|
|
||||||
if reason == StopReasonCrash {
|
switch reason {
|
||||||
|
case StopReasonCrash:
|
||||||
m.workerCrashes.WithLabelValues(name).Inc()
|
m.workerCrashes.WithLabelValues(name).Inc()
|
||||||
} else if reason == StopReasonRestart {
|
case StopReasonRestart:
|
||||||
m.workerRestarts.WithLabelValues(name).Inc()
|
m.workerRestarts.WithLabelValues(name).Inc()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -107,7 +107,7 @@ func drainPHPThreads() {
|
|||||||
|
|
||||||
func (mainThread *phpMainThread) start() error {
|
func (mainThread *phpMainThread) start() error {
|
||||||
if C.frankenphp_new_main_thread(C.int(mainThread.numThreads)) != 0 {
|
if C.frankenphp_new_main_thread(C.int(mainThread.numThreads)) != 0 {
|
||||||
return MainThreadCreationError
|
return ErrMainThreadCreation
|
||||||
}
|
}
|
||||||
|
|
||||||
mainThread.state.waitFor(stateReady)
|
mainThread.state.waitFor(stateReady)
|
||||||
@@ -144,15 +144,6 @@ func getInactivePHPThread() *phpThread {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func getPHPThreadAtState(state stateID) *phpThread {
|
|
||||||
for _, thread := range phpThreads {
|
|
||||||
if thread.state.is(state) {
|
|
||||||
return thread
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
//export go_frankenphp_main_thread_is_ready
|
//export go_frankenphp_main_thread_is_ready
|
||||||
func go_frankenphp_main_thread_is_ready() {
|
func go_frankenphp_main_thread_is_ready() {
|
||||||
mainThread.setAutomaticMaxThreads()
|
mainThread.setAutomaticMaxThreads()
|
||||||
|
@@ -220,7 +220,7 @@ func allPossibleTransitions(worker1Path string, worker2Path string) []func(*phpT
|
|||||||
|
|
||||||
func TestCorrectThreadCalculation(t *testing.T) {
|
func TestCorrectThreadCalculation(t *testing.T) {
|
||||||
maxProcs := runtime.GOMAXPROCS(0) * 2
|
maxProcs := runtime.GOMAXPROCS(0) * 2
|
||||||
oneWorkerThread := []workerOpt{workerOpt{num: 1}}
|
oneWorkerThread := []workerOpt{{num: 1}}
|
||||||
|
|
||||||
// default values
|
// default values
|
||||||
testThreadCalculation(t, maxProcs, maxProcs, &opt{})
|
testThreadCalculation(t, maxProcs, maxProcs, &opt{})
|
||||||
|
@@ -149,7 +149,7 @@ func go_frankenphp_before_script_execution(threadIndex C.uintptr_t) *C.char {
|
|||||||
func go_frankenphp_after_script_execution(threadIndex C.uintptr_t, exitStatus C.int) {
|
func go_frankenphp_after_script_execution(threadIndex C.uintptr_t, exitStatus C.int) {
|
||||||
thread := phpThreads[threadIndex]
|
thread := phpThreads[threadIndex]
|
||||||
if exitStatus < 0 {
|
if exitStatus < 0 {
|
||||||
panic(ScriptExecutionError)
|
panic(ErrScriptExecution)
|
||||||
}
|
}
|
||||||
thread.handler.afterScriptExecution(int(exitStatus))
|
thread.handler.afterScriptExecution(int(exitStatus))
|
||||||
|
|
||||||
|
12
scaling.go
12
scaling.go
@@ -20,8 +20,6 @@ const (
|
|||||||
cpuProbeTime = 120 * time.Millisecond
|
cpuProbeTime = 120 * time.Millisecond
|
||||||
// do not scale over this amount of CPU usage
|
// do not scale over this amount of CPU usage
|
||||||
maxCpuUsageForScaling = 0.8
|
maxCpuUsageForScaling = 0.8
|
||||||
// upscale stalled threads every x milliseconds
|
|
||||||
upscaleCheckTime = 100 * time.Millisecond
|
|
||||||
// downscale idle threads every x seconds
|
// downscale idle threads every x seconds
|
||||||
downScaleCheckTime = 5 * time.Second
|
downScaleCheckTime = 5 * time.Second
|
||||||
// max amount of threads stopped in one iteration of downScaleCheckTime
|
// max amount of threads stopped in one iteration of downScaleCheckTime
|
||||||
@@ -31,13 +29,11 @@ const (
|
|||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
|
ErrMaxThreadsReached = errors.New("max amount of overall threads reached")
|
||||||
|
|
||||||
scaleChan chan *frankenPHPContext
|
scaleChan chan *frankenPHPContext
|
||||||
autoScaledThreads = []*phpThread{}
|
autoScaledThreads = []*phpThread{}
|
||||||
scalingMu = new(sync.RWMutex)
|
scalingMu = new(sync.RWMutex)
|
||||||
|
|
||||||
MaxThreadsReachedError = errors.New("max amount of overall threads reached")
|
|
||||||
CannotRemoveLastThreadError = errors.New("cannot remove last thread")
|
|
||||||
WorkerNotFoundError = errors.New("worker not found for given filename")
|
|
||||||
)
|
)
|
||||||
|
|
||||||
func initAutoScaling(mainThread *phpMainThread) {
|
func initAutoScaling(mainThread *phpMainThread) {
|
||||||
@@ -67,7 +63,7 @@ func drainAutoScaling() {
|
|||||||
func addRegularThread() (*phpThread, error) {
|
func addRegularThread() (*phpThread, error) {
|
||||||
thread := getInactivePHPThread()
|
thread := getInactivePHPThread()
|
||||||
if thread == nil {
|
if thread == nil {
|
||||||
return nil, MaxThreadsReachedError
|
return nil, ErrMaxThreadsReached
|
||||||
}
|
}
|
||||||
convertToRegularThread(thread)
|
convertToRegularThread(thread)
|
||||||
thread.state.waitFor(stateReady, stateShuttingDown, stateReserved)
|
thread.state.waitFor(stateReady, stateShuttingDown, stateReserved)
|
||||||
@@ -77,7 +73,7 @@ func addRegularThread() (*phpThread, error) {
|
|||||||
func addWorkerThread(worker *worker) (*phpThread, error) {
|
func addWorkerThread(worker *worker) (*phpThread, error) {
|
||||||
thread := getInactivePHPThread()
|
thread := getInactivePHPThread()
|
||||||
if thread == nil {
|
if thread == nil {
|
||||||
return nil, MaxThreadsReachedError
|
return nil, ErrMaxThreadsReached
|
||||||
}
|
}
|
||||||
convertToWorkerThread(thread, worker)
|
convertToWorkerThread(thread, worker)
|
||||||
thread.state.waitFor(stateReady, stateShuttingDown, stateReserved)
|
thread.state.waitFor(stateReady, stateShuttingDown, stateReserved)
|
||||||
|
@@ -33,7 +33,7 @@ func (handler *inactiveThread) beforeScriptExecution() string {
|
|||||||
panic("unexpected state: " + thread.state.name())
|
panic("unexpected state: " + thread.state.name())
|
||||||
}
|
}
|
||||||
|
|
||||||
func (handler *inactiveThread) afterScriptExecution(exitStatus int) {
|
func (handler *inactiveThread) afterScriptExecution(int) {
|
||||||
panic("inactive threads should not execute scripts")
|
panic("inactive threads should not execute scripts")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -47,7 +47,7 @@ func (handler *regularThread) beforeScriptExecution() string {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// return true if the worker should continue to run
|
// return true if the worker should continue to run
|
||||||
func (handler *regularThread) afterScriptExecution(exitStatus int) {
|
func (handler *regularThread) afterScriptExecution(int) {
|
||||||
handler.afterRequest()
|
handler.afterRequest()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -2,6 +2,7 @@ package frankenphp_test
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"github.com/stretchr/testify/require"
|
||||||
"io"
|
"io"
|
||||||
"log"
|
"log"
|
||||||
"net/http"
|
"net/http"
|
||||||
@@ -139,7 +140,8 @@ func ExampleServeHTTP_workers() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func TestWorkerHasOSEnvironmentVariableInSERVER(t *testing.T) {
|
func TestWorkerHasOSEnvironmentVariableInSERVER(t *testing.T) {
|
||||||
os.Setenv("CUSTOM_OS_ENV_VARIABLE", "custom_env_variable_value")
|
require.NoError(t, os.Setenv("CUSTOM_OS_ENV_VARIABLE", "custom_env_variable_value"))
|
||||||
|
|
||||||
runTest(t, func(handler func(http.ResponseWriter, *http.Request), _ *httptest.Server, i int) {
|
runTest(t, func(handler func(http.ResponseWriter, *http.Request), _ *httptest.Server, i int) {
|
||||||
req := httptest.NewRequest("GET", "http://example.com/worker.php", nil)
|
req := httptest.NewRequest("GET", "http://example.com/worker.php", nil)
|
||||||
w := httptest.NewRecorder()
|
w := httptest.NewRecorder()
|
||||||
|
Reference in New Issue
Block a user