Skip to content

[native] Enable reuse_addr for reliable development restarts #21

Description

@yorkin-bot

Summary

The native listener constructs @http.Server(addr) without passing reuse_addr:

Mocket 0.8.0 pins moonbitlang/async@0.21.0. In that version:

Therefore Mocket does not enable SO_REUSEADDR on POSIX listeners. During rapid development restarts, sockets left in TIME_WAIT can make the new process report that the port is still occupied even after the previous listener has exited.

Observed behavior

After sending traffic, stopping the previous process, and immediately starting the native Mocket server on the same 127.0.0.1:49400 address:

mocket: failed to listen on 127.0.0.1:49400:
OSError("@socket.TcpServer::new(): Address already in use")

lsof showed no process listening on that port. A second immediate attempt produced the same error. Because listen_ffi catches the bind error and returns, the process also exits successfully instead of reporting failure to its caller.

This is OS-, address-, and timing-dependent: a native-to-native control restart succeeded in one macOS run. That does not change the configuration issue; the async socket documentation describes TIME_WAIT rebinding as the purpose of reuse_addr.

Expected behavior

Enable address reuse by default in Mocket's native listener by passing reuse_addr=true when constructing the HTTP server:

let server = @http.Server(addr, reuse_addr=true)

This should be the primary fix so existing applications get reliable rapid restarts without additional configuration. If Mocket also wants to expose this setting publicly, it should be an opt-out whose default remains true, rather than an option that leaves the current false behavior unchanged.

Document the BSD/macOS wildcard/specific-address caveat described by moonbitlang/async. Bind failures should also propagate as checked errors rather than being printed and converted to a successful return, so supervisors and development tools can react correctly.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions