popa.bogdanp
2020-9-30 09:48:00

You can create the thread under a different custodian, where the custodian itself is created outside of the request-handling thread (eg. the top level of a module).


popa.bogdanp
2020-9-30 09:57:42

It doesn’t look like threads created in a handler inherit the request-handling thread’s custodian, though, so you might be running into some other issue. This code behaves as expected:

#lang racket/base (require web-server/http web-server/servlet-dispatch web-server/web-server) (serve #:port 9999 #:dispatch (dispatch/servlet (lambda (_req) (thread (lambda () (let loop () (displayln "hello from thread") (sleep 1) (loop)))) (response/xexpr '(h1 "Hello"))))) i.e. it prints the message even after the request completes.


badkins
2020-9-30 13:13:17

That’s interesting. I had created a thread for sending a notification email, and the email wasn’t sent until I added a (sleep 3) in the main request thread, so I assumed the issue was the premature termination of my notification thread.


badkins
2020-9-30 13:18:23

@popa.bogdanp how do you create a thread with a custodian other than the current custodian?


badkins
2020-9-30 13:32:58

Here’s my main function for context: (define (axio-app-init environment route get-user) (let* ([ instance-id (string->number (vector-ref (current-command-line-arguments) 0)) ] [ env (get-app-env environment) ] [ port (+ (app-env-port-base env) instance-id) ] [ axio-context (axio-init environment) ]) (void (serve #:dispatch (seq:make (log:make #:format log:extended-format #:log-path (format "~a.log" (symbol->string environment))) (lift:make (λ (request) (front-controller axio-context request route get-user)))) #:port port)) (do-not-return)))


popa.bogdanp
2020-9-30 13:44:40

You can create a new custodian at the top level, then parameterize current-custodian around the extent of thread. Something like:

(define task-custodian (make-custodian)) (define (axio-app-init ...) ...) (define (front-controller ...) (parameterize ([current-custodian task-custodian]) (thread (lambda () ...))) ...)


badkins
2020-9-30 13:47:16

I ran your example, and it just returned a procedure - did you extract it out of a more complete example?


badkins
2020-9-30 13:48:01

Thanks for the custodian example - I’ll experiment with that.


badkins
2020-9-30 13:55:35

@popa.bogdanp the parameterization of current-custodian worked perfectly!


badkins
2020-9-30 13:56:28

There must be something different in how I’m using serve that causes spawned threads to be terminated when the request ends, but using a separate custodian is fine.