From 20ac7e62e90e04e3ce74e0996756a2c7297e552e Mon Sep 17 00:00:00 2001 From: MeiMei <30769358+mei23@users.noreply.github.com> Date: Fri, 6 Mar 2020 22:33:54 +0900 Subject: [PATCH] =?UTF-8?q?=E3=83=81=E3=83=A3=E3=83=BC=E3=83=88Insert?= =?UTF-8?q?=E6=99=82=E3=81=AB=E3=83=AD=E3=83=83=E3=82=AF=E3=82=92=E3=81=8B?= =?UTF-8?q?=E3=81=91=E3=82=8B=E3=82=88=E3=81=86=E3=81=AB=20(#6100)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * chart lock * fix --- src/misc/app-lock.ts | 4 ++++ src/services/chart/core.ts | 35 ++++++++++++++++++++--------------- 2 files changed, 24 insertions(+), 15 deletions(-) diff --git a/src/misc/app-lock.ts b/src/misc/app-lock.ts index 3d5ff91882..ca2181f879 100644 --- a/src/misc/app-lock.ts +++ b/src/misc/app-lock.ts @@ -24,3 +24,7 @@ export function getApLock(uri: string, timeout = 30 * 1000) { export function getNodeinfoLock(host: string, timeout = 30 * 1000) { return lock(`nodeinfo:${host}`, timeout); } + +export function getChartInsertLock(lockKey: string, timeout = 30 * 1000) { + return lock(`chart-insert:${lockKey}`, timeout); +} diff --git a/src/services/chart/core.ts b/src/services/chart/core.ts index 088c524780..f471a9920c 100644 --- a/src/services/chart/core.ts +++ b/src/services/chart/core.ts @@ -9,8 +9,8 @@ import autobind from 'autobind-decorator'; import Logger from '../logger'; import { Schema } from '../../misc/schema'; import { EntitySchema, getRepository, Repository, LessThan, MoreThanOrEqual } from 'typeorm'; -import { isDuplicateKeyValueError } from '../../misc/is-duplicate-key-value-error'; import { DateUTC, isTimeSame, isTimeBefore, subtractTimespan } from '../../prelude/time'; +import { getChartInsertLock } from '../../misc/app-lock'; const logger = new Logger('chart', 'white', process.env.NODE_ENV !== 'test'); @@ -283,30 +283,35 @@ export default abstract class Chart> { logger.info(`${this.name + (group ? `:${group}` : '')} (${span}): Initial commit created`); } + const date = Chart.dateToTimestamp(current); + const lockKey = `${this.name}:${date}:${group}:${span}`; + + const unlock = await getChartInsertLock(lockKey); try { + // ロック内でもう1回チェックする + const currentLog = await this.repository.findOne({ + span: span, + date: date, + ...(group ? { group: group } : {}) + }); + + // ログがあればそれを返して終了 + if (currentLog != null) return currentLog; + // 新規ログ挿入 log = await this.repository.save({ group: group, span: span, - date: Chart.dateToTimestamp(current), + date: date, ...Chart.convertObjectToFlattenColumns(data) }); logger.info(`${this.name + (group ? `:${group}` : '')} (${span}): New commit created`); - } catch (e) { - // duplicate key error - // 並列動作している他のチャートエンジンプロセスと処理が重なる場合がある - // その場合は再度最も新しいログを持ってくる - if (isDuplicateKeyValueError(e)) { - log = await this.getLatestLog(span, group) as Log; - logger.info(`${this.name + (group ? `:${group}` : '')} (${span}): Commit duplicated`); - } else { - logger.error(e); - throw e; - } - } - return log; + return log; + } finally { + unlock(); + } } @autobind