If I have an active TcpConnection, SIGINT and SIGTERM do not quit the program -- until the connection terminates (even though SIGINT / ctrl-C returns control to the shell, making it seem like it has terminated). In my case, I have an infinite TCP stream, so I would like to be able to interrupt the TCP download and gracefully terminate the program. Is there a better way to accomplish this shutdown than just SIGKILLing the program?
On Tue, 16 Sep 2014 02:30:03 GMT, Luís Marques wrote:
If I have an active TcpConnection, SIGINT and SIGTERM do not quit the program -- until the connection terminates (even though SIGINT / ctrl-C returns control to the shell, making it seem like it has terminated). In my case, I have an infinite TCP stream, so I would like to be able to interrupt the TCP download and gracefully terminate the program. Is there a better way to accomplish this shutdown than just SIGKILLing the program?
This only seems to happen in a module constructor, not on a runTask task.
Am 18.09.2014 16:30, schrieb Luís Marques:
On Tue, 16 Sep 2014 02:30:03 GMT, Luís Marques wrote:
If I have an active TcpConnection, SIGINT and SIGTERM do not quit the program -- until the connection terminates (even though SIGINT / ctrl-C returns control to the shell, making it seem like it has terminated). In my case, I have an infinite TCP stream, so I would like to be able to interrupt the TCP download and gracefully terminate the program. Is there a better way to accomplish this shutdown than just SIGKILLing the program?
This only seems to happen in a module constructor, not on a runTask task.
Ah okay, that's because Ctrl+C basically triggers a call to exitEventLoop
, but while the module constructors are still run, there
is no event loop running, yet - only a temporary implicit event loop for
each blocking operation.
The question is what would be the best thing to do. Throw an InterruptException
or simply call exit(-2)
- or anything else?
On Thu, 18 Sep 2014 18:08:55 +0200, Sönke Ludwig wrote:
Ah okay, that's because Ctrl+C basically triggers a call to
exitEventLoop
, but while the module constructors are still run, there
is no event loop running, yet - only a temporary implicit event loop for
each blocking operation.The question is what would be the best thing to do. Throw an
InterruptException
or simply callexit(-2)
- or anything else?
How does exitEventLoop
implement the interruption of the normal event loop? (outside the module ctors)
Am 21.09.2014 17:02, schrieb Luís Marques:
On Thu, 18 Sep 2014 18:08:55 +0200, Sönke Ludwig wrote:
Ah okay, that's because Ctrl+C basically triggers a call to
exitEventLoop
, but while the module constructors are still run, there
is no event loop running, yet - only a temporary implicit event loop for
each blocking operation.The question is what would be the best thing to do. Throw an
InterruptException
or simply callexit(-2)
- or anything else?How does
exitEventLoop
implement the interruption of the normal event loop? (outside the module ctors)
It uses the event loop implementation specific mechanism - for libevent
that is event_base_loopbreak
and for Win32 it's a WM_QUIT
message.
On Sun, 21 Sep 2014 18:17:04 +0200, Sönke Ludwig wrote:
It uses the event loop implementation specific mechanism - for libevent
that isevent_base_loopbreak
and for Win32 it's aWM_QUIT
message.
What I don't exactly understand is why can't we also use that mechanism for the "temporary implicit event loop for each blocking operation"?
Is it because vibed does not have a reference to those event loops?
Is it because if we quit one temporary event loop we would just continue to the next one, once we reach the next blocking operation in the module ctor?
Am 21.09.2014 19:29, schrieb Luís Marques:
On Sun, 21 Sep 2014 18:17:04 +0200, Sönke Ludwig wrote:
It uses the event loop implementation specific mechanism - for libevent
that isevent_base_loopbreak
and for Win32 it's aWM_QUIT
message.What I don't exactly understand is why can't we also use that mechanism for the "temporary implicit event loop for each blocking operation"?
Is it because vibed does not have a reference to those event loops?
Is it because if we quit one temporary event loop we would just continue to the next one, once we reach the next blocking operation in the module ctor?
More the latter, and even on a lower level. For example a socket read is
usually implemented similar to this:
while (bytes_read < bytes_to_read) {
if (!try_to_read_some_bytes(&bytes_read))
wait_for_socket_to_become_ready();
}
Now in the non-event-loop case, the wait function would simply run such
a temporary loop (instead if yield()
ing). But when this loop gets
terminated, it would simply go to the next while
loop iteration and
would wait again. So in the end wait
would have to throw an
exception to not cause strange effects within the normal program flow.
On Mon, 22 Sep 2014 08:31:46 +0200, Sönke Ludwig wrote:
Is it because if we quit one temporary event loop we would just continue to the next one, once we reach the next blocking operation in the module ctor?
More the latter, and even on a lower level. For example a socket read is
usually implemented similar to this:while (bytes_read < bytes_to_read) { if (!try_to_read_some_bytes(&bytes_read)) wait_for_socket_to_become_ready(); }
Now in the non-event-loop case, the wait function would simply run such
a temporary loop (instead ifyield()
ing). But when this loop gets
terminated, it would simply go to the nextwhile
loop iteration and
would wait again. So in the endwait
would have to throw an
exception to not cause strange effects within the normal program flow.
Yes, that's exactly what I meant. Hmm, I'll have to think about this.
BTW, I have noticed that an exception is thrown when you run a vibed app like ./app | tee file.txt and then Ctrl-C. vibed complains about a broken log file descriptor or something. But this does not happen when the logging output is being (re)directed to the console or to a file. Hmmm.
BTW 2: If I try to reply after being automatically logged out, the reply failing (because without being logged in the email field is not filled-in), and then try to log in, it HTTP 500s. Hadn't we discussed and solved this before?
object.Exception@../vibe/source/vibe/utils/dictionarylist.d(154): Accessing non-existent key 'group'.
----------------
./vibenews(pure @safe bool std.exception.enforce!(bool).enforce(bool, lazy const(char)[], immutable(char)[], ulong)+0x6b) [0x7d6fef]
./vibenews(vibe.utils.dictionarylist.DictionaryList!(immutable(char)[], true, 16).DictionaryList.opIndexinout(pure @safe inout(immutable(char)[]) function(immutable(char)[]))+0xa7) [0x960b2f]
./vibenews(void vibenews.web.WebInterface.showPostArticle(vibe.http.server.HTTPServerRequest, vibe.http.server.HTTPServerResponse)+0xfb) [0x8e577f]
./vibenews(void vibe.http.router.URLRouter.handleRequest(vibe.http.server.HTTPServerRequest, vibe.http.server.HTTPServerResponse).void __lambda3!(ulong, immutable(char)[][]).__lambda3(ulong, scope immutable(char)[][])+0x1dc) [0x94e888]
./vibenews(void vibe.http.router.MatchTree!(vibe.http.router.Route).MatchTree.match(immutable(char)[], scope void delegate(ulong, scope immutable(char)[][]))+0x1dc) [0x94eec8]
On Tue, 23 Sep 2014 09:42:18 GMT, Luís Marques wrote:
BTW, I have noticed that an exception is thrown when you run a vibed app like ./app | tee file.txt and then Ctrl-C. vibed complains about a broken log file descriptor or something. But this does not happen when the logging output is being (re)directed to the console or to a file. Hmmm.
Could this be because Ctrl-C first terminates the tee command and thus breaks the stdout pipe?
BTW 2: If I try to reply after being automatically logged out, the reply failing (because without being logged in the email field is not filled-in), and then try to log in, it HTTP 500s. Hadn't we discussed and solved this before?
object.Exception@../vibe/source/vibe/utils/dictionarylist.d(154): Accessing non-existent key 'group'. ---------------- ./vibenews(pure @safe bool std.exception.enforce!(bool).enforce(bool, lazy const(char)[], immutable(char)[], ulong)+0x6b) [0x7d6fef] ./vibenews(vibe.utils.dictionarylist.DictionaryList!(immutable(char)[], true, 16).DictionaryList.opIndexinout(pure @safe inout(immutable(char)[]) function(immutable(char)[]))+0xa7) [0x960b2f] ./vibenews(void vibenews.web.WebInterface.showPostArticle(vibe.http.server.HTTPServerRequest, vibe.http.server.HTTPServerResponse)+0xfb) [0x8e577f] ./vibenews(void vibe.http.router.URLRouter.handleRequest(vibe.http.server.HTTPServerRequest, vibe.http.server.HTTPServerResponse).void __lambda3!(ulong, immutable(char)[][]).__lambda3(ulong, scope immutable(char)[][])+0x1dc) [0x94e888] ./vibenews(void vibe.http.router.MatchTree!(vibe.http.router.Route).MatchTree.match(immutable(char)[], scope void delegate(ulong, scope immutable(char)[][]))+0x1dc) [0x94eec8]
It sounds familiar, maybe it was under slightly different circumstances? I've added a ticket: #25