Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

ZF2, Oracle, SlmQueueDoctrine, ClearObjectManagerStrategy is not working

I have a ZF2 project with following configurations. It is using Doctrine ORM and SlmQueue. Since SlmQueue is not supporting our naming conventions and oracle database, we have customized SlmQueueDoctrine.

I suspect my job is not using ClearObjectManagerStrategy and does not clear ObjectManager before execution of individual jobs.

It does not reflect DB modifications after queue started. But it picks new values if I kill queue daemon and start again.

How do I implement ClearObjectManagerStrategy and clear ObjectManager before execution of individual jobs?

I have tried many approached without a luck.

composer.json

{
    "repositories": [
        {
            "url": "https://github.com/pradeep-sanjaya/doctrine-extensions.git",
            "type": "git"
        }
    ],
    "require": {
        "php": ">=5.3.3",
        "zendframework/zendframework": "2.3.3",
        "doctrine/doctrine-orm-module": "0.7.*",
        "pradeep-sanjaya/doctrine-extensions": "dev-master",
        "spoonx/sxmail": "1.4.*",
        "slm/locale": "dev-master",
        "imagine/Imagine": "0.6.*",
        "tecnick.com/tcpdf": "dev-master",
        "slm/queue": "0.4.*",
        "slm/queue-doctrine": "0.4.*"
    }
}

config/autoload/slm_queue.local.php

<?php
return array(
    'slm_queue' => array(
        'queue_manager' => array(
            'factories' => array(
                'doctrineQueue' => 'SlmQueueDoctrine\Factory\DoctrineQueueFactory'
            ),
        ),
        'job_manager' => array(
            'factories' => array(
                'Report\Job\Rank' => 'Report\Job\RankFactory',
            ),
            'shared' => array(
                'Report\Job\Rank' => false
            ),
        ),
        'queues' => array(
            'doctrineQueue' => array(
                'table_name' => 'IOQUEUE'
            )
        )
    )
);
?>

module/Report/src/Report/Job/Rank.php

<?php
namespace Report\Job;

use DoctrineModule\Persistence\ObjectManagerAwareInterface;
use DoctrineModule\Persistence\ProvidesObjectManager as ProvidesObjectManagerTrait;
use SlmQueue\Job\AbstractJob;

use Application\Entity\Report;

use Application\Log\LoggerAwareInterface;
use Application\Log\LoggerAwareTrait;

use Application\Service\ReportService;

class Rank extends AbstractJob implements ObjectManagerAwareInterface, LoggerAwareInterface
{
    use LoggerAwareTrait;
    use ProvidesObjectManagerTrait;

    /**
     * @var ReportService
     */
    protected $reportService;

    /**
     * @var array
     */
    protected $reportId = array();

    public function setReportService(ReportService $reportService)
    {
        $this->reportService = $reportService;
    }

    /**
     * Execute the job
     *
     * @return void
     */
    public function execute()
    {
        //clear object manager does not work
        //$om = $this->getObjectManager();
        //$om->clear();

        $content = $this->getContent();
        $this->setReportId($content['reportId']);

        if (!empty($this->reportId)) {
            try {
                if (is_array($this->reportId)) {
                    foreach ($this->reportId as $reportId) {
                        $this->updateRank($reportId);
                    }
                    unset($reportId);
                } else {
                    $this->updateRank($this->reportId);
                }
            } catch (\Exception $exception) {
                echo "Exception message is {$exception->getMessage()} \n";
            }
        }
    }

    private function updateRank($reportId)
    {
        /* @var $report Report */
        $report = $this->reportService->getReport($reportId);
        $this->logInfo(print_r($report, true)); // this always return older db values, the values before it start queue deamon

        if (!$report instanceof Report) {
            return;
        }

        if (empty($rankData)) {
            return;
        }

        //more codes, application related logics

        $this->reportService->updateReportEntity($report);
    }

    private function setReportId($reportId)
    {
        if (is_numeric($reportId)) {
            $this->reportId = array($reportId);
        } elseif (is_array($reportId)) {
            $this->reportId = $reportId;
        } else {
            throw new \Exception('Expects reportId as int or array');
        }
    }
}
like image 972
Pradeep Sanjaya Avatar asked Dec 01 '15 08:12

Pradeep Sanjaya


1 Answers

If you mean that it doesn't fully clear then apparently this is not a bug, but expected behavior.

You can check the documentation chapter 7.5. for behavior on calling the clear method:

When EntityManager#clear() is invoked, all entities that are currently managed by the EntityManager instance become detached.

In your comment you said "it does not flush object manager's and current transaction". This is not an action you can expect from calling clear. Detach results in the following actions according to the documentation:

The semantics of the detach operation, applied to an entity X are as follows:

  • If X is a managed entity, the detach operation causes it to become detached. The detach operation is cascaded to entities referenced by X, if the relationships from X to these other entities is mapped with cascade=DETACH or cascade=ALL (see “Transitive Persistence”). Entities which previously referenced X will continue to reference X.
  • If X is a new or detached entity, it is ignored by the detach operation.
  • If X is a removed entity, the detach operation is cascaded to entities referenced by X, if the relationships from X to these other entities is mapped with cascade=DETACH or cascade=ALL (see “Transitive Persistence”). Entities which previously referenced X will continue to reference X.
like image 126
Wilt Avatar answered Sep 22 '22 02:09

Wilt