1

I have two approaches and I need your expertise on the matter... Let's say we call a certain API and store every request data into RequestEntity. And let's say that API call we made initiates some long-run process on a remote server. So as to have an update of the state of this particular process we have to call every second API and store a response into $logEntries which is ArrayCollection:

class RequestEntity implements PlatformRequestInterface 
{
     ...

     /**
      * @var RequestLogEntity[]|ArrayCollection
      * @ORM\OneToMany(targetEntity=RequestLogEntity::class, fetch="EXTRA_LAZY", 
      *  mappedBy="request")
      */
     protected $logEntries;

     ...

     public function __construct(...) 
     {
          $this->logEntries = [];
     }

     ...

     /**
     * @return RequestLogEntity[]|ArrayCollection
     */
     public function getLogEntries()
     {
         return $this->logEntries;
     }

     ...
}

class RequestLogEntity 
{
    ...
 
   /**
    * @var RequestEntity
    * @ORM\ManyToOne(targetEntity=RequestEntity::class, fetch="EXTRA_LAZY", 
    * inversedBy="logEntries")
    * @ORM\JoinColumn(name="request_id", referencedColumnName="id", nullable=false)
    */
   protected $request;
 
   ...
 
  /**
   * Gets a current request to work with
   *
   * @return RequestEntity
  */
  public function getRequest()
  {
      return $this->request;
  }
 
...
}

Let's assume that we have RequestEntity with ID 42 that has in $logEntities 5 records: enter image description here

So every process on the remote server has its own velocity and some processes can stack for a while in a particular stage which creates an enormous amount of RequestLogEntity records with an identical data since we are calling for an update every second.

So approach 1 is we can just retrieve existed $logEntities in RequestEntity, loop through them(max amount is 10), checking data, and if we've already got a record with a similar data we just update created_at field in a record therefore avoid a necessity to insert a new record every time, creating a huge stack of a similarity:

private function loggingResponseMessageToRequest(
    RequestProgress $progress,
    RequestEntity $request
) {
    foreach ($request->getLogEntries() as $log) {
        if (
            $log->getRequest()->getId() == $progress->getRequestId()
            && $log->getMessage() == $progress->getMessage()
        ) {
            $log->setCreatedAt($progress->getCreatedAt());
            $this->entityManager->persist($log);
            $this->entityManager->flush($log);

            return;
        }
    }
 
...
}

Another approach on the other hand is we can reach out directly for RequestLogEntity using obviously entityManager and search for that particular record in DB. If we do have the one we update created_at and persists() and flush() $requestLogEntity. If we do not have a record we proceed with INSERT procedure further:

 private function loggingResponseMessageToRequest(
    RequestProgress $progress,
    RequestEntity $request
) {
    $requestLogEntity = $this->entityManager->getRepository(RequestLogEntity::class)
        ->findOneBy([
            'request_id' => $progress->getRequestId(), //12345
            'message' => $progress->getMessage() // 'Test1'
        ]);

    if ($requestLogEntity) {
        $requestLogEntity->setCreatedAt($progress->getCreatedAt());
        $this->entityManager->persist();
        $this->entityManager->flush();

        return;
    }

...

So what do you think? What approach has more Symfony way in this particular case and why? Would very much appreciate your honesty! And many thanks in advance...

0 Answers0