3

I am using the beanstalkd task queue in order to postpone some heavy Doctrine operations, but this can be reproduced in any other similar system like RabbitMQ, etc.

Client (producer) side

$entityManager = $this->getDoctrine()->getManager();

$productEntity = new Product();
$productEntity->setData('somedata');

$entityManager->persist($productEntity);

// This method is blocking, right? The execution will not continue until the 
// data is inserted into the database
$entityManager->flush();


// At this point the data should be already in the database
// $productEntity->getId() returns a valid auto-incremented integer
// So we pass the job to the task queue, which will be executed immediately in the worker
$beanstalkdService->put(
    json_encode([
        'command'=>'some:heavy:task', 
        'product_id' => $productEntity->getId()
    )
);

Worker daemon (long running process on the same server)

$entityManager = $this->getDoctrine()->getManager();
while(true){
    $job = json_decode($beanstalkd->reserve());

    if ($job['command'] === 'some:heavy:task'){
        $productEntity = $entityManager->find('\Path\To\Product, $job['product_id']);
    }
}

the line $entityManager->find('\Path\To\Product, $job['product_id']); returns null if is executed immediately

HOWEVER

if i add a small delay before its execution, like

sleep(1);
$entityManager->find('\Path\To\Product, $job['product_id']);

then the entity is returned as it is supposed to!

Why the record is not accessible without the delay? Isn't the flush() method blocking, so the execution will not continue unless the record is inserted into the database?

Vlad
  • 655
  • 6
  • 12
  • this might be of help: http://docs.doctrine-project.org/en/2.0.x/reference/transactions-and-concurrency.html – Udan Mar 24 '14 at 20:30
  • 1
    This may be as well due to a transaction that wasn't yet committed, or the persistence layer taking too long to actually write the transaction to the drive (which seems odd to me) – Ocramius Aug 18 '14 at 21:55
  • Maybe create postPersist listener for the product and try to "put" the task from there? – Jekis Feb 22 '16 at 09:57

0 Answers0