fix(medusa): Transaction lock issues on create/update cart items (#2612)

* fix(medusa): Transaction lock issues on create/update cart items

* fix add missing trans

* cleanup

* cleanup

* Create perfect-bears-invent.md

* cleanup

* revert draft order to no take it in that pr

* cleanup handler

* cleanup steps

* fix reference issue

* cleanup + fix tests and mock

* cleanup type

* rename file

* cleanup

* fix missing transaction

* wip

* Address pr feedback

* cleanup and fix unit tests

* fix handler

Co-authored-by: Oliver Windall Juhl <59018053+olivermrbl@users.noreply.github.com>
This commit is contained in:
Adrien de Peretti
2022-11-18 12:15:53 +01:00
committed by GitHub
co-authored by Oliver Windall Juhl
parent 5332081972
commit a77780671a
14 changed files with 310 additions and 117 deletions
@@ -0,0 +1,2 @@
export * from "./run-idempotency-step"
export * from "./initialize-idempotency-request"
@@ -0,0 +1,26 @@
import { Request, Response } from "express"
import { IdempotencyKey } from "../../models"
import IdempotencyKeyService from "../../services/idempotency-key"
import { EntityManager } from "typeorm"
export async function initializeIdempotencyRequest(
req: Request,
res: Response
): Promise<IdempotencyKey> {
const idempotencyKeyService: IdempotencyKeyService = req.scope.resolve(
"idempotencyKeyService"
)
const manager: EntityManager = req.scope.resolve("manager")
const headerKey = req.get("Idempotency-Key") || ""
let idempotencyKey
idempotencyKey = await idempotencyKeyService
.withTransaction(manager)
.initializeRequest(headerKey, req.method, req.params, req.path)
res.setHeader("Access-Control-Expose-Headers", "Idempotency-Key")
res.setHeader("Idempotency-Key", idempotencyKey.idempotency_key)
return idempotencyKey
}
@@ -0,0 +1,40 @@
import { IdempotencyCallbackResult } from "../../types/idempotency-key"
import { EntityManager } from "typeorm"
import { IdempotencyKey } from "../../models"
import { AwilixContainer } from "awilix"
import IdempotencyKeyService from "../../services/idempotency-key"
import { IsolationLevel } from "typeorm/driver/types/IsolationLevel"
export type RunIdempotencyStepOptions = {
manager: EntityManager
idempotencyKey: IdempotencyKey
container: AwilixContainer
isolationLevel: IsolationLevel
}
export async function runIdempotencyStep(
handler: ({ manager: EntityManager }) => Promise<IdempotencyCallbackResult>,
{
manager,
idempotencyKey,
container,
isolationLevel,
}: RunIdempotencyStepOptions
) {
const idempotencyKeyService: IdempotencyKeyService = container.resolve(
"idempotencyKeyService"
)
return await manager.transaction(
isolationLevel,
async (transactionManager) => {
const idempotencyKey_ = await idempotencyKeyService
.withTransaction(transactionManager)
.workStage(idempotencyKey.idempotency_key, async (stageManager) => {
return await handler({ manager: stageManager })
})
idempotencyKey.response_code = idempotencyKey_.response_code
idempotencyKey.response_body = idempotencyKey_.response_body
idempotencyKey.recovery_point = idempotencyKey_.recovery_point
}
)
}