New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
An optimistic locking mechanism for campaigns #13659
base: 5.x
Are you sure you want to change the base?
An optimistic locking mechanism for campaigns #13659
Conversation
Codecov ReportAttention: Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## 5.x #13659 +/- ##
============================================
+ Coverage 61.26% 61.34% +0.07%
- Complexity 33983 34003 +20
============================================
Files 2238 2240 +2
Lines 101593 101660 +67
============================================
+ Hits 62243 62365 +122
+ Misses 39350 39295 -55
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM!
Thanks @fedys!!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Followed the steps and works as described!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This worked fine if I just changed something like the name.
If I opened the builder, and made a change to the campaign, then I got the following 500 error:
500 Internal Server Error - Key "deleted" for array with keys "canvasSettings, name, triggerMode, triggerDate, triggerInterval, triggerIntervalUnit, triggerHour, triggerRestrictedStartHour, triggerRestrictedStopHour, anchor, properties, type, eventType, anchorEventType, campaignId, _token, buttons, settings, triggerRestrictedDaysOfWeek, tempId, id" does not exist.
Stack trace:
[2024-04-25T13:22:03.155371+00:00] mautic.CRITICAL: Uncaught PHP Exception Twig\Error\RuntimeError: "Key "deleted" for array with keys "canvasSettings, name, triggerMode, triggerDate, triggerInterval, triggerIntervalUnit, triggerHour, triggerRestrictedStartHour, triggerRestrictedStopHour, anchor, properties, type, eventType, anchorEventType, campaignId, _token, buttons, settings, triggerRestrictedDaysOfWeek, tempId, id" does not exist." at /var/www/html/app/bundles/CampaignBundle/Resources/views/Campaign/_builder.html.twig line 36 {"exception":"[object] (Twig\\Error\\RuntimeError(code: 0): Key \"deleted\" for array with keys \"canvasSettings, name, triggerMode, triggerDate, triggerInterval, triggerIntervalUnit, triggerHour, triggerRestrictedStartHour, triggerRestrictedStopHour, anchor, properties, type, eventType, anchorEventType, campaignId, _token, buttons, settings, triggerRestrictedDaysOfWeek, tempId, id\" does not exist. at /var/www/html/app/bundles/CampaignBundle/Resources/views/Campaign/_builder.html.twig:36)
[stacktrace]
#0 /var/www/html/vendor/twig/twig/src/Environment.php(360) : eval()'d code(132): twig_get_attribute(Object(Twig\\Environment), Object(Twig\\Source), Array, 'deleted', Array, 'any', false, false, false, 36)
#1 /var/www/html/vendor/twig/twig/src/Template.php(394): __TwigTemplate_b3b345528e9a52da99d56ed8e00e11da->doDisplay(Array, Array)
#2 /var/www/html/vendor/twig/twig/src/Template.php(367): Twig\\Template->displayWithErrorHandling(Array, Array)
#3 /var/www/html/vendor/twig/twig/src/Template.php(379): Twig\\Template->display(Array)
#4 /var/www/html/vendor/twig/twig/src/TemplateWrapper.php(38): Twig\\Template->render(Array)
#5 /var/www/html/vendor/twig/twig/src/Extension/CoreExtension.php(1347): Twig\\TemplateWrapper->render(Array)
#6 /var/www/html/vendor/twig/twig/src/Environment.php(360) : eval()'d code(170): twig_include(Object(Twig\\Environment), Array, '@MauticCampaign...', Array)
#7 /var/www/html/vendor/twig/twig/src/Template.php(171): __TwigTemplate_38a11f0e36529cc48894b46211a2c936->block_content(Array, Array)
#8 /var/www/html/vendor/twig/twig/src/Template.php(243): Twig\\Template->displayBlock('content', Array, Array, true)
#9 /var/www/html/vendor/twig/twig/src/Environment.php(360) : eval()'d code(66): Twig\\Template->renderBlock('content', Array, Array)
#10 /var/www/html/vendor/twig/twig/src/Template.php(394): __TwigTemplate_274f4d32b0e34e384411d368c6082172->doDisplay(Array, Array)
#11 /var/www/html/vendor/twig/twig/src/Template.php(367): Twig\\Template->displayWithErrorHandling(Array, Array)
#12 /var/www/html/vendor/twig/twig/src/Environment.php(360) : eval()'d code(49): Twig\\Template->display(Array, Array)
#13 /var/www/html/vendor/twig/twig/src/Template.php(394): __TwigTemplate_38a11f0e36529cc48894b46211a2c936->doDisplay(Array, Array)
#14 /var/www/html/vendor/twig/twig/src/Template.php(367): Twig\\Template->displayWithErrorHandling(Array, Array)
#15 /var/www/html/vendor/twig/twig/src/Template.php(379): Twig\\Template->display(Array)
#16 /var/www/html/vendor/twig/twig/src/TemplateWrapper.php(38): Twig\\Template->render(Array)
#17 /var/www/html/vendor/twig/twig/src/Environment.php(280): Twig\\TemplateWrapper->render(Array)
#18 /var/www/html/vendor/symfony/framework-bundle/Controller/AbstractController.php(258): Twig\\Environment->render('@MauticCampaign...', Array)
#19 /var/www/html/app/bundles/CoreBundle/Controller/CommonController.php(334): Symfony\\Bundle\\FrameworkBundle\\Controller\\AbstractController->renderView('@MauticCampaign...', Array)
#20 /var/www/html/app/bundles/CoreBundle/Controller/CommonController.php(157): Mautic\\CoreBundle\\Controller\\CommonController->ajaxAction(Object(Symfony\\Component\\HttpFoundation\\Request), Array)
#21 /var/www/html/app/bundles/CoreBundle/Controller/AbstractStandardFormController.php(490): Mautic\\CoreBundle\\Controller\\CommonController->delegateView(Array)
#22 /var/www/html/app/bundles/CampaignBundle/Controller/CampaignController.php(207): Mautic\\CoreBundle\\Controller\\AbstractStandardFormController->editStandard(Object(Symfony\\Component\\HttpFoundation\\Request), '1', false)
#23 /var/www/html/vendor/symfony/http-kernel/HttpKernel.php(163): Mautic\\CampaignBundle\\Controller\\CampaignController->editAction(Object(Symfony\\Component\\HttpFoundation\\Request), '1', false)
#24 /var/www/html/vendor/symfony/http-kernel/HttpKernel.php(75): Symfony\\Component\\HttpKernel\\HttpKernel->handleRaw(Object(Symfony\\Component\\HttpFoundation\\Request), 2)
#25 /var/www/html/vendor/symfony/framework-bundle/Controller/AbstractController.php(156): Symfony\\Component\\HttpKernel\\HttpKernel->handle(Object(Symfony\\Component\\HttpFoundation\\Request), 2)
#26 /var/www/html/app/bundles/CoreBundle/Controller/CommonController.php(415): Symfony\\Bundle\\FrameworkBundle\\Controller\\AbstractController->forward('Mautic\\\\Campaign...', Array, Array)
#27 /var/www/html/vendor/symfony/http-kernel/HttpKernel.php(163): Mautic\\CoreBundle\\Controller\\CommonController->executeAction(Object(Symfony\\Component\\HttpFoundation\\Request), 'edit', '1', 0, '')
#28 /var/www/html/vendor/symfony/http-kernel/HttpKernel.php(75): Symfony\\Component\\HttpKernel\\HttpKernel->handleRaw(Object(Symfony\\Component\\HttpFoundation\\Request), 1)
#29 /var/www/html/vendor/symfony/http-kernel/Kernel.php(202): Symfony\\Component\\HttpKernel\\HttpKernel->handle(Object(Symfony\\Component\\HttpFoundation\\Request), 1, true)
#30 /var/www/html/app/AppKernel.php(109): Symfony\\Component\\HttpKernel\\Kernel->handle(Object(Symfony\\Component\\HttpFoundation\\Request), 1, true)
#31 /var/www/html/app/middlewares/CORSMiddleware.php(76): AppKernel->handle(Object(Symfony\\Component\\HttpFoundation\\Request), 1, true)
#32 /var/www/html/app/middlewares/HSTSMiddleware.php(39): Mautic\\Middleware\\CORSMiddleware->handle(Object(Symfony\\Component\\HttpFoundation\\Request), 1, true)
#33 /var/www/html/app/middlewares/CatchExceptionMiddleware.php(28): Mautic\\Middleware\\HSTSMiddleware->handle(Object(Symfony\\Component\\HttpFoundation\\Request), 1, true)
#34 /var/www/html/app/middlewares/Dev/IpRestrictMiddleware.php(52): Mautic\\Middleware\\CatchExceptionMiddleware->handle(Object(Symfony\\Component\\HttpFoundation\\Request), 1, true)
#35 /var/www/html/app/middlewares/VersionCheckMiddleware.php(58): Mautic\\Middleware\\Dev\\IpRestrictMiddleware->handle(Object(Symfony\\Component\\HttpFoundation\\Request), 1, true)
#36 /var/www/html/app/middlewares/TrustMiddleware.php(42): Mautic\\Middleware\\VersionCheckMiddleware->handle(Object(Symfony\\Component\\HttpFoundation\\Request), 1, true)
#37 /var/www/html/vendor/stack/builder/src/Stack/StackedHttpKernel.php(23): Mautic\\Middleware\\TrustMiddleware->handle(Object(Symfony\\Component\\HttpFoundation\\Request), 1, true)
#38 /var/www/html/index.php(19): Stack\\StackedHttpKernel->handle(Object(Symfony\\Component\\HttpFoundation\\Request))
#39 {main}
"} {"hostname":"mautic-web","pid":11885}
Thanks @RCheesley! I tried to reproduce it in my environment but with no luck. Please can you provide me with the exact steps you took. Screen recording would help a lot. |
Sure thing, here's a screen recording: https://app.screencastify.com/v3/watch/oBWSIOnNIxfozpvu2qJP
|
@RCheesley thanks a ton! I'm able to reproduce it. I will take a look at what is going wrong. |
Description:
This PR adds support for optimistic locking. I tried to implement it via Doctrine functionality. It turned out to be too dangerous as it could cause many bugs (connected with OptimisticLockException). I implemented the optimistic locking the way we can control when an entity version is incremented/checked.
Let's consider the following steps:
-2
for example) and click Apply.-3
for example) and click Apply.Steps to test this PR:
ddev exec bin/console doctrine:migrations:migrate
if needed-2
for example) and click Apply.-3
for example) and click Apply.The record you are updating has been changed by someone else in the meantime. Please refresh the browser window and re-submit your changes.
.