Feature #60460

Epic #55070: Workpackages

Epic #55065: WP: Overall System Performance (Backend and Frontend)

Epic #55656: Optimize overall Extbase performance

Story #55168: Optimize Extbase generic persistence

Task #55169: Extbase: fetch child objects in one query

Refactor lazyLoading handling in extbase

Added by Felix Oertel almost 5 years ago. Updated over 1 year ago.

Status:
Closed
Priority:
Could have
Assignee:
Category:
Extbase
Target version:
-
Start date:
2014-07-22
Due date:
% Done:

0%

PHP Version:
Tags:
Complexity:
Sprint Focus:

Description

For quiet some time now I wanted to refactor the lazyLoading handling in extbase.

It stinks, that the lazyLoadingProxy does not extend the actual class, thus fataling when using correct typehints. This leads to developers allways resolving the lazyLoadingProxy which - let's face it - kind of goes against what lazyLoading was intended to do. ;-)

So we need a lazyProxy, which extends the actual class, eliminating the need to ever resolve a lazyProxy if no property is called.


Related issues

Related to TYPO3 Core - Bug #60913: Cannot edit lazy loaded objects Closed 2014-08-12
Related to TYPO3 Core - Task #59917: User Repositories in internal persistence logic Rejected 2014-06-27 2014-07-09

History

#1 Updated by Stefano Kowalke almost 5 years ago

The new implementation introduces a LazyLoadingProxyFactory which generates a LazyProxy object which extends the concrete object. With this way proxy objects will pass type hints.

The implementation in detail:

LazyLoadingProxyFactory

The class can be found at \TYPO3\CMS\Extbase\Persistence\Generic\LazyLoadingProxyFactory. To retrieve a lazy proxy object call the get() method of the class, which expects three parameters:

  1. The classname or object to create the proxy from
  2. The parent object
  3. The property
  4. The value of the field

$this->lazyProxyFactory->getProxy($propertyMetaData['type'], $parentObject, $propertyName, $fieldValue);

The generated proxy class is cached and you will find it at typo3temp/Cache/Code/extbase_lazyproxyobject_storage/*LazyProxy.php

Example

Lets use the blog_example as … well … as an example:

At some point the DataMapper calls $this->lazyProxyFactory->getProxy(…) with this values:
  1. string $className: ExtbaseTeam\BlogExample\Domain\Model\Administrator
  2. object $parentObject: ExtbaseTeam\BlogExample\Domain\Model\Blog
  3. string $propertyName: administrator
  4. string $fieldValue: 351

Here is the code of the generated AdministratorLazyProxy.php:

<?php
namespace ExtbaseTeam\BlogExample\Domain\Model;
use TYPO3\CMS\Extbase\Persistence\QueryResultInterface;

/**
 * This class is generated by the LazyProxyFactory of Extbase. Don't change the file by yourself!
 */
class AdministratorLazyProxy extends \ExtbaseTeam\BlogExample\Domain\Model\Administrator implements \TYPO3\CMS\Extbase\Persistence\Generic\LoadingStrategyInterface {
    private $parentObject;
    private $propertyName;
    private $fieldValue;
    private $parentQueryResult;

    public function __construct($parentObject, $propertyName, $fieldValue) {
        $this->parentObject = $parentObject;
        $this->propertyName = $propertyName;
        $this->fieldValue = $fieldValue;
    }

    public function setUsername($username) {
        $this->parentQueryResult->fetchLazyObjects($this->propertyName);
        return parent::setUsername($username);
    }

    public function getUsername() {
        $this->parentQueryResult->fetchLazyObjects($this->propertyName);
        return parent::getUsername();
    }

    ...

    /**
      * @param QueryResultInterface $queryResult
      *
      * @return void
      */
    public function setParentQueryResult(QueryResultInterface $queryResult) {
        $this->parentQueryResult = $queryResult;
    }

    /**
     * Returns the parentObject so we can populate the proxy.
     *
     * @return object
     */
    public function _getParentObject() {
        return $this->parentObject;
    }

    /**
     * Returns the fieldValue so we can fetch multiple LazyObjects in one query.
     *
     * @return mixed
     */
    public function _getFieldValue() {
        return $this->fieldValue;
    }
}

The proxy class overrides all public methods from his parent with his own variant of the methods. This just just add a call to the methods whereby the proxy is able to resolve himself. At the end it will return the requested value from the concrete object.

#2 Updated by Mathias Brodala almost 5 years ago

Can you push a changeset to Gerrit to get this ball rolling again?

#3 Updated by Felix Oertel almost 5 years ago

Hey Mathias,

sorry, the patch was with me for some polish ... an I was on vacation. ;-) But it's ready now and I am gonna push it today.

#4 Updated by Mathias Schreiber over 4 years ago

  • Target version changed from 7.0 to 7.1 (Cleanup)

#6 Updated by Christian Kuhn almost 4 years ago

the pending patch was abandoned.

#7 Updated by Benni Mack almost 4 years ago

  • Target version changed from 7.1 (Cleanup) to 7.4 (Backend)

#8 Updated by Susanne Moog almost 4 years ago

  • Target version changed from 7.4 (Backend) to 7.5

#9 Updated by Benni Mack over 3 years ago

  • Status changed from Accepted to New
  • Target version deleted (7.5)

#10 Updated by Ernesto Baschny almost 3 years ago

Since this was abandoned, I suspect that this "documentation" is obsolete?

https://wiki.typo3.org/Enhanced_Lazy_Loading

Our developers today stumbled over the update + LazyLoading bug and found this wiki page, and it looks as if it is a "documentation" for a feature which was never released.
Could someone that is aware of it please mark the status of that page accordingly?

Other than that, the idea is still valid, as the issue is still there: developers are currently forced to do if(LazyLoadingProxy) then _loadRealInstance() in different places. Even the core does so (see typo3/sysext/fluid/Classes/ViewHelpers/Form/AbstractFormViewHelper.php).

#11 Updated by Ernesto Baschny almost 3 years ago

I just marked the page as outdated. Thanks!

#12 Updated by Benni Mack over 1 year ago

  • Status changed from New to Closed

we won't do that anymore

Also available in: Atom PDF