Skip to content

Commit c42d287

Browse files
authored
refactor: extension worker (#1910)
* refactor: extension worker * feat: optional HTTP request * allow passing unsafe.Pointer to the extension callback * lint * simplify
1 parent 1f6f768 commit c42d287

9 files changed

Lines changed: 232 additions & 195 deletions

File tree

cgi.go

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -214,8 +214,10 @@ func go_register_variables(threadIndex C.uintptr_t, trackVarsArray *C.zval) {
214214
thread := phpThreads[threadIndex]
215215
fc := thread.getRequestContext()
216216

217-
addKnownVariablesToServer(thread, fc, trackVarsArray)
218-
addHeadersToServer(fc, trackVarsArray)
217+
if fc.request != nil {
218+
addKnownVariablesToServer(thread, fc, trackVarsArray)
219+
addHeadersToServer(fc, trackVarsArray)
220+
}
219221

220222
// The Prepared Environment is registered last and can overwrite any previous values
221223
addPreparedEnvToServer(fc, trackVarsArray)
@@ -280,6 +282,10 @@ func go_update_request_info(threadIndex C.uintptr_t, info *C.sapi_request_info)
280282
fc := thread.getRequestContext()
281283
request := fc.request
282284

285+
if request == nil {
286+
return C.bool(fc.worker != nil)
287+
}
288+
283289
authUser, authPassword, ok := request.BasicAuth()
284290
if ok {
285291
if authPassword != "" {

context.go

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -42,13 +42,18 @@ func fromContext(ctx context.Context) (fctx *frankenPHPContext, ok bool) {
4242
return
4343
}
4444

45-
// NewRequestWithContext creates a new FrankenPHP request context.
46-
func NewRequestWithContext(r *http.Request, opts ...RequestOption) (*http.Request, error) {
47-
fc := &frankenPHPContext{
45+
func newFrankenPHPContext() *frankenPHPContext {
46+
return &frankenPHPContext{
4847
done: make(chan any),
4948
startedAt: time.Now(),
50-
request: r,
5149
}
50+
}
51+
52+
// NewRequestWithContext creates a new FrankenPHP request context.
53+
func NewRequestWithContext(r *http.Request, opts ...RequestOption) (*http.Request, error) {
54+
fc := newFrankenPHPContext()
55+
fc.request = r
56+
5257
for _, o := range opts {
5358
if err := o(fc); err != nil {
5459
return nil, err
@@ -132,6 +137,10 @@ func (fc *frankenPHPContext) validate() bool {
132137
}
133138

134139
func (fc *frankenPHPContext) clientHasClosed() bool {
140+
if fc.request == nil {
141+
return false
142+
}
143+
135144
select {
136145
case <-fc.request.Context().Done():
137146
return true

frankenphp.go

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -215,7 +215,7 @@ func Init(options ...Option) error {
215215
registerExtensions()
216216

217217
// add registered external workers
218-
for _, ew := range externalWorkers {
218+
for _, ew := range extensionWorkers {
219219
options = append(options, WithWorkers(ew.Name(), ew.FileName(), ew.GetMinThreads(), WithWorkerEnv(ew.Env())))
220220
}
221221

@@ -527,8 +527,12 @@ func go_read_post(threadIndex C.uintptr_t, cBuf *C.char, countBytes C.size_t) (r
527527

528528
//export go_read_cookies
529529
func go_read_cookies(threadIndex C.uintptr_t) *C.char {
530-
cookies := phpThreads[threadIndex].getRequestContext().request.Header.Values("Cookie")
531-
cookie := strings.Join(cookies, "; ")
530+
request := phpThreads[threadIndex].getRequestContext().request
531+
if request == nil {
532+
return nil
533+
}
534+
535+
cookie := strings.Join(request.Header.Values("Cookie"), "; ")
532536
if cookie == "" {
533537
return nil
534538
}

threadFramework.go

Lines changed: 0 additions & 145 deletions
This file was deleted.

threadworker.go

Lines changed: 23 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -20,12 +20,12 @@ type workerThread struct {
2020
dummyContext *frankenPHPContext
2121
workerContext *frankenPHPContext
2222
backoff *exponentialBackoff
23-
externalWorker WorkerExtension
23+
externalWorker Worker
2424
isBootingScript bool // true if the worker has not reached frankenphp_handle_request yet
2525
}
2626

2727
func convertToWorkerThread(thread *phpThread, worker *worker) {
28-
externalWorker := externalWorkers[worker.name]
28+
externalWorker := extensionWorkers[worker.name]
2929

3030
thread.setHandler(&workerThread{
3131
state: thread.state,
@@ -204,7 +204,11 @@ func (handler *workerThread) waitForWorkerRequest() (bool, any) {
204204
handler.workerContext = fc
205205
handler.state.markAsWaiting(false)
206206

207-
logger.LogAttrs(ctx, slog.LevelDebug, "request handling started", slog.String("worker", handler.worker.name), slog.Int("thread", handler.thread.threadIndex), slog.String("url", fc.request.RequestURI))
207+
if fc.request == nil {
208+
logger.LogAttrs(ctx, slog.LevelDebug, "request handling started", slog.String("worker", handler.worker.name), slog.Int("thread", handler.thread.threadIndex))
209+
} else {
210+
logger.LogAttrs(ctx, slog.LevelDebug, "request handling started", slog.String("worker", handler.worker.name), slog.Int("thread", handler.thread.threadIndex), slog.String("url", fc.request.RequestURI))
211+
}
208212

209213
return true, fc.handlerParameters
210214
}
@@ -217,10 +221,18 @@ func go_frankenphp_worker_handle_request_start(threadIndex C.uintptr_t) (C.bool,
217221
hasRequest, parameters := handler.waitForWorkerRequest()
218222

219223
if parameters != nil {
220-
p := PHPValue(parameters)
221-
handler.thread.Pin(p)
224+
var ptr unsafe.Pointer
225+
226+
switch p := parameters.(type) {
227+
case unsafe.Pointer:
228+
ptr = p
222229

223-
return C.bool(hasRequest), p
230+
default:
231+
ptr = PHPValue(ptr)
232+
}
233+
handler.thread.Pin(ptr)
234+
235+
return C.bool(hasRequest), ptr
224236
}
225237

226238
return C.bool(hasRequest), nil
@@ -239,7 +251,11 @@ func go_frankenphp_finish_worker_request(threadIndex C.uintptr_t, retval *C.zval
239251
fc.closeContext()
240252
thread.handler.(*workerThread).workerContext = nil
241253

242-
fc.logger.LogAttrs(context.Background(), slog.LevelDebug, "request handling finished", slog.String("worker", fc.scriptFilename), slog.Int("thread", thread.threadIndex), slog.String("url", fc.request.RequestURI))
254+
if fc.request == nil {
255+
fc.logger.LogAttrs(context.Background(), slog.LevelDebug, "request handling finished", slog.String("worker", fc.scriptFilename), slog.Int("thread", thread.threadIndex))
256+
} else {
257+
fc.logger.LogAttrs(context.Background(), slog.LevelDebug, "request handling finished", slog.String("worker", fc.scriptFilename), slog.Int("thread", thread.threadIndex), slog.String("url", fc.request.RequestURI))
258+
}
243259
}
244260

245261
// when frankenphp_finish_request() is directly called from PHP

types.go

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ package frankenphp
55
*/
66
import "C"
77
import (
8+
"fmt"
89
"strconv"
910
"unsafe"
1011
)
@@ -284,7 +285,7 @@ func phpValue(value any) *C.zval {
284285
case []any:
285286
return (*C.zval)(PHPPackedArray(v))
286287
default:
287-
C.__zval_null__(&zval)
288+
panic(fmt.Sprintf("unsupported Go type %T", v))
288289
}
289290

290291
return &zval

worker.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,7 @@ func initWorkers(opt []workerOpt) error {
5555
// create a pipe from the external worker to the main worker
5656
// note: this is locked to the initial thread size the external worker requested
5757
if workerThread, ok := thread.handler.(*workerThread); ok && workerThread.externalWorker != nil {
58-
go startExternalWorkerPipe(w, workerThread.externalWorker, thread)
58+
go startWorker(w, workerThread.externalWorker, thread)
5959
}
6060
workersReady.Done()
6161
}()

0 commit comments

Comments
 (0)