Skip to content

Commit

Permalink
Watchdog now forces all agents' process groups to exit using SIGKILL,…
Browse files Browse the repository at this point in the history
… to ensure no garbage processes are left behind.
  • Loading branch information
FooBarWidget committed Sep 19, 2012
1 parent 016e327 commit d953241
Show file tree
Hide file tree
Showing 5 changed files with 25 additions and 8 deletions.
1 change: 1 addition & 0 deletions NEWS
Expand Up @@ -14,6 +14,7 @@ Release 3.9.0
* [Standalone] Automatic asset pipeline expiry headers support.
* [Enterprise] Multithreading support for apps
* Deleting restart.txt will no longer trigger a restart.
* The watchdog now forces all agents' process groups to exit using SIGKILL, to ensure no garbage processes are left behind.


Release 3.0.17
Expand Down
5 changes: 3 additions & 2 deletions ext/common/agents/HelperAgent/Main.cpp
Expand Up @@ -446,6 +446,7 @@ class Server {
* instance directory will be cleaned up, making this helper agent
* inaccessible.
*/
P_DEBUG("Watchdog seems to be killed; forcing shutdown of all subprocesses");
syscalls::killpg(getpgrp(), SIGKILL);
_exit(2); // In case killpg() fails.
} else {
Expand Down Expand Up @@ -486,11 +487,11 @@ main(int argc, char *argv[]) {
UPDATE_TRACE_POINT();
server.mainLoop();
} catch (const tracable_exception &e) {
P_ERROR(e.what() << "\n" << e.backtrace());
P_ERROR("*** ERROR: " << e.what() << "\n" << e.backtrace());
return 1;
}

MultiLibeio::shutdown();
P_TRACE(2, "Helper agent exited.");
P_TRACE(2, "Helper agent exiting with code 0.");
return 0;
}
1 change: 1 addition & 0 deletions ext/common/agents/LoggingAgent/Main.cpp
Expand Up @@ -283,6 +283,7 @@ main(int argc, char *argv[]) {

P_DEBUG("Logging agent online, listening at " << socketAddress);
ev_run(eventLoop, 0);
P_DEBUG("Logging agent exiting with code " << exitCode << ".");
return exitCode;
} catch (const tracable_exception &e) {
P_ERROR("*** ERROR: " << e.what() << "\n" << e.backtrace());
Expand Down
13 changes: 7 additions & 6 deletions ext/common/agents/Watchdog/Main.cpp
@@ -1,6 +1,6 @@
/*
* Phusion Passenger - http://www.modrails.com/
* Copyright (c) 2010 Phusion
* Copyright (c) 2010-2012 Phusion
*
* "Phusion Passenger" is a trademark of Hongli Lai & Ninh Bui.
*
Expand Down Expand Up @@ -982,12 +982,12 @@ cleanupAgentsInBackground(vector<AgentWatcher *> &watchers) {
// processes.
P_WARN("Some Phusion Passenger agent processes did not exit " <<
"in time, forcefully shutting down all.");
for (it = watchers.begin(); it != watchers.end(); it++) {
(*it)->forceShutdown();
}
} else {
P_DEBUG("All Phusion Passenger agent processes have exited.");
P_DEBUG("All Phusion Passenger agent processes have exited. Forcing all subprocesses to shut down.");
}
for (it = watchers.begin(); it != watchers.end(); it++) {
(*it)->forceShutdown();
}

// Now clean up the server instance directory.
delete generation.get();
Expand Down Expand Up @@ -1126,10 +1126,11 @@ main(int argc, char *argv[]) {
* the background and exit this watchdog process so that we don't block
* the web server.
*/
P_DEBUG("Web server exited gracefully; gracefully shutting down all agents...");
cleanupAgentsInBackground(watchers);
return 0;
} else {
P_DEBUG("Web server did not exit gracefully, forcing shutdown of all service processes...");
P_DEBUG("Web server did not exit gracefully, forcing shutdown of all agents...");
forceAllAgentsShutdown(watchers);
return 1;
}
Expand Down
13 changes: 13 additions & 0 deletions ext/ruby/passenger_native_support.c
Expand Up @@ -458,6 +458,18 @@ detach_process(VALUE self, VALUE pid) {
return Qnil;
}

/**
* Freeze the current process forever. On Ruby 1.9 this never unlocks the GIL.
* Useful for testing purposes.
*/
static VALUE
freeze_process(VALUE self) {
while (1) {
usleep(60 * 1000000);
}
return Qnil;
}

#if defined(HAVE_KQUEUE) || defined(IN_DOXYGEN)
typedef struct {
VALUE klass;
Expand Down Expand Up @@ -852,6 +864,7 @@ Init_passenger_native_support() {
rb_define_singleton_method(mNativeSupport, "writev3", f_writev3, 4);
rb_define_singleton_method(mNativeSupport, "process_times", process_times, 0);
rb_define_singleton_method(mNativeSupport, "detach_process", detach_process, 1);
rb_define_singleton_method(mNativeSupport, "freeze_process", freeze_process, 0);

#ifdef HAVE_KQUEUE
cFileSystemWatcher = rb_define_class_under(mNativeSupport,
Expand Down

0 comments on commit d953241

Please sign in to comment.