Просмотр исходного кода

impl publish and reload process

Yuki Takei 5 лет назад
Родитель
Сommit
33c52f83c2
2 измененных файлов с 48 добавлено и 3 удалено
  1. 43 1
      src/server/service/config-manager.js
  2. 5 2
      src/server/service/config-pubsub/nchan.js

+ 43 - 1
src/server/service/config-manager.js

@@ -25,6 +25,7 @@ class ConfigManager {
     this.configLoader = new ConfigLoader(this.configModel);
     this.configObject = null;
     this.configKeys = [];
+    this.lastLoadedAt = null;
 
     this.getConfig = this.getConfig.bind(this);
   }
@@ -38,6 +39,8 @@ class ConfigManager {
 
     // cache all config keys
     this.reloadConfigKeys();
+
+    this.lastLoadedAt = new Date();
   }
 
   /**
@@ -47,7 +50,8 @@ class ConfigManager {
   async setPubsub(configPubsub) {
     this.configPubsub = configPubsub;
     this.configPubsub.addMessageHandler((message) => {
-      logger.info('message recieved', message);
+      logger.debug('Recieved message from publisher', message);
+      this.handleUpdateMessage(message);
     });
   }
 
@@ -187,8 +191,15 @@ class ConfigManager {
     }
     await this.configModel.bulkWrite(queries);
 
+    // get updated date before loading
+    //  to avoid triggering a reload by the own notification
+    const updatedAt = new Date();
+
     await this.loadConfigs();
     this.reloadConfigKeys();
+
+    // publish updated date after reloading
+    this.publishUpdateMessage(updatedAt);
   }
 
   /**
@@ -298,6 +309,37 @@ class ConfigManager {
     return JSON.stringify(value === '' ? null : value);
   }
 
+  async publishUpdateMessage(updatedAt) {
+    const message = JSON.stringify({ updatedAt });
+    this.configPubsub.publish(message);
+  }
+
+  async handleUpdateMessage(message) {
+    let parsedMessage;
+    let updatedAt;
+
+    try {
+      // parse JSON
+      parsedMessage = JSON.parse(message);
+
+      if (!(parsedMessage instanceof Object)) {
+        throw new Error('A message could not be parsed to JSON object', message);
+      }
+
+      // parse Date
+      updatedAt = new Date(parsedMessage.updatedAt);
+    }
+    catch (e) {
+      logger.warn(e.message);
+      return;
+    }
+
+    if (this.lastLoadedAt == null || this.lastLoadedAt < updatedAt) {
+      logger.info('Reload configs by pubsub notification');
+      return this.loadConfigs();
+    }
+  }
+
 }
 
 module.exports = ConfigManager;

+ 5 - 2
src/server/service/config-pubsub/nchan.js

@@ -1,6 +1,7 @@
 const logger = require('@alias/logger')('growi:service:config-pubsub:nchan');
 
 const path = require('path');
+const axios = require('axios');
 const WebSocketClient = require('websocket').client;
 
 const ConfigPubsubDelegator = require('./base');
@@ -52,14 +53,16 @@ class NchanDelegator extends ConfigPubsubDelegator {
   /**
    * @inheritdoc
    */
-  publish() {
+  publish(message) {
     const pathname = this.channelId == null
       ? this.publishPath //                                 /pub
       : path.join(this.subscribePath, this.channelId); //   /pub/my-channel-id
 
     const publishUri = new URL(pathname, this.uri);
 
-    throw new Error('implement this');
+    logger.debug('Publish message', message);
+
+    axios.post(publishUri.toString(), message);
   }
 
   /**