Closed (fixed)
Project:
Entity reference
Version:
7.x-1.x-dev
Component:
Code
Priority:
Normal
Category:
Bug report
Assigned:
Unassigned
Issue tags:
Reporter:
Created:
17 Mar 2023 at 16:55 UTC
Updated:
14 Apr 2023 at 16:46 UTC
Jump to comment: Most recent, Most recent file
Comments
Comment #2
joelpittetThese are related I believe and depending on how the maintainers decide to deal with it, they may deal with the problem here or there.
#2151631: Improve performance of getReferencableEntities(). I won't close this as a duplicate yet, but probably should close it if the other gets committed as a revert or partial revert.
Generally new issue per problem, so maybe committing it over here is better?
Comment #3
joelpittetComment #4
joseph.olstadTry this patch
Comment #5
joseph.olstadComment #6
joseph.olstadalternatively, try this patch
patch 4 should work.
This one might also resolve the issue.
Comment #7
joelpittet@joseph.olstad I'm not a fan of the try catch approach because you're passing in the wrong data type as
$entityon purpose but it also suffers from the same problem as mentioned to @franceslui here#2151631-48: Improve performance of getReferencableEntities()
And #6 is a bit better although
list($id,, $bundle) = entity_extract_ids($target_type, $entity);will suffer the same fate if the resulting entity_load does an access check and notices you aren't allowed to load that entity.Comment #8
joelpittetMinor nitpick for #6 as I've seen you do this in other patches I might as well mention it.
empty()does an implicitisset(), so you don't need both.if (!isset($entity->{$info['entity keys']['bundle']}) || $entity->{$info['entity keys']['bundle']} === '') {becomes
if (empty($entity->{$info['entity keys']['bundle']})) {Though I'm still in favor of @franceslui's patch (with a check for a returned entity after access checks have run) #2151631-37: Improve performance of getReferencableEntities()
Comment #9
joseph.olstad@joelpittet, Did the patch #6 resolve the issue for you? I used the verbatim exact condition that core does in entity_extract
that line is straight from core here:
https://api.drupal.org/api/drupal/includes%21common.inc/function/entity_...
it should prevent the exception.
Comment #10
joseph.olstad@joelpittet, re: patch #6.
I believe core does this due to the faster performance of isset.
I merely copied what core did verbatim.
(from here: https://api.drupal.org/api/drupal/includes%21common.inc/function/entity_...)
In fact, you were behind some related micro optimizations
#2770065: array_key_exists() micro-optimization
the reasoning behind the micro optimizations is that isset is very fast.
This might not be the case in PHP 8.1+ but it was back when we were doing performance profiling on #2770065: array_key_exists() micro-optimization
Comment #11
joseph.olstadok the empty check, I'll roll a new patch
Comment #12
joseph.olstad@joelpittet, I'm hopeful that this patch will do the job for you.
Comment #13
joseph.olstadwith that said, check the results of try catch, it's perhaps the fastest performing approach.
https://stackoverflow.com/a/445094
For now I'm going with the approach of patch 6 and patch 12, but according to stackoverflow the performance of try/catch is extremely high.
If you want the empty condition instead of the isset I can replace that also , with that said, I'm going straight from the Drupal core API approach for the entity_extract_ids() for consistency / performance I think it would be good to follow what core is doing in this case.
Comment #14
joseph.olstadoops , scratch 12, going with 14
Comment #15
joelpittetYes, I have much experience with micro-optimizations 😅,
array_key_exists()is slow,isset($array[$key]) || array_key_exists($key, $array)is faster because PHP shortcuts on a positiveisset()check, but you need both because they do different things.Nice work on referencing core, but I stand by what I said in #8, and with an implicit isset(),
empty()is really fast too.This issue is really wanting of a regression test... it's probably the best way to make sure any changes we make are going to survive logical mistakes in the code.
#12 theEDIT: looks like you spotted that too, lol. But let me take a moment to write a failing test then you can throw patches at it, sound good?reset()should be on$loaded_entitiesComment #16
joelpittetComment #17
joseph.olstadOk @joelpittet, the performance cost of empty() is multitudes times less than entity_load() so I'm totally sure that the performance difference is minute, with that said it is in a foreach loop.
Here's the new patch as requested.
Comment #18
joseph.olstadomg, what was that, ok undo
Comment #19
joseph.olstadremoving noise from .orig file
Comment #20
joelpittet@joseph.olstad ok here is the tests-only patch. Add your patches that you'd like to test against it. It tests all the things I want (except translation, which might also be affected...).
I realized while writing the test that while
taxonomy_term_accessdoes matter, it also gets called by the View execution before, so it's getting a double duty with theentity_load. The test covers thetaxonomy_term_accessjust in case.This patch is expected to fail (showing the problem with #2151631: Improve performance of getReferencableEntities())
Comment #22
joseph.olstad@joelpittet, awesome work, ok testing.
Comment #23
joseph.olstadnew patch, fix PHP 8.2 deprecation notice
Comment #24
joseph.olstadoops, try again
Comment #25
joseph.olstadnew patch
Comment #26
joseph.olstadtesting
Comment #27
joseph.olstad@joelpittet, neither your colleagues approach, nor my approach resolve this issue, have you tested his approach and my approach?
I will attempt to revert the previous commit in the form of a patch and test against your test code to prove whether or not your test is working.
Comment #28
joelpittet@joseph.olstad I tested the partial revert. Probably should have posted that too (it was early in my defence). I'll let you try that one. You can run them all locally if you have a setup, though the testbot is always here for us.
Let me know if you want me to post that too if it's giving you trouble still when you do it, maybe I made a mistake somewhere.
Comment #29
joseph.olstadOk, I've switched to testing in my dev environment, it's much faster, I hope to have a working patch soon, thanks for your followup, I'll post a fix as soon as I find it.
Comment #30
joseph.olstadOk this patch should fix the bug. Passes all tests locally.
Comment #31
joseph.olstadComment #33
joseph.olstadTry this instead.
Comment #35
joseph.olstadThat's very strange, locally patch 33 is passing 100% on PHP 8.2.1
Comment #36
joseph.olstadpasses on my local, see screenshot:
Comment #37
joseph.olstad@joelpittet, any idea why patch 33 would pass 100% locally for me on a similar version of php (PHP 8.2.1 vs PHP 8.2.x on d.o?) but fail on d.o?
Comment #38
joseph.olstad@joelpittet, the only reason why I could imagine such a difference is Drupal.org test framework uses PHP 8.2.0
my test environment uses PHP 8.2.1
Could there really be such a difference between 8.2.0 and 8.2.1? perhaps!
Comment #39
joseph.olstadok, circumventing the test this time.
Makes no sense, passes 100% locally for me without doing this isset check in the tests.
Comment #40
joseph.olstadComment #41
joseph.olstadI don't like having to do this, but the patch passes locally with PHP 8.2.1 no issues, drupal.org test framework appears to be using .0 minor releases first releases of PHP with lots of bugs.
Comment #42
joelpittetThe latest looks to pass, I’ll investigate. My computer is getting repaired this morning. You can discuss on slack if your there.
Comment #43
joseph.olstad@joelpittet, ok I'll try to set up slack, I'm on drupalchat.me
Comment #44
joelpittetOk just undid the test fixes and cleaned up the assertions to be a bit more helpful. I'll dig into the CI if it fails again.
Comment #45
joelpittetComment #47
joelpittetOk maybe the reference was going sideways. Trying to simplify the pass by reference issues that may be happening here.
Like you mentioned I can't reproduce the fails on my machine, even running like testbot does:
php scripts/run-tests.sh --color --concurrency "32" --directory sites/all/modules/contrib/entityreferenceComment #48
joelpittet<error message="exception: [Warning] Line 1871 of includes/bootstrap.inc: Trying to access array offset on value of type int exception: [Warning] Line 1871 of includes/bootstrap.inc: Trying to access array offset on value of type int exception: [Warning] Line 1871 of includes/bootstrap.inc: Trying to access array offset on value of type int exception: [Warning] Line 1871 of includes/bootstrap.inc: Trying to access array offset on value of type int exception: [Warning] Line 1871 of includes/bootstrap.inc: Trying to access array offset on value of type int exception: [Warning] Line 1871 of includes/bootstrap.inc: Trying to access array offset on value of type int " type="exception"/>This is the only thing in the CI that looked suspicious and that was my bad in the test trying to add the
@countComment #50
joseph.olstad@joelpittet, thanks for looking into this, these kinds of mysteries are fascinating.
Comment #51
joseph.olstadI was thinking, to reproduce the drupal.org test environment, we could maybe try installing Drupal vanilla on a docker image with PHP 8.2.0 instead of 8.2.1+?
Comment #52
joseph.olstad@joelpittet
for these fixes:
Creation of dynamic property EntityReference_SelectionHandler_Broken::$field is deprecated
this is the fix:
Comment #53
joelpittetThanks @joseph.olstad this puts those fixes you made earlier for the abstract.inc but it sounds like it's getting a broken handler, which makes me think the class loader is the problem.
Comment #54
joelpittetI might come to the same conclusion you have in #51 but it's hard for me to believe that
PHP 8.2.0is the culprit. Do you have one available? I'm just using DDEV withPHP 8.2.3(earlier I was usingPHP 8.1)Comment #55
joelpittetComment #57
joseph.olstadI'm looking at a PHP 8.2.0 setup now
jakubboucek/lamp-devstack-php:8.2.0-debug
https://hub.docker.com/r/jakubboucek/lamp-devstack-php
Comment #58
joelpittetI refactored the fix to use empty(), that's not going to help but the changes in interdiff-58.txt
EDIT: I added a handler check and did some syntax error clean-up... just in case... in the test
Comment #60
joelpittetViews is not loaded before entityreference and the handler is not available. I see another test that has a workaround. Going to try that.
Comment #62
joseph.olstadok so got the docker environment running but I have to change the port it's on so that the tests will run, I'll try changing 8080 to 80.
Comment #63
joseph.olstad@joelpittet, I tested the PHP 8.2.0 theory, it passes ALL tests with patch #33 above
When using a Docker jakubboucek/lamp-devstack-php:8.2.0-debug (PITA to set up btw, but I got it working) DEBIAN BASED.
all tests pass for 8.2.0
When using my normal development server, Ubuntu 18.04 LTS with PHP 8.2.1
all tests pass for 8.2.1
However patch 33 does not pass all tests with Drupal.org infrastructure, and I have no idea why.
Pretty sure that one of my servers has apcu enabled, the above docker might not, but it passes all tests with Patch 33.
Comment #64
joseph.olstadOk proof that all tests pass with patch 33 on the php 8.2.0 docker container
check this:
Comment #65
joseph.olstad@joelpittet, I lined up patch 41 that like patch 33, should resolve the issue, unless you found something else. Patch 41 basically ignores the noise from drupal.orgs testbot, makes no sense why this would always pass locally but not on d.o, I even tried php 8.2.0 same same.
I even went as far as switching from fast-cgi to fpm on 8.2.1, the only thing I didn't do was test both fast-cgi and fpm on 8.2.0, however I did test 8.2.0 fast cgi, and it passes with patch 33.
So, do we take #41 as a win, and defer the rest for another ticket?
I'd like to tag 1.8 with this fix, all I need is for you to test patch 41 against 1.7 in your environment where this WAS a problem, and let me know if it resolves the issue.
Comment #66
joelpittet#60 is the fix I’d like to see in, I’ll keep trying to uncover the secrets of the testbot only failures.
Comment #67
joseph.olstadI updated the ci testbot issue title, haven't gotten any traction on it yet, was hoping maybe someone else would notice something or report something similar from another project. There is something about the drupal.org test setup that is different, but what? What could possibly be causing this, we've tested PHP 8.2.0 exactly same minor version, I even tested fast-cgi vs fpm, same success on my server, why is drupal.org test ci failing for this particular test?
#3349436: entityreference patch passes all tests everywhere except on Drupal.org test framework
Comment #68
damienmckennaHave you tried running drupalci locally? It might give you extra clues.
Comment #69
joelpittet@DamienMcKenna
is there documentation on how to set that up?I haven't tried that yet.Edit: I found it https://www.drupal.org/node/2487065 by following Joseph's link above to the project page of the drupalci test runner
This patch has the instance passed in to the handler (hailmary... again)
Comment #71
damienmckennahttps://www.drupal.org/drupalorg/docs/drupal-ci/running-drupalci-locally
Comment #72
joelpittetThanks @DamienMcKenna I failed out of the gate on that because of Apple Silicon doesn't like virtualbox
Error: Cask virtualbox depends on hardware architecture being one of [{:type=>:intel, :bits=>64}], but you are running {:type=>:arm, :bits=>64}.This change is trying to copy our feeds integration on how to enable modules.
Comment #74
joelpittet#72 is back to EntityReference_SelectionHandler_Broken, which I assume means that Views wasn't installed before entityreference and this failed.
if (module_exists('views')) {inplugins/selection/views.incTweaking this to get views to install first.
Comment #76
joseph.olstadHmm, maybe try this after the setup
drupal_flush_all_caches()Comment #77
joelpittet@joseph.olstad
$this->resetAll()line does do that, though yeah I was thinking similar.Comment #78
joseph.olstadgrasping at straws but maybe some ci issue with depencency detection
hmmm:
parent::setUp(array('views'));views requires ctools, maybe explicitly include it in the setUp ?
to
parent::setUp(array('ctools', 'views'));Comment #79
joseph.olstador
parent::setUp(array('ctools', 'views','entityreference', 'entityreference_views_test'));Comment #80
joseph.olstad@DamienMcKenna great suggestion, I'll work on that soon hopefully make progress on running the d.o drupalci dockers, meanwhile, maybe @joelpittet figures it out before I do with a change to the test or module code?
Comment #81
joelpittetMore assertions and tweaking the setUp() module load.
Comment #83
joseph.olstadis the views_ui module needed to test the view access?
Comment #84
joelpittetTaking from how setUp is done in
EntityReferenceFormTestCasewhich uses the same view . Not sure why the access failure on the view built in the same method namedcreateNodeEntityReferenceView.We don't have the
views_uionEntityReferenceFormTestCase@joseph.olstadComment #85
joelpittetHa I collided with @joseph.olstad on the last comment and it says I uploaded his file
3348756-interdiff_06_to_12.txtWe are hacking d.o now...Comment #87
franceslui commentedI work with @joelpittet.
Because @joelpittet was not able to install DrupalCI Testbot on his machine, I installed it on my machine and could reproduce the errors in it locally.
Comment #88
joelpittetSorting that label issue out (hopefully)
Comment #90
joelpittetI was able to reproduce the error above, the handler is broken... this seems like I have something I can debug so that's helpful.
Comment #92
joseph.olstadComment #93
joelpittetViews plugin cache is hardcore and the way we are clearing it for the other test is not working for this test.
Seeing how it's done in views tests and not trying to mess with the module load order:
views_fetch_plugin_data(NULL, NULL, TRUE);clears it.Comment #95
joelpittetMore cache clearing?
Comment #97
joelpittetRemoved that cache clearing and specifically clearing the ctools one.
Comment #99
joelpittetIf we are getting a broken selection handler
EntityReference_SelectionHandler_Broken, we know we haveentityreferenceenabled.Comment #101
joelpittetComment #103
joelpittetCan't get the ctools plugin. Clearing more related caches.
Comment #105
joelpittetCopy the way FeedsMapperFieldTestCase does the module install.
Comment #107
joelpittetTricky to fix the views selection plugin after it's installed, so loading views before should help. I took the cache clearing out for now.
Comment #109
joelpittetSo that module ordering is totally the reason for the plugin not loading. The views selection plugin is wrapped in
And if
entityreferenceis enabled first then that isfalseand that plugin is cached (apparently pretty hard) as being empty.Comment #110
joelpittetOk taking full control over the module dependencies and ordering.
Comment #111
joseph.olstad@joelpittet! wow nice work!
Comment #112
damienmckennaThat's impressive! Great work!
Comment #114
joseph.olstadComment #115
joseph.olstadVery pleased to get this fix in, major performance improvement (plus memory heap exception fix) can be maintained and we now have added test coverage for the regression fix.
The only thing I'd like to know is WHY drupal.org ci docker image behaves differently than all the environments I tested?
Comment #117
joseph.olstadOk, we're good, aside from the pgsql mystery, (it was passing for 1.7, and the fails are for feeds not what we changed, makes no sense other than possibly some new configurations made to the drupal ci testbot related to pgsql 13.5)

Comment #118
joseph.olstadThanks very much to the entire team at UBC for this important fix and tricky ci mystery fix and for the additional support we got from everyone else.
Release 1.8 is ready here:
https://www.drupal.org/project/entityreference/releases/7.x-1.8
Comment #119
joelpittetLots of failures brings deeper understanding… I hope
Comment #121
joseph.olstadplease try the latest release, there were two reported issues with 1.7/1.8 , patched and released 1.9
rushed this a bit
https://www.drupal.org/project/entityreference/releases/7.x-1.9