Mwalker has uploaded a new change for review.

  https://gerrit.wikimedia.org/r/148738

Change subject: Add path and size information to health check
......................................................................

Add path and size information to health check

TODO: This has just revealed a horrible problem with the config
object; in that the defaults are computed in the backgrond thread
which is a separate process from the frontend -- meaning the frontend
has no clue what the backend did to the config options. Solution: always
set paths statically in the config file...

Change-Id: Icd8c6d43eb1ba57b75b70c3d63c14212a4f3ea8a
---
M lib/threads/frontend.js
1 file changed, 82 insertions(+), 35 deletions(-)


  git pull 
ssh://gerrit.wikimedia.org:29418/mediawiki/extensions/Collection/OfflineContentGenerator
 refs/changes/38/148738/1

diff --git a/lib/threads/frontend.js b/lib/threads/frontend.js
index 1400c6b..e9fea68 100644
--- a/lib/threads/frontend.js
+++ b/lib/threads/frontend.js
@@ -30,6 +30,7 @@
 var fs = require( 'fs' );
 var http = require( 'http' );
 var mime = require( 'mime' );
+var path = require( 'path' );
 var url = require( 'url' );
 var util = require( 'util' );
 
@@ -290,43 +291,60 @@
  * @param response
  */
 function handleHealthCheck( requestId, args, response ) {
-       var responseAry = {};
+       var responseAry = {
+               'host': config.coordinator.hostname,
+               'directories': {
+                       'temp': { path: config.backend.temp_dir, size: 0 },
+                       'output': { path: config.backend.output_dir, size: 0 },
+                       'postmortem': { path: config.backend.post_mortem_dir, 
size: 0 }
+               }
+       };
 
-       return redisClient
-               .llen( config.redis.job_queue_name )
-               .then( function( len ) {
-                       responseAry.JobQueue = {
-                               name: config.redis.job_queue_name,
-                               length: len
-                       };
-               } ).then( function() {
-                       return redisClient.hlen( config.redis.status_set_name );
-               } ).then( function( len ) {
-                       responseAry.StatusObjects = {
-                               name: config.redis.status_set_name,
-                               length: len
-                       };
-               } ).then( function() {
-                       // Add a time to the response so we know it's current
-                       responseAry.time = Date.now();
-                       response.writeHead( 200, "OK" );
-                       response.write( JSON.stringify( responseAry ) );
-                       response.end();
-               } ).then( function() {
-                       statsd.gauge( 'job_queue_length', 
responseAry.JobQueue.length );
-                       statsd.gauge( 'status_objects', 
responseAry.StatusObjects.length );
-               } ).catch( function( err ) {
-                       console.error(
-                               'Health failed with error: %s',
-                               err,
-                               {
-                                       channel: 'frontend.error',
-                                       error: eh.jsonify( err ),
-                                       request: { id: requestId }
-                               }
-                       );
-                       throw new FrontendError( 'Status check failed (redis 
failure?)', 500 );
+       var resolveSize = function ( node ) {
+               return Promise.resolve( getFolderSize( node.path ) ).then( 
function( size ) {
+                       node.size = size;
                } );
+       };
+
+       return Promise.all( [
+               resolveSize( responseAry.directories.temp ),
+               resolveSize( responseAry.directories.output ),
+               resolveSize( responseAry.directories.postmortem ),
+       ] ).then( function() {
+               return redisClient.llen( config.redis.job_queue_name )
+       } ).then( function( len ) {
+               responseAry.JobQueue = {
+                       name: config.redis.job_queue_name,
+                       length: len
+               };
+       } ).then( function() {
+               return redisClient.hlen( config.redis.status_set_name );
+       } ).then( function( len ) {
+               responseAry.StatusObjects = {
+                       name: config.redis.status_set_name,
+                       length: len
+               };
+       } ).then( function() {
+               // Add a time to the response so we know it's current
+               responseAry.time = Date.now();
+               response.writeHead( 200, "OK" );
+               response.write( JSON.stringify( responseAry ) );
+               response.end();
+       } ).then( function() {
+               statsd.gauge( 'job_queue_length', responseAry.JobQueue.length );
+               statsd.gauge( 'status_objects', 
responseAry.StatusObjects.length );
+       } ).catch( function( err ) {
+               console.error(
+                       'Health failed with error: %s',
+                       err,
+                       {
+                               channel: 'frontend.error',
+                               error: eh.jsonify( err ),
+                               request: { id: requestId }
+                       }
+               );
+               throw new FrontendError( 'Status check failed (redis 
failure?)', 500 );
+       } );
 }
 
 /**
@@ -637,6 +655,35 @@
 }
 
 /**
+ * Obtain the size in bytes of all the contents of a folder
+ * @param {string} fspath - File system path
+ * @returns {int} Size in bytes of the folder
+ */
+function getFolderSize( fspath ) {
+       var lstat = Promise.promisify( fs.lstat, false, fs );
+       var readdir = Promise.promisify( fs.readdir, false, fs );
+
+       if ( !fspath ) {
+               return 0;
+       }
+
+       return lstat( fspath ).then( function( stat ) {
+               if ( stat.isDirectory() ) {
+                       return readdir( fspath ).map( function( item ) {
+                               return getFolderSize( path.join( fspath, item ) 
);
+                       } ).then( function ( sizes ) {
+                               return sizes.reduce( function( prev, current ) 
{ return prev + current; }, 0 );
+                       } );
+               } else {
+                       return stat.size;
+               }
+       } ).catch( function( err ) {
+               console.warn( "Could not find size of '%s': %s", fspath, err );
+               return 0;
+       } );
+}
+
+/**
  * HTTP error analogue; throw and code will be returned to HTTP client
  *
  * @param {string} message - Message that will be logged

-- 
To view, visit https://gerrit.wikimedia.org/r/148738
To unsubscribe, visit https://gerrit.wikimedia.org/r/settings

Gerrit-MessageType: newchange
Gerrit-Change-Id: Icd8c6d43eb1ba57b75b70c3d63c14212a4f3ea8a
Gerrit-PatchSet: 1
Gerrit-Project: mediawiki/extensions/Collection/OfflineContentGenerator
Gerrit-Branch: master
Gerrit-Owner: Mwalker <mwal...@wikimedia.org>

_______________________________________________
MediaWiki-commits mailing list
MediaWiki-commits@lists.wikimedia.org
https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits

Reply via email to