From 852a374b9302c49bf702e745d03d787495d6909f Mon Sep 17 00:00:00 2001 From: Dominik Pfaffenbauer Date: Thu, 27 Apr 2023 13:37:13 +0200 Subject: [PATCH 1/3] [Core] fixes for high load systems --- .../OrderBundle/Manager/CartManager.php | 16 +++-- .../OrderBundle/Resources/config/services.yml | 3 + .../EventListener/SessionSubscriber.php | 2 +- .../WorkflowBundle/History/HistoryLogger.php | 2 +- .../History/StateHistoryLogger.php | 2 +- .../Core/Order/Committer/OrderCommitter.php | 14 ++-- .../Component/Order/Factory/OrderFactory.php | 4 ++ .../StorageListPimcoreModelManager.php | 70 +++++++++---------- 8 files changed, 63 insertions(+), 50 deletions(-) diff --git a/src/CoreShop/Bundle/OrderBundle/Manager/CartManager.php b/src/CoreShop/Bundle/OrderBundle/Manager/CartManager.php index ba46cf6acc..1f4c0178f2 100644 --- a/src/CoreShop/Bundle/OrderBundle/Manager/CartManager.php +++ b/src/CoreShop/Bundle/OrderBundle/Manager/CartManager.php @@ -46,7 +46,7 @@ public function persist(StorageListInterface $storageList): void public function persistCart(OrderInterface $cart): void { $cartsFolder = $this->folderCreationService->createFolderForResource($cart, [ - 'suffix' => date('Y/m/d'), + 'suffix' => date('Y/m/d') . '/' . $cart->getToken(), 'path' => 'cart', ]); @@ -72,12 +72,14 @@ public function persistCart(OrderInterface $cart): void * @var OrderItemInterface $item */ foreach ($items as $index => $item) { - $item->setParent( - $this->folderCreationService->createFolderForResource( - $item, - ['prefix' => $cart->getFullPath()], - ), - ); + if (!$item->getParent()) { + $item->setParent( + $this->folderCreationService->createFolderForResource( + $item, + ['prefix' => $cartsFolder->getFullPath()], + ), + ); + } //$item->setPath($cart->getFullPath()); $item->setPublished(true); $item->setKey((string)((int)$index + 1)); diff --git a/src/CoreShop/Bundle/OrderBundle/Resources/config/services.yml b/src/CoreShop/Bundle/OrderBundle/Resources/config/services.yml index b2a05b0dce..d796ae5530 100644 --- a/src/CoreShop/Bundle/OrderBundle/Resources/config/services.yml +++ b/src/CoreShop/Bundle/OrderBundle/Resources/config/services.yml @@ -106,12 +106,15 @@ services: arguments: - '@CoreShop\Component\Order\Factory\OrderItemFactory.inner' + CoreShop\Component\Resource\TokenGenerator\UniqueTokenGenerator: ~ + CoreShop\Component\Order\Factory\OrderFactory: decorates: coreshop.factory.order decoration_priority: 256 public: false arguments: - '@CoreShop\Component\Order\Factory\OrderFactory.inner' + - '@CoreShop\Component\Resource\TokenGenerator\UniqueTokenGenerator' CoreShop\Bundle\OrderBundle\Factory\AddToCartFactoryInterface: '@CoreShop\Bundle\OrderBundle\Factory\AddToCartFactory' CoreShop\Bundle\OrderBundle\Factory\AddToCartFactory: diff --git a/src/CoreShop/Bundle/StorageListBundle/EventListener/SessionSubscriber.php b/src/CoreShop/Bundle/StorageListBundle/EventListener/SessionSubscriber.php index 93c8039970..19fc1eea49 100644 --- a/src/CoreShop/Bundle/StorageListBundle/EventListener/SessionSubscriber.php +++ b/src/CoreShop/Bundle/StorageListBundle/EventListener/SessionSubscriber.php @@ -69,7 +69,7 @@ public function onKernelResponse(ResponseEvent $event): void return; } - if (0 !== $list->getId()) { + if (null !== $list->getId()) { $session = $request->getSession(); $session->set( diff --git a/src/CoreShop/Bundle/WorkflowBundle/History/HistoryLogger.php b/src/CoreShop/Bundle/WorkflowBundle/History/HistoryLogger.php index 043315e9d5..2aa8f6e789 100644 --- a/src/CoreShop/Bundle/WorkflowBundle/History/HistoryLogger.php +++ b/src/CoreShop/Bundle/WorkflowBundle/History/HistoryLogger.php @@ -57,6 +57,6 @@ public function log( $note->setDescription($description); } - $this->noteService->storeNote($note); + //$this->noteService->storeNote($note); } } diff --git a/src/CoreShop/Bundle/WorkflowBundle/History/StateHistoryLogger.php b/src/CoreShop/Bundle/WorkflowBundle/History/StateHistoryLogger.php index 5453db1234..5cc3976721 100644 --- a/src/CoreShop/Bundle/WorkflowBundle/History/StateHistoryLogger.php +++ b/src/CoreShop/Bundle/WorkflowBundle/History/StateHistoryLogger.php @@ -60,7 +60,7 @@ public function log(Concrete $object, Event $event): void $note->addData('workflow', 'text', $event->getWorkflowName()); $note->addData('transition', 'text', $transition->getName()); - $this->noteService->storeNote($note); + //$this->noteService->storeNote($note); } private function getFrom(array $froms) diff --git a/src/CoreShop/Component/Core/Order/Committer/OrderCommitter.php b/src/CoreShop/Component/Core/Order/Committer/OrderCommitter.php index be30fd315c..9737dc6bc5 100644 --- a/src/CoreShop/Component/Core/Order/Committer/OrderCommitter.php +++ b/src/CoreShop/Component/Core/Order/Committer/OrderCommitter.php @@ -57,12 +57,21 @@ public function commitOrder(OrderInterface $order): void Assert::isInstanceOf($order, \CoreShop\Component\Core\Model\OrderInterface::class); $orderFolder = $this->folderCreationService->createFolderForResource($order, [ - 'suffix' => date('Y/m/d'), + 'suffix' => date('Y/m/d') . '/' . $order->getToken(), 'path' => 'order', ]); $orderNumber = $this->numberGenerator->generate($order); $order->setParent($orderFolder); + + foreach ($order->getItems() as $item) { + $item->setParent($this->folderCreationService->createFolderForResource( + $item, + ['prefix' => $orderFolder->getFullPath()], + ) + ); + } + $order->setSaleState(OrderSaleStates::STATE_ORDER); $order->setOrderDate(Carbon::now()); $order->setOrderNumber($orderNumber); @@ -72,9 +81,6 @@ public function commitOrder(OrderInterface $order): void $order->setPaymentState(OrderPaymentStates::STATE_NEW); $order->setInvoiceState(OrderInvoiceStates::STATE_NEW); - $tokenGenerator = new UniqueTokenGenerator(); - $order->setToken($tokenGenerator->generate(10)); - $this->cartManager->persistCart($order); $originalShippingAddress = $order->hasShippableItems() === false ? $order->getInvoiceAddress() : $order->getShippingAddress(); diff --git a/src/CoreShop/Component/Order/Factory/OrderFactory.php b/src/CoreShop/Component/Order/Factory/OrderFactory.php index ba01355f56..d6f7e6a188 100644 --- a/src/CoreShop/Component/Order/Factory/OrderFactory.php +++ b/src/CoreShop/Component/Order/Factory/OrderFactory.php @@ -19,11 +19,14 @@ namespace CoreShop\Component\Order\Factory; use CoreShop\Component\Resource\Factory\FactoryInterface; +use CoreShop\Component\Resource\TokenGenerator\UniqueTokenGenerator; class OrderFactory implements FactoryInterface { public function __construct( private FactoryInterface $cartFactory, + private UniqueTokenGenerator $tokenGenerator, + private int $tokenLength = 10 ) { } @@ -32,6 +35,7 @@ public function createNew() $cart = $this->cartFactory->createNew(); $cart->setKey(uniqid('cart', true)); $cart->setPublished(true); + $cart->setToken($this->tokenGenerator->generate($this->tokenLength)); return $cart; } diff --git a/src/CoreShop/Component/StorageList/Manager/StorageListPimcoreModelManager.php b/src/CoreShop/Component/StorageList/Manager/StorageListPimcoreModelManager.php index 9f4663e756..8c637af163 100644 --- a/src/CoreShop/Component/StorageList/Manager/StorageListPimcoreModelManager.php +++ b/src/CoreShop/Component/StorageList/Manager/StorageListPimcoreModelManager.php @@ -44,49 +44,47 @@ public function persist(StorageListInterface $storageList): void 'path' => 'storage-list', ]); - $this->connection->transactional(function () use ($storageList, $folder) { - VersionHelper::useVersioning(function () use ($storageList, $folder) { - $tempItems = $storageList->getItems(); + VersionHelper::useVersioning(function () use ($storageList, $folder) { + $tempItems = $storageList->getItems(); - if (!$storageList->getId()) { - $storageList->setItems([]); - - /** - * @psalm-suppress DocblockTypeContradiction - */ - if (!$storageList->getParent()) { - $storageList->setParent($folder); - } - - $storageList->save(); - } + if (!$storageList->getId()) { + $storageList->setItems([]); /** - * @var AbstractPimcoreModel $item + * @psalm-suppress DocblockTypeContradiction */ - foreach ($tempItems as $index => $item) { - $item->setParent( - $this->folderCreationService->createFolderForResource( - $item, - ['prefix' => $storageList->getFullPath()], - ), - ); - $item->setPublished(true); - $item->setKey($index + 1); - $item->save(); + if (!$storageList->getParent()) { + $storageList->setParent($folder); } - $storageList->setItems($tempItems); + $storageList->save(); + } - /** - * @var AbstractPimcoreModel $storageListItem - */ - foreach ($storageList->getItems() as $storageListItem) { - $storageListItem->save(); - } + /** + * @var AbstractPimcoreModel $item + */ + foreach ($tempItems as $index => $item) { + $item->setParent( + $this->folderCreationService->createFolderForResource( + $item, + ['prefix' => $storageList->getFullPath()], + ), + ); + $item->setPublished(true); + $item->setKey($index + 1); + $item->save(); + } - $storageList->save(); - }, false); - }); + $storageList->setItems($tempItems); + + /** + * @var AbstractPimcoreModel $storageListItem + */ + foreach ($storageList->getItems() as $storageListItem) { + $storageListItem->save(); + } + + $storageList->save(); + }, false); } } From 746b42df06a93e702352add429236044ce7a8753 Mon Sep 17 00:00:00 2001 From: Dominik Pfaffenbauer Date: Fri, 28 Apr 2023 08:30:43 +0200 Subject: [PATCH 2/3] [Core] fixes for high load systems - locking the sequence --- .../Bundle/OrderBundle/Manager/CartManager.php | 16 +++++++--------- .../Doctrine/ORM/SequenceRepository.php | 2 ++ .../Core/Order/Committer/OrderCommitter.php | 11 +---------- .../Sequence/Generator/SequenceGenerator.php | 4 +++- 4 files changed, 13 insertions(+), 20 deletions(-) diff --git a/src/CoreShop/Bundle/OrderBundle/Manager/CartManager.php b/src/CoreShop/Bundle/OrderBundle/Manager/CartManager.php index 1f4c0178f2..ba46cf6acc 100644 --- a/src/CoreShop/Bundle/OrderBundle/Manager/CartManager.php +++ b/src/CoreShop/Bundle/OrderBundle/Manager/CartManager.php @@ -46,7 +46,7 @@ public function persist(StorageListInterface $storageList): void public function persistCart(OrderInterface $cart): void { $cartsFolder = $this->folderCreationService->createFolderForResource($cart, [ - 'suffix' => date('Y/m/d') . '/' . $cart->getToken(), + 'suffix' => date('Y/m/d'), 'path' => 'cart', ]); @@ -72,14 +72,12 @@ public function persistCart(OrderInterface $cart): void * @var OrderItemInterface $item */ foreach ($items as $index => $item) { - if (!$item->getParent()) { - $item->setParent( - $this->folderCreationService->createFolderForResource( - $item, - ['prefix' => $cartsFolder->getFullPath()], - ), - ); - } + $item->setParent( + $this->folderCreationService->createFolderForResource( + $item, + ['prefix' => $cart->getFullPath()], + ), + ); //$item->setPath($cart->getFullPath()); $item->setPublished(true); $item->setKey((string)((int)$index + 1)); diff --git a/src/CoreShop/Bundle/SequenceBundle/Doctrine/ORM/SequenceRepository.php b/src/CoreShop/Bundle/SequenceBundle/Doctrine/ORM/SequenceRepository.php index 407cfb694c..7a82edeef5 100644 --- a/src/CoreShop/Bundle/SequenceBundle/Doctrine/ORM/SequenceRepository.php +++ b/src/CoreShop/Bundle/SequenceBundle/Doctrine/ORM/SequenceRepository.php @@ -21,6 +21,7 @@ use CoreShop\Bundle\ResourceBundle\Doctrine\ORM\EntityRepository; use CoreShop\Component\Sequence\Model\SequenceInterface; use CoreShop\Component\Sequence\Repository\SequenceRepositoryInterface; +use Doctrine\DBAL\LockMode; class SequenceRepository extends EntityRepository implements SequenceRepositoryInterface { @@ -30,6 +31,7 @@ public function findForType(string $type): ?SequenceInterface ->andWhere('o.type = :type') ->setParameter('type', $type) ->getQuery() + ->setLockMode(LockMode::PESSIMISTIC_WRITE) ->getOneOrNullResult() ; } diff --git a/src/CoreShop/Component/Core/Order/Committer/OrderCommitter.php b/src/CoreShop/Component/Core/Order/Committer/OrderCommitter.php index 9737dc6bc5..473bef7d1d 100644 --- a/src/CoreShop/Component/Core/Order/Committer/OrderCommitter.php +++ b/src/CoreShop/Component/Core/Order/Committer/OrderCommitter.php @@ -57,21 +57,12 @@ public function commitOrder(OrderInterface $order): void Assert::isInstanceOf($order, \CoreShop\Component\Core\Model\OrderInterface::class); $orderFolder = $this->folderCreationService->createFolderForResource($order, [ - 'suffix' => date('Y/m/d') . '/' . $order->getToken(), + 'suffix' => date('Y/m/d'), 'path' => 'order', ]); $orderNumber = $this->numberGenerator->generate($order); $order->setParent($orderFolder); - - foreach ($order->getItems() as $item) { - $item->setParent($this->folderCreationService->createFolderForResource( - $item, - ['prefix' => $orderFolder->getFullPath()], - ) - ); - } - $order->setSaleState(OrderSaleStates::STATE_ORDER); $order->setOrderDate(Carbon::now()); $order->setOrderNumber($orderNumber); diff --git a/src/CoreShop/Component/Sequence/Generator/SequenceGenerator.php b/src/CoreShop/Component/Sequence/Generator/SequenceGenerator.php index 494c5886a2..6e0ab853b9 100644 --- a/src/CoreShop/Component/Sequence/Generator/SequenceGenerator.php +++ b/src/CoreShop/Component/Sequence/Generator/SequenceGenerator.php @@ -34,11 +34,13 @@ public function __construct( public function getNextSequenceForType(string $type): int { + $this->entityManager->beginTransaction(); + $sequence = $this->getSequence($type); $sequence->incrementIndex(); - $this->entityManager->persist($sequence); $this->entityManager->flush(); + $this->entityManager->commit(); return $sequence->getIndex(); } From 09e44e0898c166467c9e766ab958cf3e4b6817f7 Mon Sep 17 00:00:00 2001 From: Dominik Pfaffenbauer Date: Sun, 30 Apr 2023 20:46:33 +0200 Subject: [PATCH 3/3] [Core] fixes for high load systems - re-enabled history and state logger --- src/CoreShop/Bundle/WorkflowBundle/History/HistoryLogger.php | 2 +- .../Bundle/WorkflowBundle/History/StateHistoryLogger.php | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/CoreShop/Bundle/WorkflowBundle/History/HistoryLogger.php b/src/CoreShop/Bundle/WorkflowBundle/History/HistoryLogger.php index 2aa8f6e789..043315e9d5 100644 --- a/src/CoreShop/Bundle/WorkflowBundle/History/HistoryLogger.php +++ b/src/CoreShop/Bundle/WorkflowBundle/History/HistoryLogger.php @@ -57,6 +57,6 @@ public function log( $note->setDescription($description); } - //$this->noteService->storeNote($note); + $this->noteService->storeNote($note); } } diff --git a/src/CoreShop/Bundle/WorkflowBundle/History/StateHistoryLogger.php b/src/CoreShop/Bundle/WorkflowBundle/History/StateHistoryLogger.php index 5cc3976721..5453db1234 100644 --- a/src/CoreShop/Bundle/WorkflowBundle/History/StateHistoryLogger.php +++ b/src/CoreShop/Bundle/WorkflowBundle/History/StateHistoryLogger.php @@ -60,7 +60,7 @@ public function log(Concrete $object, Event $event): void $note->addData('workflow', 'text', $event->getWorkflowName()); $note->addData('transition', 'text', $transition->getName()); - //$this->noteService->storeNote($note); + $this->noteService->storeNote($note); } private function getFrom(array $froms)