소스 검색

flush redis before max memory is reached; hotfix for #49

jomo 10 년 전
부모
커밋
c80eefd992
4개의 변경된 파일58개의 추가작업 그리고 11개의 파일을 삭제
  1. 12 0
      modules/cache.js
  2. 43 9
      modules/cleaner.js
  3. 2 1
      modules/config.example.js
  4. 1 1
      server.js

+ 12 - 0
modules/cache.js

@@ -51,10 +51,22 @@ function update_file_date(hash) {
 
 var exp = {};
 
+// returns the redis instance
 exp.get_redis = function() {
   return redis;
 };
 
+
+// updates the redis instance's server_info object
+// callback contains error, info object
+exp.info = function(callback) {
+  redis.info(function (err, res) {
+    // parse the info command and store it in redis.server_info
+    redis.on_info_cmd(err, res);
+    callback(err, redis.server_info);
+  });
+};
+
 // sets the timestamp for +uuid+ and its face file's date to now
 exp.update_timestamp = function(uuid, hash) {
   logging.log(uuid + " cache: updating timestamp");

+ 43 - 9
modules/clean_images.js → modules/cleaner.js

@@ -1,13 +1,35 @@
 var logging = require("./logging");
 var config = require("./config");
+var cache = require("./cache");
 var df = require("node-df");
 var fs = require("fs");
 
+var redis = cache.get_redis();
 var exp = {};
 
+// compares redis' used_memory with cleaning_redis_limit
+// callback contains error, true|false
+function should_clean_redis(callback) {
+  cache.info(function(err, info) {
+    if (err) {
+      callback(err, false);
+    } else {
+      try {
+        logging.debug(info);
+        logging.debug("used mem:" + info.used_memory);
+        var used = parseInt(info.used_memory) / 1024;
+        logging.log("RedisCleaner: " + used + "KB used");
+        callback(err, used >= config.cleaning_redis_limit);
+      } catch(e) {
+        callback(e, false);
+      }
+    }
+  });
+}
+
 // uses `df` to get the available fisk space
 // callback contains error, true|false
-function should_clean(callback) {
+function should_clean_disk(callback) {
   df({
     file: __dirname + "/../" + config.faces_dir,
     prefixMultiplier: 'KiB',
@@ -18,21 +40,33 @@ function should_clean(callback) {
       callback(err, false);
     } else {
       var available = response[0].available;
-      console.log("ImageCleaner: " + available + "KB available");
-      callback(err, available < config.cleaning_limit);
+      logging.log("DiskCleaner: " + available + "KB available");
+      callback(err, available < config.cleaning_disk_limit);
     }
   });
 }
 
-// check if disk limit reached
-// then delete images
+// check if redis limit reached, then flush redis
+// check if disk limit reached, then delete images
 exp.run = function() {
-  should_clean(function(err, clean) {
+  should_clean_redis(function(err, clean) {
+    if (err) {
+      logging.error("Failed to run RedisCleaner");
+      logging.error(err);
+    } else if (clean) {
+      logging.warn("RedisCleaner: Redis limit reached! flushing now");
+      redis.flushall();
+    } else {
+      logging.log("RedisCleaner: Nothing to clean");
+    }
+  });
+
+  should_clean_disk(function(err, clean) {
     if (err) {
-      logging.error("Failed to run ImageCleaner");
+      logging.error("Failed to run DiskCleaner");
       logging.error(err);
     } else if (clean) {
-      logging.warn("ImageCleaner: Disk limit reached! Cleaning images now");
+      logging.warn("DiskCleaner: Disk limit reached! Cleaning images now");
       var facesdir = __dirname + "/../" + config.faces_dir;
       var helmdir = __dirname + "/../" + config.helms_dir;
       var renderdir = __dirname + "/../" + config.renders_dir;
@@ -54,7 +88,7 @@ exp.run = function() {
         }
       }
     } else {
-      logging.log("ImageCleaner: Nothing to clean");
+      logging.log("DiskCleaner: Nothing to clean");
     }
   });
 };

+ 2 - 1
modules/config.example.js

@@ -5,7 +5,8 @@ var config = {
   local_cache_time: 1200,        // seconds until we will check if the image changed. should be > 60 to prevent mojang 429 response
   browser_cache_time: 3600,      // seconds until browser will request image again
   cleaning_interval: 1800,       // seconds interval: deleting images if disk size at limit
-  cleaning_limit: 10240,         // minumum required available KB on disk to trigger cleaning
+  cleaning_disk_limit: 10240,    // min allowed available KB on disk to trigger cleaning
+  cleaning_redis_limit: 24576,   // max allowed used KB on redis to trigger redis flush
   cleaning_amount: 50000,        // amount of avatar (and their helm) files to clean
   http_timeout: 1000,            // ms until connection to mojang is dropped
   faces_dir: 'skins/faces/',     // directory where faces are kept. should have trailing '/'

+ 1 - 1
server.js

@@ -1,7 +1,7 @@
 #!/usr/bin/env node
 var config = require("./modules/config");
 var debug = require("debug")("crafatar");
-var clean = require("./modules/clean_images");
+var clean = require("./modules/cleaner");
 var app = require("./app");
 
 app.set("port", process.env.PORT || 3000);