# How can I properly thread serve/servlet?

**URL:** <https://racket.discourse.group/t/how-can-i-properly-thread-serve-servlet/3326>\
**Category:** Questions & Answers\
**Tags:** repl, web-server, thread\
**Created:** [November 15, 2024, 3:56pm UTC](https://racket.discourse.group/t/how-can-i-properly-thread-serve-servlet/3326 "2024-11-15T15:56:02Z")\
**Posts on this page:** 6\
**Page:** 1

<div class="post-metadata">

**Author:** ![mfru](https://yyz2.discourse-cdn.com/free1/user_avatar/racket.discourse.group/mfru/32/2040_2.png) [@mfru](https://racket.discourse.group/u/mfru)\
**Post date:** [November 15, 2024, 3:56pm UTC](https://racket.discourse.group/t/how-can-i-properly-thread-serve-servlet/3326/1 "2024-11-15T15:56:02Z")

</div>

Hi,

I am working on a Racket web server. Having used Clojure in the past, I quite like being able to have convenience procedures for working within my code.

Particularly, I want to implement a `(start-server!)` and a `(stop-server!)` procedure that enable me to start / stop the web-server within the current REPL.

My approach so far looks like this:

```scheme
#lang/racket 

;; (...)

(define servlet-thread #f)

(define (start-server!)
  (unless servlet-thread
    (set! servlet-thread (thread (thunk (serve/servlet app-dispatch
                                                       #:launch-browser? #f
                                                       #:port 8080
                                                       #:server-root-path (build-path (current-directory))
                                                       #:servlet-path "/"
                                                       #:listen-ip #f
                                                       #:log-file (build-path "app.log")
                                                       #:extra-files-paths (list "htdocs")))))))

(define (stop-server!) 
 (kill-thread servlet-thread)
 ;; (set! servlet-thread #f)
)

```

Starting the server works fine and I can continue using the REPL, but when running `(stop-server!)` nothing really happens.

The thread is dead according to `(thread-dead?)`, but I can still reach and interact with my server when browsing to `localhost:8080`.

Why is that? I expected the thread to be actually dead and not executing code anymore.

---

<div class="post-metadata">

**Author:** ![jbclements](https://yyz2.discourse-cdn.com/free1/user_avatar/racket.discourse.group/jbclements/32/11_2.png) [@jbclements](https://racket.discourse.group/u/jbclements)\
**Post date:** [November 15, 2024, 4:51pm UTC](https://racket.discourse.group/t/how-can-i-properly-thread-serve-servlet/3326/2 "2024-11-15T16:51:01Z")

</div>

Check me on this: when you run `serve/servlet` without the thread wrapper, it returns immediately after starting the server, right? Assuming so: the thread you started will die as soon as the call to `serve/servlet` returns. You can probably also check this by calling `thread-dead?` _before_ you call `stop-server!`. I believe you will find that the thread dies immediately when the server starts up.

In order to get the behavior you want, I suspect you will either need to

- find a function in the web-server interface that lets you inspect and halt running server instances, or
- start the server with a lower-level blocking call that does not immediately return, but actually runs the (main?) web server thread on the current thread.

There are other heavier-handed approaches, e.g. custodians or literally running another process using `process` or `system` or similar.

... But I bet there's a way to do this using only web server functions.

John

---

<div class="post-metadata">

**Author:** ![mfru](https://yyz2.discourse-cdn.com/free1/user_avatar/racket.discourse.group/mfru/32/2040_2.png) [@mfru](https://racket.discourse.group/u/mfru)\
**Post date:** [November 15, 2024, 5:02pm UTC](https://racket.discourse.group/t/how-can-i-properly-thread-serve-servlet/3326/3 "2024-11-15T17:02:37Z")

</div>

When I run `start-server!` and then check `(thread-dead? servlet-thread)` I get `#f`.

Furthermore, when just running `serve/servlet` the procedure blocks and the server is listening to incoming requests:

```plaintext
Your Web application is running at http://localhost:8080.
Stop this program at any time to terminate the Web Server.

```

Indeed I then cannot run further procedures in the same REPL (unlike with `start-server!`) until I CTRL-C.

I'll try to have a look if I can find other functions in the web-server interface that might suit my needs more, thanks.

---

<div class="post-metadata">

**Author:** ![bogdan](https://yyz2.discourse-cdn.com/free1/user_avatar/racket.discourse.group/bogdan/32/8_2.png) [@bogdan](https://racket.discourse.group/u/bogdan)\
**Post date:** [November 15, 2024, 5:06pm UTC](https://racket.discourse.group/t/how-can-i-properly-thread-serve-servlet/3326/4 "2024-11-15T17:06:56Z")

</div>

You want one of the procedures listed here: [3&nbsp;Launching Servers](https://docs.racket-lang.org/web-server-internal/web-server.html) . My preference is to always use `serve`, which returns a procedure that can be used to stop the server. [This post](https://defn.io/2020/02/12/racket-web-server-guide/) might also be helpful.

Also, generally, `kill-thread` should be avoided unless you know (i.e. the documentation mentions) that the data structures used by the thread you're killing are kill-safe.

---

<div class="post-metadata">

**Author:** ![mfru](https://yyz2.discourse-cdn.com/free1/user_avatar/racket.discourse.group/mfru/32/2040_2.png) [@mfru](https://racket.discourse.group/u/mfru)\
**Post date:** [November 15, 2024, 5:41pm UTC](https://racket.discourse.group/t/how-can-i-properly-thread-serve-servlet/3326/5 "2024-11-15T17:41:27Z")

</div>

This seems to be the way to go, experimenting right now with `serve`.

I will post my working result and resolve the thread when finished, thank you.

---

<div class="post-metadata">

**Author:** ![mfru](https://yyz2.discourse-cdn.com/free1/user_avatar/racket.discourse.group/mfru/32/2040_2.png) [@mfru](https://racket.discourse.group/u/mfru)\
**Post date:** [November 16, 2024, 10:27pm UTC](https://racket.discourse.group/t/how-can-i-properly-thread-serve-servlet/3326/6 "2024-11-16T22:27:41Z")

</div>

I ended up with the following:

```scheme
;; (...)

(define servlet-thread #f)
(define server-semaphore (make-semaphore 0))

(define (start-server!)
  (unless servlet-thread
    (set! servlet-thread (thread (thunk (let ([stop (serve
                                                     #:dispatch (sequencer:make
                                                                 (dispatch/servlet app)
                                                                 (dispatch/servlet not-found))
                                                     #:listen-ip "127.0.0.1"
                                                     #:port 8080)])
                                          (semaphore-wait server-semaphore)
                                          (stop)))))))

(define (stop-server!)
  (unless (thread-dead? servlet-thread)
    (semaphore-post server-semaphore)))

```

Works for me 🙂
