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

Add mochiweb_request:is_closed/1 function #258

Merged
merged 1 commit into from
Aug 31, 2023

Conversation

nickva
Copy link
Collaborator

@nickva nickva commented Aug 31, 2023

This function can used during long running request callbacks to detect if the client connection is closed.

If the request callback periodically streams data back to the client, the act of writting to the client socket will detect if it is closed or not. However, in cases when no data is sent back, and the client times-out and closes the connection, it may be useful to be able to find out early and stop processing the request on the server.

It turns out there is no easy way to detect if a passive mode socket is closed in Erlang/OTP [1]. Neither one of inet:monitor/1, inet:info/1, inet:getstat/1 work. However, it is possible to do it by querying the TCP state info of the socket. That option available in Linux since kernel 2.4 and on other Unix-like OSes (NetBSD, OpenBSD, FreeBSD and MacOS). Windows also has a tcp info query method however it is not reacheable via the gensockopts(2) standard socket API, so it can't be queried from Erlang's inet:getopts/2 API.

[1] Using the newer socket module it's possible to detect if a socket is closed by attempting a recv with a MSG_PEEK option. However, the regular gen_tcp OTP module doesn't have a recv() variant which takes extra options. In addition, the new socket implementation still feels rather experimental. (It's not the default even in the latest OTP 26 release).

@nickva nickva requested a review from etrepum August 31, 2023 16:52
@nickva nickva force-pushed the add-request-is-closed-function branch 2 times, most recently from 53b6017 to 7d2a79d Compare August 31, 2023 16:58
This function can used during long running request callbacks to detect if the
client connection is closed.

If the request callback periodically streams data back to the client, the act
of writting to the client socket will detect if it is closed or not. However,
in cases when no data is sent back, and the client times-out and closes the
connection, it may be useful to be able to find out early and stop processing
the request on the server.

It turns out there is no easy way to detect if a passive mode socket is closed
in Erlang/OTP [1]. Neither one of inet:monitor/1, inet:info/1, inet:getstat/1
work. However, it is possible to do it by querying the TCP state info of the
socket. That option available in Linux since kernel 2.4 and on other Unix-like
OSes (NetBSD, OpenBSD, FreeBSD and MacOS). Windows also has a tcp info query
method however it is not reacheable via the gensockopts(2) standard socket API,
so it can't be queried from Erlang's inet:getopts/2 API.

[1] Using the newer socket module it's possible to detect if a socket is closed
by attempting a recv with a MSG_PEEK option. However, the regular gen_tcp OTP
module doesn't have a recv() variant which takes extra options. In addition,
the new socket implementation still feels rather experimental. (It's not the
default even in the latest OTP 26 release).
@nickva nickva force-pushed the add-request-is-closed-function branch from 7d2a79d to 8b2d844 Compare August 31, 2023 17:01
Copy link
Member

@etrepum etrepum left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks great, thank you!

@etrepum etrepum merged commit af661f1 into mochi:main Aug 31, 2023
8 checks passed
@nickva nickva deleted the add-request-is-closed-function branch August 31, 2023 17:23
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

Successfully merging this pull request may close these issues.

2 participants