Skip to content
This repository

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse code

Watchdog now forces all agents' process groups to exit using SIGKILL,…

… to ensure no garbage processes are left behind.
  • Loading branch information...
commit d9532417680a17dc9fc111b7acd4712de813cb15 1 parent 016e327
Hongli Lai authored September 19, 2012
1  NEWS
@@ -14,6 +14,7 @@ Release 3.9.0
14 14
  * [Standalone] Automatic asset pipeline expiry headers support.
15 15
  * [Enterprise] Multithreading support for apps
16 16
  * Deleting restart.txt will no longer trigger a restart.
  17
+ * The watchdog now forces all agents' process groups to exit using SIGKILL, to ensure no garbage processes are left behind.
17 18
 
18 19
 
19 20
 Release 3.0.17
5  ext/common/agents/HelperAgent/Main.cpp
@@ -446,6 +446,7 @@ class Server {
446 446
 			 * instance directory will be cleaned up, making this helper agent
447 447
 			 * inaccessible.
448 448
 			 */
  449
+			P_DEBUG("Watchdog seems to be killed; forcing shutdown of all subprocesses");
449 450
 			syscalls::killpg(getpgrp(), SIGKILL);
450 451
 			_exit(2); // In case killpg() fails.
451 452
 		} else {
@@ -486,11 +487,11 @@ main(int argc, char *argv[]) {
486 487
 		UPDATE_TRACE_POINT();
487 488
 		server.mainLoop();
488 489
 	} catch (const tracable_exception &e) {
489  
-		P_ERROR(e.what() << "\n" << e.backtrace());
  490
+		P_ERROR("*** ERROR: " << e.what() << "\n" << e.backtrace());
490 491
 		return 1;
491 492
 	}
492 493
 	
493 494
 	MultiLibeio::shutdown();
494  
-	P_TRACE(2, "Helper agent exited.");
  495
+	P_TRACE(2, "Helper agent exiting with code 0.");
495 496
 	return 0;
496 497
 }
1  ext/common/agents/LoggingAgent/Main.cpp
@@ -283,6 +283,7 @@ main(int argc, char *argv[]) {
283 283
 		
284 284
 		P_DEBUG("Logging agent online, listening at " << socketAddress);
285 285
 		ev_run(eventLoop, 0);
  286
+		P_DEBUG("Logging agent exiting with code " << exitCode << ".");
286 287
 		return exitCode;
287 288
 	} catch (const tracable_exception &e) {
288 289
 		P_ERROR("*** ERROR: " << e.what() << "\n" << e.backtrace());
13  ext/common/agents/Watchdog/Main.cpp
... ...
@@ -1,6 +1,6 @@
1 1
 /*
2 2
  *  Phusion Passenger - http://www.modrails.com/
3  
- *  Copyright (c) 2010 Phusion
  3
+ *  Copyright (c) 2010-2012 Phusion
4 4
  *
5 5
  *  "Phusion Passenger" is a trademark of Hongli Lai & Ninh Bui.
6 6
  *
@@ -982,12 +982,12 @@ cleanupAgentsInBackground(vector<AgentWatcher *> &watchers) {
982 982
 			// processes.
983 983
 			P_WARN("Some Phusion Passenger agent processes did not exit " <<
984 984
 				"in time, forcefully shutting down all.");
985  
-			for (it = watchers.begin(); it != watchers.end(); it++) {
986  
-				(*it)->forceShutdown();
987  
-			}
988 985
 		} else {
989  
-			P_DEBUG("All Phusion Passenger agent processes have exited.");
  986
+			P_DEBUG("All Phusion Passenger agent processes have exited. Forcing all subprocesses to shut down.");
990 987
 		}
  988
+		for (it = watchers.begin(); it != watchers.end(); it++) {
  989
+				(*it)->forceShutdown();
  990
+			}
991 991
 		
992 992
 		// Now clean up the server instance directory.
993 993
 		delete generation.get();
@@ -1126,10 +1126,11 @@ main(int argc, char *argv[]) {
1126 1126
 			 * the background and exit this watchdog process so that we don't block
1127 1127
 			 * the web server.
1128 1128
 			 */
  1129
+			P_DEBUG("Web server exited gracefully; gracefully shutting down all agents...");
1129 1130
 			cleanupAgentsInBackground(watchers);
1130 1131
 			return 0;
1131 1132
 		} else {
1132  
-			P_DEBUG("Web server did not exit gracefully, forcing shutdown of all service processes...");
  1133
+			P_DEBUG("Web server did not exit gracefully, forcing shutdown of all agents...");
1133 1134
 			forceAllAgentsShutdown(watchers);
1134 1135
 			return 1;
1135 1136
 		}
13  ext/ruby/passenger_native_support.c
@@ -458,6 +458,18 @@ detach_process(VALUE self, VALUE pid) {
458 458
 	return Qnil;
459 459
 }
460 460
 
  461
+/**
  462
+ * Freeze the current process forever. On Ruby 1.9 this never unlocks the GIL.
  463
+ * Useful for testing purposes.
  464
+ */
  465
+static VALUE
  466
+freeze_process(VALUE self) {
  467
+	while (1) {
  468
+		usleep(60 * 1000000);
  469
+	}
  470
+	return Qnil;
  471
+}
  472
+
461 473
 #if defined(HAVE_KQUEUE) || defined(IN_DOXYGEN)
462 474
 typedef struct {
463 475
 	VALUE klass;
@@ -852,6 +864,7 @@ Init_passenger_native_support() {
852 864
 	rb_define_singleton_method(mNativeSupport, "writev3", f_writev3, 4);
853 865
 	rb_define_singleton_method(mNativeSupport, "process_times", process_times, 0);
854 866
 	rb_define_singleton_method(mNativeSupport, "detach_process", detach_process, 1);
  867
+	rb_define_singleton_method(mNativeSupport, "freeze_process", freeze_process, 0);
855 868
 	
856 869
 	#ifdef HAVE_KQUEUE
857 870
 		cFileSystemWatcher = rb_define_class_under(mNativeSupport,

0 notes on commit d953241

Please sign in to comment.
Something went wrong with that request. Please try again.