Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Suggestion: Move caching of source models into AbstractSource #20068

Open
schmengler opened this issue Jan 4, 2019 · 9 comments
Open

Suggestion: Move caching of source models into AbstractSource #20068

schmengler opened this issue Jan 4, 2019 · 9 comments
Labels
Component: Eav help wanted Issue: Confirmed Gate 3 Passed. Manual verification of the issue completed. Issue is confirmed Priority: P3 May be fixed according to the position in the backlog. Progress: ready for dev Reproduced on 2.2.x The issue has been reproduced on latest 2.2 release Reproduced on 2.3.x The issue has been reproduced on latest 2.3 release Severity: S3 Affects non-critical data or functionality and does not force users to employ a workaround.

Comments

@schmengler
Copy link
Contributor

Summary (*)

The EAV source model base class \Magento\Eav\Model\Entity\Attribute\Source\AbstractSource contains a protected attribute $_options that is meant to cache the options. Unfortunately this is not enforced, instead each implementation of getAllOptions() is responsible to use that cache properly.

EAV source models often load possible values for attributes from external resources. Every access to those values, e.g. with $product->getAttributeText() calls getAllOptions() on the source model. So it makes sense that the result of this method should only be calculated once. As far as I see, all core source models already do this, using $_options, but it is easy to miss in custom implementations, which can have significant performance impact.

Examples (*)

A typical "correct" implementation of getAllOptions():

    public function getAllOptions()
    {
        if (empty($this->_options)) {
            $materials = $this->materialRepository->getList($this->searchCriteriaBuilder->create())->getItems();
            foreach ($materials as $material) {
                $this->_options[] = ['value' => $material->getId(), 'label' => $material->getTitle()];
            }
        }
        return $this->_options;
    }

A typical problematic implementation:

    public function getAllOptions()
    {
        $options = [];
        $materials = $this->materialRepository->getList($this->searchCriteriaBuilder->create())->getItems();
        foreach ($materials as $material) {
            $options[] = ['value' => $material->getId(), 'label' => $material->getTitle()];
        }
        return $options;
    }

Proposed solution

Move caching as default behavior into AbstractSource:

    public function getAllOptions()
    {
        if (empty($this->_options)) {
            $this->_options = $this->loadOptions();
        }
        return $this->_options;
    }
    abstract protected function loadOptions() : array;

Implementations then override loadOptions() instead of getAllOptions(). The core source models should lead by example.

BC considerations

To maintain backwards compatibility, loadOptions() can be optional instead:

    protected function loadOptions() : array
    {
        return [];
    }

This way existing implementations, that override getAllOptions() still work.

@magento-engcom-team magento-engcom-team added the Issue: Format is valid Gate 1 Passed. Automatic verification of issue format passed label Jan 4, 2019
@magento-engcom-team
Copy link
Contributor

Hi @schmengler. Thank you for your report.
To help us process this issue please make sure that you provided the following information:

  • Summary of the issue
  • Information on your environment
  • Steps to reproduce
  • Expected and actual results

Please make sure that the issue is reproducible on the vanilla Magento instance following Steps to reproduce. To deploy vanilla Magento instance on our environment, please, add a comment to the issue:

@magento-engcom-team give me $VERSION instance

where $VERSION is version tags (starting from 2.2.0+) or develop branches (for example: 2.3-develop).
For more details, please, review the Magento Contributor Assistant documentation.

@schmengler do you confirm that you was able to reproduce the issue on vanilla Magento instance following steps to reproduce?

  • yes
  • no

@ghost ghost self-assigned this Jan 4, 2019
@magento-engcom-team
Copy link
Contributor

magento-engcom-team commented Jan 4, 2019

Hi @engcom-backlog-nazar. Thank you for working on this issue.
In order to make sure that issue has enough information and ready for development, please read and check the following instruction: 👇

  • 1. Verify that issue has all the required information. (Preconditions, Steps to reproduce, Expected result, Actual result).

    DetailsIf the issue has a valid description, the label Issue: Format is valid will be added to the issue automatically. Please, edit issue description if needed, until label Issue: Format is valid appears.

  • 2. Verify that issue has a meaningful description and provides enough information to reproduce the issue. If the report is valid, add Issue: Clear Description label to the issue by yourself.

  • 3. Add Component: XXXXX label(s) to the ticket, indicating the components it may be related to.

  • 4. Verify that the issue is reproducible on 2.3-develop branch

    Details- Add the comment @magento-engcom-team give me 2.3-develop instance to deploy test instance on Magento infrastructure.
    - If the issue is reproducible on 2.3-develop branch, please, add the label Reproduced on 2.3.x.
    - If the issue is not reproducible, add your comment that issue is not reproducible and close the issue and stop verification process here!

  • 5. Verify that the issue is reproducible on 2.2-develop branch.

    Details- Add the comment @magento-engcom-team give me 2.2-develop instance to deploy test instance on Magento infrastructure.
    - If the issue is reproducible on 2.2-develop branch, please add the label Reproduced on 2.2.x

  • 6. Add label Issue: Confirmed once verification is complete.

  • 7. Make sure that automatic system confirms that report has been added to the backlog.

@ghost ghost added Issue: Clear Description Gate 2 Passed. Manual verification of the issue description passed Component: Eav Reproduced on 2.3.x The issue has been reproduced on latest 2.3 release Issue: Confirmed Gate 3 Passed. Manual verification of the issue completed. Issue is confirmed labels Jan 4, 2019
@magento-engcom-team magento-engcom-team added the Issue: Ready for Work Gate 4. Acknowledged. Issue is added to backlog and ready for development label Jan 4, 2019
@magento-engcom-team
Copy link
Contributor

@engcom-backlog-nazar Thank you for verifying the issue. Based on the provided information internal tickets MAGETWO-97437 were created

@ghost ghost added help wanted and removed Issue: Ready for Work Gate 4. Acknowledged. Issue is added to backlog and ready for development labels Jan 4, 2019
@ghost ghost removed their assignment Jan 4, 2019
@davidverholen davidverholen self-assigned this Jan 5, 2019
@magento-engcom-team
Copy link
Contributor

Hi @davidverholen. Thank you for working on this issue.
Looks like this issue is already verified and confirmed. But if your want to validate it one more time, please, go though the following instruction:

  • 1. Add/Edit Component: XXXXX label(s) to the ticket, indicating the components it may be related to.

  • 2. Verify that the issue is reproducible on 2.3-develop branch

    Details- Add the comment @magento-engcom-team give me 2.3-develop instance to deploy test instance on Magento infrastructure.
    - If the issue is reproducible on 2.3-develop branch, please, add the label Reproduced on 2.3.x.
    - If the issue is not reproducible, add your comment that issue is not reproducible and close the issue and stop verification process here!

  • 3. Verify that the issue is reproducible on 2.2-develop branch.

    Details- Add the comment @magento-engcom-team give me 2.2-develop instance to deploy test instance on Magento infrastructure.
    - If the issue is reproducible on 2.2-develop branch, please add the label Reproduced on 2.2.x

  • 4. If the issue is not relevant or is not reproducible any more, feel free to close it.

@davidverholen davidverholen added the Progress: PR Created Indicates that Pull Request has been created to fix issue label Jan 5, 2019
@davidverholen davidverholen removed their assignment Jan 5, 2019
@davidverholen davidverholen added the Reproduced on 2.2.x The issue has been reproduced on latest 2.2 release label Jan 5, 2019
davidverholen added a commit to davidverholen/magento2 that referenced this issue Feb 14, 2019
@ghost ghost assigned davidverholen Mar 28, 2019
@ghost ghost unassigned davidverholen Apr 15, 2019
@magento-engcom-team magento-engcom-team added this to Ready for Dev in Community Backlog Mar 24, 2020
@sidolov sidolov added this to Ready for Grooming in Low Priority Backlog Sep 3, 2020
@m2-community-project m2-community-project bot removed Progress: PR Created Indicates that Pull Request has been created to fix issue Progress: ready for dev labels Sep 3, 2020
@sidolov sidolov added this to Ready for Development in Low Priority Backlog Sep 24, 2020
@ghost ghost removed this from Ready for Dev in Community Backlog Oct 20, 2020
@ghost ghost removed this from Ready for Development in Low Priority Backlog Oct 20, 2020
@ghost ghost removed Issue: Clear Description Gate 2 Passed. Manual verification of the issue description passed Issue: Format is valid Gate 1 Passed. Automatic verification of issue format passed labels Oct 20, 2020
@magento-engcom-team magento-engcom-team added Priority: P3 May be fixed according to the position in the backlog. Severity: S3 Affects non-critical data or functionality and does not force users to employ a workaround. labels Nov 30, 2020
@m2-community-project m2-community-project bot added this to Ready for Development in Low Priority Backlog Nov 30, 2020
@stale
Copy link

stale bot commented Feb 15, 2021

This issue has been automatically marked as stale because it has not had recent activity. It will be closed after 14 days if no further activity occurs. Is this issue still relevant? If so, what is blocking it? Is there anything you can do to help move it forward? Thank you for your contributions!

@stale stale bot added the stale issue label Feb 15, 2021
@schmengler
Copy link
Contributor Author

Well, the core team decided against it (see #20087 (review)). It is still relevant because carelessly written extensions easily bring down performance in product exports.

It would be easy and helpful to prevent those developer errors.

@stale stale bot removed the stale issue label Feb 15, 2021
@atrandafir
Copy link

What if someone uses the options list programatically and doesn't want to cache it?

I mean, I'm writing a custom import script.

And while looping products in the CSV, if some attribute value is missing, I create it.

Problem is that if I try to get the "fresh" list of options of that attribute to get the id of the new created value.. well, I can't, cause I get the old cached list.

I might end up doing it with SQL queries instead..

Here's the code that I'm using:

function createMissingGrappeTypeValue($attribute_value) {
  global $grappeTypeAttributeInfo, $eavSetup;
  
  $attribute_arr = [$attribute_value];
  
  $option=array();
  $option['attribute_id'] = $grappeTypeAttributeInfo->getAttributeId();
  foreach($attribute_arr as $key=>$value){
      $option['value'][$value][0]=$value;
      $storeId=0;
      $option['value'][$value][$storeId] = $value;
  }
  
  $eavSetup->addAttributeOption($option);
}

function getAttributeValues($attribute_name) {
  global $eavAttribute;
  $attr = $eavAttribute->get(\Magento\Catalog\Model\Product::ENTITY, $attribute_name);
  $allOptions = $attr->getSource()->getAllOptions(false);
  $result=array();
  foreach ($allOptions as $allOption) {
    $result[$allOption['value']]=$allOption['label'];
  }
  return $result;
}

@stale
Copy link

stale bot commented May 19, 2021

This issue has been automatically marked as stale because it has not had recent activity. It will be closed after 14 days if no further activity occurs. Is this issue still relevant? If so, what is blocking it? Is there anything you can do to help move it forward? Thank you for your contributions!

@stale stale bot added the stale issue label May 19, 2021
@schmengler
Copy link
Contributor Author

@atrandafir

What if someone uses the options list programatically and doesn't want to cache it?

You already have this problem with all existing implementations that follow best practice and do cache the options. If you explicitly need it uncached, you can always create a new instance of the source model to have an empty $_options cache.

@stale stale bot removed the stale issue label May 19, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Component: Eav help wanted Issue: Confirmed Gate 3 Passed. Manual verification of the issue completed. Issue is confirmed Priority: P3 May be fixed according to the position in the backlog. Progress: ready for dev Reproduced on 2.2.x The issue has been reproduced on latest 2.2 release Reproduced on 2.3.x The issue has been reproduced on latest 2.3 release Severity: S3 Affects non-critical data or functionality and does not force users to employ a workaround.
Projects
Low Priority Backlog
  
Ready for Development
Development

No branches or pull requests

5 participants