Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

WebSockets error trace when using PrecompileTools #1180

Open
attdona opened this issue May 27, 2024 · 0 comments
Open

WebSockets error trace when using PrecompileTools #1180

attdona opened this issue May 27, 2024 · 0 comments

Comments

@attdona
Copy link

attdona commented May 27, 2024

Versions:

  • Julia 1.10.3
  • HTTP.jl 1.10.8

I'm using HTTP and PrecompileTools for my package and I get:

[pid 860579] waiting for IO to finish:
 Handle type        uv_handle_t->data
 timer              0x297fc50->0x7ab870880e20
This means that a package has started a background task or event source that has not finished running. For precompilation to complete successfully, the event source needs to be closed explicitly. See the developer documentation on fixing precompilation hangs for more help.

The culprit is a timer defined here: https://github.com/JuliaWeb/HTTP.jl/blob/master/src/WebSockets.jl#L598

I think something like the following should work.
To get code simple, the if around the Timer expression got removed, because probably it is redundant, but I'm not 100% sure about that.

function Base.close(ws::WebSocket, body::CloseFrameBody=CloseFrameBody(1000, ""))
    isclosed(ws) && return
    @debugv 2 "$(ws.id): Closing websocket"
    ws.writeclosed = true
    data = Vector{UInt8}(body.message)
    prepend!(data, reinterpret(UInt8, [hton(UInt16(body.status))]))
    try
        writeframe(ws.io, Frame(true, CLOSE, ws.client, data))
    catch
        # ignore thrown errors here because we're closing anyway
    end
    # if we're initiating the close, wait until we receive the
    # responding close frame or timeout
    timer = Timer(5) do t
        ws.readclosed = true
        !ws.client && isopen(ws.io) && close(ws.io)
    end
    while !ws.readclosed
        try
            receive(ws)
        catch
            # ignore thrown errors here because we're closing anyway
            # but set readclosed so we don't keep trying to read
            ws.readclosed = true
        end
    end
    # we either recieved the responding CLOSE frame and readclosed was set
    # or there was an error/timeout reading it; in any case, readclosed should be closed now
    @assert ws.readclosed

    # close the timer
    close(timer)

    # if we're the server, it's our job to close the underlying socket
    !ws.client && isopen(ws.io) && close(ws.io)
    return
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant