@chevre/domain
Version:
Chevre Domain Library for Node.js
129 lines (128 loc) • 6.11 kB
JavaScript
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;
;