Skip to content

Commit

Permalink
Merge pull request #7822 from laboro/ticket/BAP-10038_1.9
Browse files Browse the repository at this point in the history
BAP-10038: Email processing create duplicates:
  • Loading branch information
Krushelnitskiy authored Jul 8, 2016
2 parents 70c5232 + 1ba8439 commit b3b8a28
Show file tree
Hide file tree
Showing 5 changed files with 46 additions and 26 deletions.
1 change: 0 additions & 1 deletion src/Oro/Bundle/EmailBundle/Cache/EmailCacheManager.php
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,6 @@ public function ensureEmailBodyCached(Email $email)
{
if ($email->getEmailBody() === null) {
$this->emailBodySynchronizer->syncOneEmailBody($email);
$this->em->flush();
}

$this->eventDispatcher->dispatch(EmailBodyLoaded::NAME, new EmailBodyLoaded($email));
Expand Down
11 changes: 11 additions & 0 deletions src/Oro/Bundle/EmailBundle/Command/Cron/EmailBodySyncCommand.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Input\InputOption;
use Symfony\Component\Console\Output\OutputInterface;
use Symfony\Component\Filesystem\LockHandler;

use Oro\Bundle\CronBundle\Command\CronCommandInterface;
use Oro\Bundle\EmailBundle\Sync\EmailBodySynchronizer;
Expand Down Expand Up @@ -60,9 +61,19 @@ protected function configure()
*/
protected function execute(InputInterface $input, OutputInterface $output)
{
$lock = new LockHandler('oro:cron:email-body-sync');
if (!$lock->lock()) {
$output->writeln('The command is already running in another process.');

return 0;
}
/** @var EmailBodySynchronizer $synchronizer */
$synchronizer = $this->getContainer()->get('oro_email.email_body_synchronizer');
$synchronizer->setLogger(new OutputLogger($output));
$synchronizer->sync((int)$input->getOption('max-exec-time'), (int)$input->getOption('batch-size'));

$lock->release();

return 0;
}
}
45 changes: 29 additions & 16 deletions src/Oro/Bundle/EmailBundle/Sync/EmailBodySynchronizer.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

namespace Oro\Bundle\EmailBundle\Sync;

use Doctrine\Common\Persistence\ObjectManager;
use Doctrine\ORM\EntityManager;

use Psr\Log\LoggerAwareInterface;
use Psr\Log\LoggerAwareTrait;
Expand Down Expand Up @@ -34,7 +34,7 @@ class EmailBodySynchronizer implements LoggerAwareInterface
/** @var array */
protected $emailBodyLoaders = [];

/** @var ObjectManager */
/** @var EntityManager */
protected $manager = null;

/**
Expand All @@ -61,7 +61,7 @@ public function __construct(
*/
public function syncOneEmailBody(Email $email)
{
if ($email->isBodySynced() !== true && $email->getEmailBody() === null) {
if ($this->isBodyNotLoaded($email)) {
// body loader can load email from any folder
// todo: refactor to use correct emailuser and origin
// to use active origin and get correct folder from this origin
Expand All @@ -72,12 +72,20 @@ public function syncOneEmailBody(Email $email)
throw new LoadEmailBodyFailedException($email);
}

$loader = $this->getBodyLoader($origin);
$email->setBodySynced(true);
$emailBody = null;
$loader = $this->getBodyLoader($origin);
$bodyLoaded = false;
try {
$emailBody = $loader->loadEmailBody($folder, $email, $this->getManager());
$email->setEmailBody($emailBody);
$em = $this->getManager();
$emailBody = $loader->loadEmailBody($folder, $email, $em);
$em->refresh($email);
// double check
if ($this->isBodyNotLoaded($email)) {
$email->setEmailBody($emailBody);
$email->setBodySynced(true);
$bodyLoaded = true;
$em->persist($email);
$em->flush($email);
}
} catch (LoadEmailBodyException $loadEx) {
$this->logger->notice(
sprintf('Load email body failed. Email id: %d. Error: %s', $email->getId(), $loadEx->getMessage()),
Expand All @@ -91,10 +99,7 @@ public function syncOneEmailBody(Email $email)
);
throw new LoadEmailBodyFailedException($email, $ex);
}

$this->getManager()->persist($email);

if ($emailBody) {
if ($bodyLoaded) {
$event = new EmailBodyAdded($email);
$this->eventDispatcher->dispatch(EmailBodyAdded::NAME, $event);
}
Expand Down Expand Up @@ -127,7 +132,7 @@ public function sync($maxExecTimeInMin = -1, $batchSize = 10)

$emails = $repo->getEmailsWithoutBody($batchSize);
if (count($emails) === 0) {
$this->logger->notice('All emails was processed');
$this->logger->info('All emails was processed');
break;
}

Expand All @@ -146,8 +151,6 @@ public function sync($maxExecTimeInMin = -1, $batchSize = 10)
continue;
}
}

$this->getManager()->flush();
$this->getManager()->clear();

$currentTime = new \DateTime('now', new \DateTimeZone('UTC'));
Expand All @@ -157,7 +160,7 @@ public function sync($maxExecTimeInMin = -1, $batchSize = 10)
}

/**
* @return ObjectManager
* @return EntityManager
*/
protected function getManager()
{
Expand All @@ -182,4 +185,14 @@ protected function getBodyLoader(EmailOrigin $origin)

return $this->emailBodyLoaders[$originId];
}

/**
* @param Email $email
*
* @return bool
*/
protected function isBodyNotLoaded(Email $email)
{
return $email->isBodySynced() !== true && $email->getEmailBody() === null;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -62,9 +62,6 @@ public function testEnsureEmailBodyCached()
$this->emailBodySynchronizer
->expects($this->once())
->method('syncOneEmailBody');
$this->em
->expects($this->once())
->method('flush');

$this->manager->ensureEmailBodyCached($email);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,7 @@ public function testSyncOneEmailBody()
->will($this->returnValue($emailBody));

$this->em->expects($this->once())
->method('persist')
->method('flush')
->with($this->identicalTo($email));

$this->logger->expects($this->never())
Expand Down Expand Up @@ -218,7 +218,7 @@ public function testSyncOnEmptyData()
$repo->expects($this->once())->method('getEmailsWithoutBody')
->willReturn([]);
$this->logger->expects($this->once())
->method('notice')
->method('info')
->with(
'All emails was processed'
);
Expand Down Expand Up @@ -270,14 +270,14 @@ function () use (&$runCount, $email) {
->will($this->returnValue($emailBody));

$this->em->expects($this->once())
->method('persist')
->method('flush')
->with($this->identicalTo($email));
$this->em->expects($this->once())
->method('flush');
$this->em->expects($this->once())
->method('clear');
$this->logger->expects($this->exactly(2))
$this->logger->expects($this->once())
->method('notice');
$this->logger->expects($this->exactly(2))
->method('info');
$this->logger->expects($this->never())
->method('warning');

Expand Down

0 comments on commit b3b8a28

Please sign in to comment.