Yuki Takei 4 лет назад
Родитель
Сommit
37f3eff8a9

+ 53 - 29
packages/app/src/server/service/s2s-messaging/base.ts

@@ -1,12 +1,54 @@
 import loggerFactory from '~/utils/logger';
 import loggerFactory from '~/utils/logger';
 
 
+import S2sMessage from '~/server/models/vo/s2s-message';
+
+import { S2sMessageHandlable } from './handlable';
+
+// eslint-disable-next-line @typescript-eslint/no-unused-vars
 const logger = loggerFactory('growi:service:s2s-messaging:base');
 const logger = loggerFactory('growi:service:s2s-messaging:base');
 
 
-const S2sMessageHandlable = require('./handlable');
 
 
-class S2sMessagingServiceDelegator {
+export interface S2sMessagingService {
+
+  uid: number;
+
+  uri: string;
+
+  handlableList: S2sMessageHandlable[];
+
+  shouldResubscribe(): boolean;
+
+  subscribe(forceReconnect: boolean): void;
+
+  /**
+   * Publish message
+   * @param s2sMessage
+   */
+  publish(s2sMessage: S2sMessage): Promise<void>;
+
+  /**
+   * Add message handler
+   * @param handlable
+   */
+  addMessageHandler(handlable: S2sMessageHandlable): void;
+
+  /**
+   * Remove message handler
+   * @param handlable
+   */
+  removeMessageHandler(handlable: S2sMessageHandlable): void;
+
+}
+
+export abstract class AbstractS2sMessagingService implements S2sMessagingService {
+
+  uid: number;
+
+  uri: string;
 
 
-  constructor(uri) {
+  handlableList: S2sMessageHandlable[];
+
+  constructor(uri: string) {
     this.uid = Math.floor(Math.random() * 100000);
     this.uid = Math.floor(Math.random() * 100000);
     this.uri = uri;
     this.uri = uri;
 
 
@@ -17,50 +59,32 @@ class S2sMessagingServiceDelegator {
     this.handlableList = [];
     this.handlableList = [];
   }
   }
 
 
-  shouldResubscribe() {
-    throw new Error('implement this');
-  }
+  abstract shouldResubscribe(): boolean;
 
 
-  subscribe(forceReconnect) {
-    throw new Error('implement this');
-  }
+  abstract subscribe(forceReconnect: boolean): void;
 
 
   /**
   /**
    * Publish message
    * Publish message
-   * @param {S2sMessage} s2sMessage
+   * @param s2sMessage
    */
    */
-  async publish(s2sMessage) {
+  async publish(s2sMessage: S2sMessage): Promise<void> {
     s2sMessage.setPublisherUid(this.uid);
     s2sMessage.setPublisherUid(this.uid);
   }
   }
 
 
   /**
   /**
    * Add message handler
    * Add message handler
-   * @param {S2sMessageHandlable} handlable
+   * @param handlable
    */
    */
-  addMessageHandler(handlable) {
-    if (!(handlable instanceof S2sMessageHandlable)) {
-      logger.warn('Unsupported instance');
-      logger.debug('Unsupported instance: ', handlable);
-      return;
-    }
-
+  addMessageHandler(handlable: S2sMessageHandlable): void {
     this.handlableList.push(handlable);
     this.handlableList.push(handlable);
   }
   }
 
 
   /**
   /**
    * Remove message handler
    * Remove message handler
-   * @param {S2sMessageHandlable} handlable
+   * @param handlable
    */
    */
-  removeMessageHandler(handlable) {
-    if (!(handlable instanceof S2sMessageHandlable)) {
-      logger.warn('Unsupported instance');
-      logger.debug('Unsupported instance: ', handlable);
-      return;
-    }
-
+  removeMessageHandler(handlable: S2sMessageHandlable): void {
     this.handlableList = this.handlableList.filter(h => h !== handlable);
     this.handlableList = this.handlableList.filter(h => h !== handlable);
   }
   }
 
 
 }
 }
-
-module.exports = S2sMessagingServiceDelegator;

+ 3 - 11
packages/app/src/server/service/s2s-messaging/handlable.ts

@@ -1,18 +1,10 @@
-// TODO: make interface with TS
-
 /**
 /**
  * The interface to handle server-to-server message
  * The interface to handle server-to-server message
  */
  */
-class S2sMessageHandlable {
+export interface S2sMessageHandlable {
 
 
-  shouldHandleS2sMessage(s2sMessage) {
-    throw new Error('implement this');
-  }
+  shouldHandleS2sMessage(s2sMessage): boolean;
 
 
-  async handleS2sMessage(s2sMessage) {
-    throw new Error('implement this');
-  }
+  handleS2sMessage(s2sMessage): Promise<void>;
 
 
 }
 }
-
-module.exports = S2sMessageHandlable;

+ 32 - 2
packages/app/src/server/service/s2s-messaging/index.ts

@@ -1,17 +1,46 @@
 import loggerFactory from '~/utils/logger';
 import loggerFactory from '~/utils/logger';
+import { S2sMessagingService } from './base';
 
 
 const logger = loggerFactory('growi:service:s2s-messaging:S2sMessagingServiceFactory');
 const logger = loggerFactory('growi:service:s2s-messaging:S2sMessagingServiceFactory');
 
 
 const envToModuleMappings = {
 const envToModuleMappings = {
-  redis:   'redis',
-  nchan:   'nchan',
+  redis: 'redis',
+  nchan: 'nchan',
 };
 };
 
 
+// WIP: Ts.ED code
+//
+// registerProvider({
+//   provide: S2sMessagingService,
+//   deps: [ConfigManager],
+//   useFactory(configManager: ConfigManager) {
+//     const type = configManager.getConfig('crowi', 's2sMessagingPubsub:serverType');
+
+//     if (type == null) {
+//       logger.info('Config pub/sub server is not defined.');
+//       return;
+//     }
+
+//     logger.info(`Config pub/sub server type '${type}' is set.`);
+
+//     const module = envToModuleMappings[type];
+
+//     const modulePath = `./${module}`;
+//     this.delegator = require(modulePath)(crowi);
+
+//     if (this.delegator == null) {
+//       logger.warn('Failed to initialize config pub/sub delegator.');
+//     }
+//   },
+// })
+
 /**
 /**
  * Instanciate server-to-server messaging service
  * Instanciate server-to-server messaging service
  */
  */
 class S2sMessagingServiceFactory {
 class S2sMessagingServiceFactory {
 
 
+  delegator!: S2sMessagingService;
+
   initializeDelegator(crowi) {
   initializeDelegator(crowi) {
     const type = crowi.configManager.getConfig('crowi', 's2sMessagingPubsub:serverType');
     const type = crowi.configManager.getConfig('crowi', 's2sMessagingPubsub:serverType');
 
 
@@ -25,6 +54,7 @@ class S2sMessagingServiceFactory {
     const module = envToModuleMappings[type];
     const module = envToModuleMappings[type];
 
 
     const modulePath = `./${module}`;
     const modulePath = `./${module}`;
+    // eslint-disable-next-line @typescript-eslint/no-var-requires
     this.delegator = require(modulePath)(crowi);
     this.delegator = require(modulePath)(crowi);
 
 
     if (this.delegator == null) {
     if (this.delegator == null) {

+ 16 - 21
packages/app/src/server/service/s2s-messaging/nchan.ts

@@ -1,32 +1,27 @@
+import path from 'path';
+import WebSocket from 'ws';
+import ReconnectingWebSocket from 'reconnecting-websocket';
+
+import axios from '~/utils/axios';
 import loggerFactory from '~/utils/logger';
 import loggerFactory from '~/utils/logger';
 
 
+import S2sMessage from '../../models/vo/s2s-message';
+import { AbstractS2sMessagingService } from './base';
+
 const logger = loggerFactory('growi:service:s2s-messaging:nchan');
 const logger = loggerFactory('growi:service:s2s-messaging:nchan');
 
 
-const path = require('path');
-const axios = require('axios');
-const WebSocket = require('ws');
-const ReconnectingWebSocket = require('reconnecting-websocket');
 
 
-const S2sMessage = require('../../models/vo/s2s-message');
-const S2sMessagingServiceDelegator = require('./base');
+class NchanDelegator extends AbstractS2sMessagingService {
 
 
+  /**
+   * A list of S2sMessageHandlable instance
+   */
+  handlableToEventListenerMap: any = {};
 
 
-class NchanDelegator extends S2sMessagingServiceDelegator {
+  socket: any = null;
 
 
-  constructor(uri, publishPath, subscribePath, channelId) {
+  constructor(uri, private publishPath: string, private subscribePath: string, private channelId: any) {
     super(uri);
     super(uri);
-
-    this.publishPath = publishPath;
-    this.subscribePath = subscribePath;
-
-    this.channelId = channelId;
-
-    /**
-     * A list of S2sMessageHandlable instance
-     */
-    this.handlableToEventListenerMap = {};
-
-    this.socket = null;
   }
   }
 
 
   /**
   /**
@@ -61,7 +56,7 @@ class NchanDelegator extends S2sMessagingServiceDelegator {
   /**
   /**
    * @inheritdoc
    * @inheritdoc
    */
    */
-  async publish(s2sMessage) {
+  async publish(s2sMessage: S2sMessage): Promise<void> {
     await super.publish(s2sMessage);
     await super.publish(s2sMessage);
 
 
     const url = this.constructUrl(this.publishPath).toString();
     const url = this.constructUrl(this.publishPath).toString();