Skip to content

Commit b02d99a

Browse files
feat: always ignore user abort (#2189)
Automatically sets `ignore_user_abort` to true in worker mode as mentioned in #2186, removing the requirement to change it via ini. Would also be possible to expose something like an explicit `frankenphp_client_has_closed()` function for in-between critical sections. --------- Co-authored-by: Marc <m@pyc.ac>
1 parent 7c563d2 commit b02d99a

File tree

3 files changed

+23
-3
lines changed

3 files changed

+23
-3
lines changed

docs/worker.md

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -72,9 +72,6 @@ The following example shows how to create your own worker script without relying
7272
<?php
7373
// public/index.php
7474

75-
// Prevent worker script termination when a client connection is interrupted
76-
ignore_user_abort(true);
77-
7875
// Boot your app
7976
require __DIR__.'/vendor/autoload.php';
8077

frankenphp.c

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,8 @@ frankenphp_config frankenphp_get_config() {
7171
}
7272

7373
bool should_filter_var = 0;
74+
bool original_user_abort_setting = 0;
75+
7476
__thread uintptr_t thread_index;
7577
__thread bool is_worker_thread = false;
7678
__thread zval *os_environment = NULL;
@@ -113,6 +115,9 @@ __thread session_user_handlers *worker_session_handlers_snapshot = NULL;
113115

114116
void frankenphp_update_local_thread_context(bool is_worker) {
115117
is_worker_thread = is_worker;
118+
119+
/* workers should keep running if the user aborts the connection */
120+
PG(ignore_user_abort) = is_worker ? 1 : original_user_abort_setting;
116121
}
117122

118123
static void frankenphp_update_request_context() {
@@ -1241,6 +1246,7 @@ static void *php_main(void *arg) {
12411246
char *default_filter;
12421247
cfg_get_string("filter.default", &default_filter);
12431248
should_filter_var = default_filter != NULL;
1249+
original_user_abort_setting = PG(ignore_user_abort);
12441250

12451251
go_frankenphp_main_thread_is_ready();
12461252

worker_test.go

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package frankenphp_test
22

33
import (
4+
"context"
45
"fmt"
56
"io"
67
"log"
@@ -157,3 +158,19 @@ func TestWorkerHasOSEnvironmentVariableInSERVER(t *testing.T) {
157158
assert.Contains(t, string(body), "custom_env_variable_value")
158159
}, &testOptions{workerScript: "worker.php", nbWorkers: 1, nbParallelRequests: 1})
159160
}
161+
162+
func TestKeepRunningOnConnectionAbort(t *testing.T) {
163+
runTest(t, func(handler func(http.ResponseWriter, *http.Request), _ *httptest.Server, i int) {
164+
req := httptest.NewRequest("GET", "http://example.com/worker-with-counter.php", nil)
165+
166+
ctx, cancel := context.WithCancel(req.Context())
167+
req = req.WithContext(ctx)
168+
cancel()
169+
body1, _ := testRequest(req, handler, t)
170+
171+
assert.Equal(t, "requests:1", body1, "should have handled exactly one request")
172+
body2, _ := testGet("http://example.com/worker-with-counter.php", handler, t)
173+
174+
assert.Equal(t, "requests:2", body2, "should not have stopped execution after the first request was aborted")
175+
}, &testOptions{workerScript: "worker-with-counter.php", nbWorkers: 1, nbParallelRequests: 1})
176+
}

0 commit comments

Comments
 (0)