Search code examples
phpsymfonywebsocketdoctrineratchet

php websocket ratchet doesn't fetch newest data from doctrine


Quite fascinating fact I just found out while messing up with WebSocket application I am now building using Symfony 4.1 and https://github.com/GeniusesOfSymfony/WebSocketBundle (which is built upon PHP Ratchet).

I wanted to fetch the newest data periodically from the MySQL database for testing purpose using $repository->find(2); but it always returned the same result even though I was changing data while being subscribed to the WebSocket channel.

After quite a lot of hours of messing with the code and crying, I found out that for some reason Doctrine is caching results (or that is what I think it does).

To test my theory, I created a service that handles fetching from the database with the following code:

/**
 * @return mixed
 * @throws \Doctrine\DBAL\DBALException
 */
public function fetchNewest()
{
    $stmt = $this->em->getConnection()->prepare('SELECT * FROM test WHERE id=2');
    $stmt->execute();

    return $stmt->fetch();
}

and for some reason, this has worked. Can anyone explain why find(2) method did not result with the newest data while the raw SQL did?


Solution

  • This is correct, and expected behaviour by an ORM. This is a way to lighten the load on the database.

    It is well documented, but most of the time we just skip to the examples and miss it. :)

    You would normally not notice this in an application, because of the PHP lifecycle. A request comes in, a response goes out, and everything, shuts down. The next request starts with a clean slate.

    If you use a websocket, this never happens, PHP just runs forever (not really, but ideally), and ratchet responds to events.

    (OFF: Check out PHP-PM... they have been able to reach a drastic increase in request / s because they subverted the PHP lifecycle).

    Lock mode is a solution, but you could also call $em->refresh($entity), which triggers a reload from db.

    EDIT: docs https://www.doctrine-project.org/projects/doctrine-orm/en/2.6/reference/working-with-objects.html#entities-and-the-identity-map