Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/tests.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ jobs:
- name: Run integrations tests
run: ./reload_test.sh
- name: Lint Go code
uses: golangci/golangci-lint-action@v6
uses: golangci/golangci-lint-action@v7
if: matrix.php-versions == '8.4'
with:
version: latest
Expand Down
2 changes: 1 addition & 1 deletion caddy/admin.go
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ func (admin *FrankenPHPAdmin) restartWorkers(w http.ResponseWriter, r *http.Requ
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()
prettyJson, err := json.MarshalIndent(debugState, "", " ")
if err != nil {
Expand Down
4 changes: 2 additions & 2 deletions cgi.go
Original file line number Diff line number Diff line change
Expand Up @@ -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))}
}

func addHeadersToServer(thread *phpThread, fc *frankenPHPContext, trackVarsArray *C.zval) {
func addHeadersToServer(fc *frankenPHPContext, trackVarsArray *C.zval) {
for field, val := range fc.request.Header {
if k := mainThread.commonHeaders[field]; k != nil {
v := strings.Join(val, ", ")
Expand Down Expand Up @@ -197,7 +197,7 @@ func go_register_variables(threadIndex C.uintptr_t, trackVarsArray *C.zval) {
fc := thread.getRequestContext()

addKnownVariablesToServer(thread, fc, trackVarsArray)
addHeadersToServer(thread, fc, trackVarsArray)
addHeadersToServer(fc, trackVarsArray)

// The Prepared Environment is registered last and can overwrite any previous values
addPreparedEnvToServer(fc, trackVarsArray)
Expand Down
26 changes: 13 additions & 13 deletions frankenphp.go
Original file line number Diff line number Diff line change
Expand Up @@ -55,13 +55,13 @@ type contextKeyStruct struct{}
var contextKey = contextKeyStruct{}

var (
InvalidRequestError = errors.New("not a FrankenPHP request")
AlreadyStartedError = errors.New("FrankenPHP is already started")
InvalidPHPVersionError = errors.New("FrankenPHP is only compatible with PHP 8.2+")
MainThreadCreationError = errors.New("error creating the main thread")
RequestContextCreationError = errors.New("error during request context creation")
ScriptExecutionError = 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")
ErrInvalidRequest = errors.New("not a FrankenPHP request")
ErrAlreadyStarted = errors.New("FrankenPHP is already started")
ErrInvalidPHPVersion = errors.New("FrankenPHP is only compatible with PHP 8.2+")
ErrMainThreadCreation = errors.New("error creating the main thread")
ErrRequestContextCreation = errors.New("error during request context creation")
ErrScriptExecution = errors.New("error during PHP script execution")
ErrNotRunning = errors.New("FrankenPHP is not running. For proper configuration visit: https://frankenphp.dev/docs/config/#caddyfile-config")

isRunning bool

Expand Down Expand Up @@ -189,7 +189,7 @@ func calculateMaxThreads(opt *opt) (int, int, int, error) {
return opt.numThreads, numWorkers, opt.maxThreads, nil
}

if !numThreadsIsSet && !maxThreadsIsSet {
if !numThreadsIsSet {
if numWorkers >= maxProcs {
// Start at least as many threads as workers, and keep a free thread to handle requests in non-worker mode
opt.numThreads = numWorkers + 1
Expand Down Expand Up @@ -218,7 +218,7 @@ func calculateMaxThreads(opt *opt) (int, int, int, error) {
// Init starts the PHP runtime and the configured workers.
func Init(options ...Option) error {
if isRunning {
return AlreadyStartedError
return ErrAlreadyStarted
}
isRunning = true

Expand Down Expand Up @@ -265,7 +265,7 @@ func Init(options ...Option) error {
config := Config()

if config.Version.MajorVersion < 8 || (config.Version.MajorVersion == 8 && config.Version.MinorVersion < 2) {
return InvalidPHPVersionError
return ErrInvalidPHPVersion
}

if config.ZTS {
Expand Down Expand Up @@ -381,7 +381,7 @@ func updateServerContext(thread *phpThread, fc *frankenPHPContext, isWorkerReque
)

if ret > 0 {
return RequestContextCreationError
return ErrRequestContextCreation
}

return nil
Expand All @@ -390,12 +390,12 @@ func updateServerContext(thread *phpThread, fc *frankenPHPContext, isWorkerReque
// ServeHTTP executes a PHP script according to the given context.
func ServeHTTP(responseWriter http.ResponseWriter, request *http.Request) error {
if !isRunning {
return NotRunningError
return ErrNotRunning
}

fc, ok := fromContext(request.Context())
if !ok {
return InvalidRequestError
return ErrInvalidRequest
}

fc.responseWriter = responseWriter
Expand Down
2 changes: 1 addition & 1 deletion frankenphp_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -754,7 +754,7 @@ func testFileUpload(t *testing.T, opts *testOptions) {
_, err := part.Write([]byte("bar"))
require.NoError(t, err)

writer.Close()
require.NoError(t, writer.Close())

req := httptest.NewRequest("POST", "http://example.com/file-upload.php", requestBody)
req.Header.Add("Content-Type", writer.FormDataContentType())
Expand Down
12 changes: 6 additions & 6 deletions internal/watcher/watcher.go
Original file line number Diff line number Diff line change
Expand Up @@ -37,22 +37,23 @@ var failureMu = sync.Mutex{}
var watcherIsActive = atomic.Bool{}

var (
ErrAlreadyStarted = errors.New("the watcher is already running")
ErrUnableToStartWatching = errors.New("unable to start the watcher")

// the currently active file watcher
activeWatcher *watcher
// after stopping the watcher we will wait for eventual reloads to finish
reloadWaitGroup sync.WaitGroup
// we are passing the logger from the main package to the watcher
logger *zap.Logger
AlreadyStartedError = errors.New("the watcher is already running")
UnableToStartWatching = errors.New("unable to start the watcher")
logger *zap.Logger
)

func InitWatcher(filePatterns []string, callback func(), zapLogger *zap.Logger) error {
if len(filePatterns) == 0 {
return nil
}
if watcherIsActive.Load() {
return AlreadyStartedError
return ErrAlreadyStarted
}
watcherIsActive.Store(true)
logger = zapLogger
Expand Down Expand Up @@ -142,7 +143,7 @@ func startSession(w *watchPattern) (C.uintptr_t, error) {
}
logger.Error("couldn't start watching", zap.String("dir", w.dir))

return watchSession, UnableToStartWatching
return watchSession, ErrUnableToStartWatching
}

func stopSession(session C.uintptr_t) {
Expand Down Expand Up @@ -186,7 +187,6 @@ func listenForFileEvents(triggerWatcher chan string, stopWatcher chan struct{})
for {
select {
case <-stopWatcher:
break
case lastChangedFile = <-triggerWatcher:
timer.Reset(debounceDuration)
case <-timer.C:
Expand Down
11 changes: 6 additions & 5 deletions metrics.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import (
const (
StopReasonCrash = iota
StopReasonRestart
StopReasonShutdown
//StopReasonShutdown
)

type StopReason int
Expand Down Expand Up @@ -74,9 +74,9 @@ func (n nullMetrics) StartWorkerRequest(string) {
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) DequeuedRequest() {}
Expand Down Expand Up @@ -127,9 +127,10 @@ func (m *PrometheusMetrics) StopWorker(name string, reason StopReason) {
m.totalWorkers.WithLabelValues(name).Dec()
m.readyWorkers.WithLabelValues(name).Dec()

if reason == StopReasonCrash {
switch reason {
case StopReasonCrash:
m.workerCrashes.WithLabelValues(name).Inc()
} else if reason == StopReasonRestart {
case StopReasonRestart:
m.workerRestarts.WithLabelValues(name).Inc()
}
}
Expand Down
11 changes: 1 addition & 10 deletions phpmainthread.go
Original file line number Diff line number Diff line change
Expand Up @@ -107,7 +107,7 @@ func drainPHPThreads() {

func (mainThread *phpMainThread) start() error {
if C.frankenphp_new_main_thread(C.int(mainThread.numThreads)) != 0 {
return MainThreadCreationError
return ErrMainThreadCreation
}

mainThread.state.waitFor(stateReady)
Expand Down Expand Up @@ -144,15 +144,6 @@ func getInactivePHPThread() *phpThread {
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
func go_frankenphp_main_thread_is_ready() {
mainThread.setAutomaticMaxThreads()
Expand Down
2 changes: 1 addition & 1 deletion phpmainthread_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -220,7 +220,7 @@ func allPossibleTransitions(worker1Path string, worker2Path string) []func(*phpT

func TestCorrectThreadCalculation(t *testing.T) {
maxProcs := runtime.GOMAXPROCS(0) * 2
oneWorkerThread := []workerOpt{workerOpt{num: 1}}
oneWorkerThread := []workerOpt{{num: 1}}

// default values
testThreadCalculation(t, maxProcs, maxProcs, &opt{})
Expand Down
2 changes: 1 addition & 1 deletion phpthread.go
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
thread := phpThreads[threadIndex]
if exitStatus < 0 {
panic(ScriptExecutionError)
panic(ErrScriptExecution)
}
thread.handler.afterScriptExecution(int(exitStatus))

Expand Down
12 changes: 4 additions & 8 deletions scaling.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,6 @@ const (
cpuProbeTime = 120 * time.Millisecond
// do not scale over this amount of CPU usage
maxCpuUsageForScaling = 0.8
// upscale stalled threads every x milliseconds
upscaleCheckTime = 100 * time.Millisecond
// downscale idle threads every x seconds
downScaleCheckTime = 5 * time.Second
// max amount of threads stopped in one iteration of downScaleCheckTime
Expand All @@ -31,13 +29,11 @@ const (
)

var (
ErrMaxThreadsReached = errors.New("max amount of overall threads reached")

scaleChan chan *frankenPHPContext
autoScaledThreads = []*phpThread{}
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) {
Expand Down Expand Up @@ -67,7 +63,7 @@ func drainAutoScaling() {
func addRegularThread() (*phpThread, error) {
thread := getInactivePHPThread()
if thread == nil {
return nil, MaxThreadsReachedError
return nil, ErrMaxThreadsReached
}
convertToRegularThread(thread)
thread.state.waitFor(stateReady, stateShuttingDown, stateReserved)
Expand All @@ -77,7 +73,7 @@ func addRegularThread() (*phpThread, error) {
func addWorkerThread(worker *worker) (*phpThread, error) {
thread := getInactivePHPThread()
if thread == nil {
return nil, MaxThreadsReachedError
return nil, ErrMaxThreadsReached
}
convertToWorkerThread(thread, worker)
thread.state.waitFor(stateReady, stateShuttingDown, stateReserved)
Expand Down
2 changes: 1 addition & 1 deletion threadinactive.go
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ func (handler *inactiveThread) beforeScriptExecution() string {
panic("unexpected state: " + thread.state.name())
}

func (handler *inactiveThread) afterScriptExecution(exitStatus int) {
func (handler *inactiveThread) afterScriptExecution(int) {
panic("inactive threads should not execute scripts")
}

Expand Down
2 changes: 1 addition & 1 deletion threadregular.go
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ func (handler *regularThread) beforeScriptExecution() string {
}

// return true if the worker should continue to run
func (handler *regularThread) afterScriptExecution(exitStatus int) {
func (handler *regularThread) afterScriptExecution(int) {
handler.afterRequest()
}

Expand Down
4 changes: 3 additions & 1 deletion worker_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package frankenphp_test

import (
"fmt"
"github.com/stretchr/testify/require"
"io"
"log"
"net/http"
Expand Down Expand Up @@ -139,7 +140,8 @@ func ExampleServeHTTP_workers() {
}

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) {
req := httptest.NewRequest("GET", "http://example.com/worker.php", nil)
w := httptest.NewRecorder()
Expand Down
Loading