Merge pull request #477 from RedBrogdon/healthchecks

diff --git a/lib/services_gae.dart b/lib/services_gae.dart
index d065726..7159f23 100644
--- a/lib/services_gae.dart
+++ b/lib/services_gae.dart
@@ -128,24 +128,31 @@
   }
 
   Future _processHealthRequest(io.HttpRequest request) async {
-    try {
-      final tempDir = await io.Directory.systemTemp.createTemp('healthz');
-      try {
-        final file = await io.File('${tempDir.path}/livecheck.txt');
-        await file.writeAsString('testing123\n' * 1000, flush: true);
-        final stat = await file.stat();
-        if (stat.size > 10000) {
-          request.response.statusCode = io.HttpStatus.ok;
-        } else {
-          request.response.statusCode = io.HttpStatus.internalServerError;
-        }
-      } finally {
-        await tempDir.delete(recursive: true);
-      }
-    } catch (e) {
-      _logger.severe('Failed to create temporary file: $e');
+    if (commonServer.running && !commonServer.analysisServersRunning) {
+      _logger.severe('CommonServer running without analysis servers. '
+          'Intentionally failing healthcheck.');
       request.response.statusCode = io.HttpStatus.internalServerError;
+    } else {
+      try {
+        final tempDir = await io.Directory.systemTemp.createTemp('healthz');
+        try {
+          final file = await io.File('${tempDir.path}/livecheck.txt');
+          await file.writeAsString('testing123\n' * 1000, flush: true);
+          final stat = await file.stat();
+          if (stat.size > 10000) {
+            request.response.statusCode = io.HttpStatus.ok;
+          } else {
+            request.response.statusCode = io.HttpStatus.internalServerError;
+          }
+        } finally {
+          await tempDir.delete(recursive: true);
+        }
+      } catch (e) {
+        _logger.severe('Failed to create temporary file: $e');
+        request.response.statusCode = io.HttpStatus.internalServerError;
+      }
     }
+
     await request.response.close();
   }
 
diff --git a/lib/src/common_server.dart b/lib/src/common_server.dart
index 1867269..161ed12 100644
--- a/lib/src/common_server.dart
+++ b/lib/src/common_server.dart
@@ -268,6 +268,12 @@
   AnalysisServerWrapper analysisServer;
   AnalysisServerWrapper flutterAnalysisServer;
 
+  bool get analysisServersRunning => analysisServer.analysisServer != null &&
+    flutterAnalysisServer.analysisServer != null;
+
+  bool _running = false;
+  bool get running => _running;
+
   CommonServer(
     this.sdkPath,
     this.flutterWebManager,
@@ -313,6 +319,7 @@
     await compiler.warmup(useHtml: useHtml);
     await analysisServer.warmup(useHtml: useHtml);
     await flutterAnalysisServer.warmup(useHtml: useHtml);
+    _running = true;
   }
 
   Future<void> restart() async {
@@ -327,6 +334,7 @@
   }
 
   Future<dynamic> shutdown() {
+    _running = false;
     return Future.wait(<Future<dynamic>>[
       analysisServer.shutdown(),
       flutterAnalysisServer.shutdown(),
diff --git a/tool/grind.dart b/tool/grind.dart
index 445792d..799a6a8 100644
--- a/tool/grind.dart
+++ b/tool/grind.dart
@@ -196,7 +196,7 @@
       'artifacts/*.js gs://compilation_artifacts/$version/');
 }
 
-@Task()
+@Task('Delete, re-download, and reinitialize the Flutter submodule.')
 void setupFlutterSubmodule() {
   final flutterDir = Directory('flutter');