RejectedSoftware Forums

Sign up

Shutdown

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?

Re: Shutdown

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.

Re: Shutdown

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?

Re: Shutdown

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 call exit(-2) - or anything else?

How does exitEventLoop implement the interruption of the normal event loop? (outside the module ctors)

Re: Shutdown

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 call exit(-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.

Re: Shutdown

On Sun, 21 Sep 2014 18:17:04 +0200, Sönke Ludwig wrote:

It uses the event loop implementation specific mechanism - for libevent
that is event_base_loopbreak and for Win32 it's a WM_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?

Re: Shutdown

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 is event_base_loopbreak and for Win32 it's a WM_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.

Re: Shutdown

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 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.

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]

Re: Shutdown

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