mirror of
https://github.com/IT4Change/gradido.git
synced 2025-12-13 07:45:54 +00:00
try catch around semaphore lock
This commit is contained in:
parent
e59d2f0a0e
commit
dab7fe584a
@ -170,148 +170,151 @@ export class TransactionLinkResolver {
|
|||||||
if (code.match(/^CL-/)) {
|
if (code.match(/^CL-/)) {
|
||||||
// acquire lock
|
// acquire lock
|
||||||
const releaseLock = await TRANSACTIONS_LOCK.acquire()
|
const releaseLock = await TRANSACTIONS_LOCK.acquire()
|
||||||
logger.info('redeem contribution link...')
|
|
||||||
const now = new Date()
|
|
||||||
const queryRunner = getConnection().createQueryRunner()
|
|
||||||
await queryRunner.connect()
|
|
||||||
await queryRunner.startTransaction('REPEATABLE READ')
|
|
||||||
try {
|
try {
|
||||||
const contributionLink = await queryRunner.manager
|
logger.info('redeem contribution link...')
|
||||||
.createQueryBuilder()
|
const now = new Date()
|
||||||
.select('contributionLink')
|
const queryRunner = getConnection().createQueryRunner()
|
||||||
.from(DbContributionLink, 'contributionLink')
|
await queryRunner.connect()
|
||||||
.where('contributionLink.code = :code', { code: code.replace('CL-', '') })
|
await queryRunner.startTransaction('REPEATABLE READ')
|
||||||
.getOne()
|
try {
|
||||||
if (!contributionLink) {
|
const contributionLink = await queryRunner.manager
|
||||||
logger.error('no contribution link found to given code:', code)
|
.createQueryBuilder()
|
||||||
throw new Error('No contribution link found')
|
.select('contributionLink')
|
||||||
}
|
.from(DbContributionLink, 'contributionLink')
|
||||||
logger.info('...contribution link found with id', contributionLink.id)
|
.where('contributionLink.code = :code', { code: code.replace('CL-', '') })
|
||||||
if (new Date(contributionLink.validFrom).getTime() > now.getTime()) {
|
.getOne()
|
||||||
logger.error(
|
if (!contributionLink) {
|
||||||
'contribution link is not valid yet. Valid from: ',
|
logger.error('no contribution link found to given code:', code)
|
||||||
contributionLink.validFrom,
|
throw new Error('No contribution link found')
|
||||||
)
|
|
||||||
throw new Error('Contribution link not valid yet')
|
|
||||||
}
|
|
||||||
if (contributionLink.validTo) {
|
|
||||||
if (new Date(contributionLink.validTo).setHours(23, 59, 59) < now.getTime()) {
|
|
||||||
logger.error('contribution link is depricated. Valid to: ', contributionLink.validTo)
|
|
||||||
throw new Error('Contribution link is depricated')
|
|
||||||
}
|
}
|
||||||
}
|
logger.info('...contribution link found with id', contributionLink.id)
|
||||||
let alreadyRedeemed: DbContribution | undefined
|
if (new Date(contributionLink.validFrom).getTime() > now.getTime()) {
|
||||||
switch (contributionLink.cycle) {
|
logger.error(
|
||||||
case ContributionCycleType.ONCE: {
|
'contribution link is not valid yet. Valid from: ',
|
||||||
alreadyRedeemed = await queryRunner.manager
|
contributionLink.validFrom,
|
||||||
.createQueryBuilder()
|
)
|
||||||
.select('contribution')
|
throw new Error('Contribution link not valid yet')
|
||||||
.from(DbContribution, 'contribution')
|
}
|
||||||
.where('contribution.contributionLinkId = :linkId AND contribution.userId = :id', {
|
if (contributionLink.validTo) {
|
||||||
linkId: contributionLink.id,
|
if (new Date(contributionLink.validTo).setHours(23, 59, 59) < now.getTime()) {
|
||||||
id: user.id,
|
logger.error('contribution link is depricated. Valid to: ', contributionLink.validTo)
|
||||||
})
|
throw new Error('Contribution link is depricated')
|
||||||
.getOne()
|
|
||||||
if (alreadyRedeemed) {
|
|
||||||
logger.error(
|
|
||||||
'contribution link with rule ONCE already redeemed by user with id',
|
|
||||||
user.id,
|
|
||||||
)
|
|
||||||
throw new Error('Contribution link already redeemed')
|
|
||||||
}
|
}
|
||||||
break
|
|
||||||
}
|
}
|
||||||
case ContributionCycleType.DAILY: {
|
let alreadyRedeemed: DbContribution | undefined
|
||||||
const start = new Date()
|
switch (contributionLink.cycle) {
|
||||||
start.setHours(0, 0, 0, 0)
|
case ContributionCycleType.ONCE: {
|
||||||
const end = new Date()
|
alreadyRedeemed = await queryRunner.manager
|
||||||
end.setHours(23, 59, 59, 999)
|
.createQueryBuilder()
|
||||||
alreadyRedeemed = await queryRunner.manager
|
.select('contribution')
|
||||||
.createQueryBuilder()
|
.from(DbContribution, 'contribution')
|
||||||
.select('contribution')
|
.where('contribution.contributionLinkId = :linkId AND contribution.userId = :id', {
|
||||||
.from(DbContribution, 'contribution')
|
|
||||||
.where(
|
|
||||||
`contribution.contributionLinkId = :linkId AND contribution.userId = :id
|
|
||||||
AND Date(contribution.confirmedAt) BETWEEN :start AND :end`,
|
|
||||||
{
|
|
||||||
linkId: contributionLink.id,
|
linkId: contributionLink.id,
|
||||||
id: user.id,
|
id: user.id,
|
||||||
start,
|
})
|
||||||
end,
|
.getOne()
|
||||||
},
|
if (alreadyRedeemed) {
|
||||||
)
|
logger.error(
|
||||||
.getOne()
|
'contribution link with rule ONCE already redeemed by user with id',
|
||||||
if (alreadyRedeemed) {
|
user.id,
|
||||||
logger.error(
|
)
|
||||||
'contribution link with rule DAILY already redeemed by user with id',
|
throw new Error('Contribution link already redeemed')
|
||||||
user.id,
|
}
|
||||||
)
|
break
|
||||||
throw new Error('Contribution link already redeemed today')
|
}
|
||||||
|
case ContributionCycleType.DAILY: {
|
||||||
|
const start = new Date()
|
||||||
|
start.setHours(0, 0, 0, 0)
|
||||||
|
const end = new Date()
|
||||||
|
end.setHours(23, 59, 59, 999)
|
||||||
|
alreadyRedeemed = await queryRunner.manager
|
||||||
|
.createQueryBuilder()
|
||||||
|
.select('contribution')
|
||||||
|
.from(DbContribution, 'contribution')
|
||||||
|
.where(
|
||||||
|
`contribution.contributionLinkId = :linkId AND contribution.userId = :id
|
||||||
|
AND Date(contribution.confirmedAt) BETWEEN :start AND :end`,
|
||||||
|
{
|
||||||
|
linkId: contributionLink.id,
|
||||||
|
id: user.id,
|
||||||
|
start,
|
||||||
|
end,
|
||||||
|
},
|
||||||
|
)
|
||||||
|
.getOne()
|
||||||
|
if (alreadyRedeemed) {
|
||||||
|
logger.error(
|
||||||
|
'contribution link with rule DAILY already redeemed by user with id',
|
||||||
|
user.id,
|
||||||
|
)
|
||||||
|
throw new Error('Contribution link already redeemed today')
|
||||||
|
}
|
||||||
|
break
|
||||||
|
}
|
||||||
|
default: {
|
||||||
|
logger.error('contribution link has unknown cycle', contributionLink.cycle)
|
||||||
|
throw new Error('Contribution link has unknown cycle')
|
||||||
}
|
}
|
||||||
break
|
|
||||||
}
|
}
|
||||||
default: {
|
|
||||||
logger.error('contribution link has unknown cycle', contributionLink.cycle)
|
const creations = await getUserCreation(user.id, clientTimezoneOffset)
|
||||||
throw new Error('Contribution link has unknown cycle')
|
logger.info('open creations', creations)
|
||||||
|
validateContribution(creations, contributionLink.amount, now, clientTimezoneOffset)
|
||||||
|
const contribution = new DbContribution()
|
||||||
|
contribution.userId = user.id
|
||||||
|
contribution.createdAt = now
|
||||||
|
contribution.contributionDate = now
|
||||||
|
contribution.memo = contributionLink.memo
|
||||||
|
contribution.amount = contributionLink.amount
|
||||||
|
contribution.contributionLinkId = contributionLink.id
|
||||||
|
contribution.contributionType = ContributionType.LINK
|
||||||
|
contribution.contributionStatus = ContributionStatus.CONFIRMED
|
||||||
|
|
||||||
|
await queryRunner.manager.insert(DbContribution, contribution)
|
||||||
|
|
||||||
|
const lastTransaction = await queryRunner.manager
|
||||||
|
.createQueryBuilder()
|
||||||
|
.select('transaction')
|
||||||
|
.from(DbTransaction, 'transaction')
|
||||||
|
.where('transaction.userId = :id', { id: user.id })
|
||||||
|
.orderBy('transaction.id', 'DESC')
|
||||||
|
.getOne()
|
||||||
|
let newBalance = new Decimal(0)
|
||||||
|
|
||||||
|
let decay: Decay | null = null
|
||||||
|
if (lastTransaction) {
|
||||||
|
decay = calculateDecay(lastTransaction.balance, lastTransaction.balanceDate, now)
|
||||||
|
newBalance = decay.balance
|
||||||
}
|
}
|
||||||
|
newBalance = newBalance.add(contributionLink.amount.toString())
|
||||||
|
|
||||||
|
const transaction = new DbTransaction()
|
||||||
|
transaction.typeId = TransactionTypeId.CREATION
|
||||||
|
transaction.memo = contribution.memo
|
||||||
|
transaction.userId = contribution.userId
|
||||||
|
transaction.previous = lastTransaction ? lastTransaction.id : null
|
||||||
|
transaction.amount = contribution.amount
|
||||||
|
transaction.creationDate = contribution.contributionDate
|
||||||
|
transaction.balance = newBalance
|
||||||
|
transaction.balanceDate = now
|
||||||
|
transaction.decay = decay ? decay.decay : new Decimal(0)
|
||||||
|
transaction.decayStart = decay ? decay.start : null
|
||||||
|
await queryRunner.manager.insert(DbTransaction, transaction)
|
||||||
|
|
||||||
|
contribution.confirmedAt = now
|
||||||
|
contribution.transactionId = transaction.id
|
||||||
|
await queryRunner.manager.update(DbContribution, { id: contribution.id }, contribution)
|
||||||
|
|
||||||
|
await queryRunner.commitTransaction()
|
||||||
|
logger.info('creation from contribution link commited successfuly.')
|
||||||
|
} catch (e) {
|
||||||
|
await queryRunner.rollbackTransaction()
|
||||||
|
logger.error(`Creation from contribution link was not successful: ${e}`)
|
||||||
|
throw new Error(`Creation from contribution link was not successful. ${e}`)
|
||||||
|
} finally {
|
||||||
|
await queryRunner.release()
|
||||||
}
|
}
|
||||||
|
|
||||||
const creations = await getUserCreation(user.id, clientTimezoneOffset)
|
|
||||||
logger.info('open creations', creations)
|
|
||||||
validateContribution(creations, contributionLink.amount, now, clientTimezoneOffset)
|
|
||||||
const contribution = new DbContribution()
|
|
||||||
contribution.userId = user.id
|
|
||||||
contribution.createdAt = now
|
|
||||||
contribution.contributionDate = now
|
|
||||||
contribution.memo = contributionLink.memo
|
|
||||||
contribution.amount = contributionLink.amount
|
|
||||||
contribution.contributionLinkId = contributionLink.id
|
|
||||||
contribution.contributionType = ContributionType.LINK
|
|
||||||
contribution.contributionStatus = ContributionStatus.CONFIRMED
|
|
||||||
|
|
||||||
await queryRunner.manager.insert(DbContribution, contribution)
|
|
||||||
|
|
||||||
const lastTransaction = await queryRunner.manager
|
|
||||||
.createQueryBuilder()
|
|
||||||
.select('transaction')
|
|
||||||
.from(DbTransaction, 'transaction')
|
|
||||||
.where('transaction.userId = :id', { id: user.id })
|
|
||||||
.orderBy('transaction.id', 'DESC')
|
|
||||||
.getOne()
|
|
||||||
let newBalance = new Decimal(0)
|
|
||||||
|
|
||||||
let decay: Decay | null = null
|
|
||||||
if (lastTransaction) {
|
|
||||||
decay = calculateDecay(lastTransaction.balance, lastTransaction.balanceDate, now)
|
|
||||||
newBalance = decay.balance
|
|
||||||
}
|
|
||||||
newBalance = newBalance.add(contributionLink.amount.toString())
|
|
||||||
|
|
||||||
const transaction = new DbTransaction()
|
|
||||||
transaction.typeId = TransactionTypeId.CREATION
|
|
||||||
transaction.memo = contribution.memo
|
|
||||||
transaction.userId = contribution.userId
|
|
||||||
transaction.previous = lastTransaction ? lastTransaction.id : null
|
|
||||||
transaction.amount = contribution.amount
|
|
||||||
transaction.creationDate = contribution.contributionDate
|
|
||||||
transaction.balance = newBalance
|
|
||||||
transaction.balanceDate = now
|
|
||||||
transaction.decay = decay ? decay.decay : new Decimal(0)
|
|
||||||
transaction.decayStart = decay ? decay.start : null
|
|
||||||
await queryRunner.manager.insert(DbTransaction, transaction)
|
|
||||||
|
|
||||||
contribution.confirmedAt = now
|
|
||||||
contribution.transactionId = transaction.id
|
|
||||||
await queryRunner.manager.update(DbContribution, { id: contribution.id }, contribution)
|
|
||||||
|
|
||||||
await queryRunner.commitTransaction()
|
|
||||||
logger.info('creation from contribution link commited successfuly.')
|
|
||||||
} catch (e) {
|
|
||||||
await queryRunner.rollbackTransaction()
|
|
||||||
logger.error(`Creation from contribution link was not successful: ${e}`)
|
|
||||||
throw new Error(`Creation from contribution link was not successful. ${e}`)
|
|
||||||
} finally {
|
} finally {
|
||||||
await queryRunner.release()
|
|
||||||
releaseLock()
|
releaseLock()
|
||||||
}
|
}
|
||||||
return true
|
return true
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user