UNPKG

@chevre/domain

Version:

Chevre Domain Library for Node.js

129 lines (128 loc) 6.11 kB
"use strict"; var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } return new (P || (P = Promise))(function (resolve, reject) { function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } step((generator = generator.apply(thisArg, _arguments || [])).next()); }); }; Object.defineProperty(exports, "__esModule", { value: true }); exports.TransactionNumberCounterRepo = void 0; const errorHandler_1 = require("../errorHandler"); const factory = require("../factory"); const transactionNumber_1 = require("./mongoose/schemas/transactionNumber"); const MAX_RETRY_INCREMENT = 1; /** * 取引番号カウンターリポジトリ */ class TransactionNumberCounterRepo { constructor(params) { const { redisClient, connection } = params; this.redisClient = redisClient; this.transactionNumberModel = connection.model(transactionNumber_1.modelName, (0, transactionNumber_1.createSchema)()); } incrementByRedis(params) { return __awaiter(this, void 0, void 0, function* () { // const now = moment(); const { expires } = params; const key = `${params.includedInDataCatalog.identifier}:${params.identifier}`; // const TTL = moment(expires) // .diff(now, 'seconds'); const [incrReply, expireAtReply] = yield this.redisClient.multi() .incr(key) // .expire(key, TTL) .expireAt(key, expires) .exec(); // tslint:disable-next-line:no-single-line-block-comment /* istanbul ignore else: please write tests */ if (typeof incrReply !== 'number') { // 基本的にありえないフロー throw new factory.errors.Internal('transaction number not incremented unexpectedly'); } // expireAtReplyの検証も追加する(2023-04-19~) const expiredSet = expireAtReply === 1 || expireAtReply === true; if (!expiredSet) { // 基本的にありえないフロー throw new factory.errors.Internal('transaction number expiration not set unexpectedly'); } return incrReply; }); } incrementByMongo(params) { return __awaiter(this, void 0, void 0, function* () { var _a; const now = new Date(); const dataFeedExpires = params.expires; const dataFeedIdentifier = params.identifier; const dataFeed = { typeOf: 'DataFeed', includedInDataCatalog: { identifier: params.includedInDataCatalog.identifier, typeOf: 'DataCatalog' }, dateCreated: now, expires: dataFeedExpires, identifier: dataFeedIdentifier, interactionStatistic: { typeOf: 'InteractionCounter', userInteractionCount: 0 }, project: { id: '*', typeOf: factory.organizationType.Project } }; const { typeOf, includedInDataCatalog, dateCreated, expires, identifier, project, interactionStatistic } = dataFeed; let doc; let retryCount = 0; while (retryCount <= MAX_RETRY_INCREMENT) { try { doc = yield this.transactionNumberModel.findOneAndUpdate({ 'project.id': { $eq: dataFeed.project.id }, 'includedInDataCatalog.identifier': { $eq: dataFeed.includedInDataCatalog.identifier }, identifier: { $eq: dataFeed.identifier } }, { $set: { dateModified: now }, $setOnInsert: { typeOf, includedInDataCatalog, dateCreated, expires, identifier, project, 'interactionStatistic.typeOf': interactionStatistic.typeOf }, $inc: { 'interactionStatistic.userInteractionCount': 1 } }, { upsert: true, new: true, projection: { _id: 0, interactionStatistic: 1 } }) .lean() .exec(); break; } catch (error) { if (yield (0, errorHandler_1.isMongoError)(error)) { if (error.code === errorHandler_1.MongoErrorCode.DuplicateKey) { // すでに存在するので、リトライすればincrementに成功するはず retryCount += 1; continue; } } throw error; } } if (doc === undefined) { throw new factory.errors.NotFound('DataFeed'); } const incrReply = (_a = doc.interactionStatistic) === null || _a === void 0 ? void 0 : _a.userInteractionCount; // tslint:disable-next-line:no-single-line-block-comment /* istanbul ignore if */ if (typeof incrReply !== 'number') { // 基本的にありえないフロー throw new factory.errors.Internal('confirmation number not incremented unexpectedly'); } return incrReply; }); } } exports.TransactionNumberCounterRepo = TransactionNumberCounterRepo;