Problem/Motivation
Apologies if I've misunderstood, but I was trying to figure out why the changes in #2500525: Time ago/hence date/time formatting breaks caching; needs appropriate max age didn't cause my view with a 'Time ago' field to only be cached for a short period. From my understanding of the code, it would never have fixed it:
FormattedDateDiff::$maxAge
is now filled with a reasonable max age based on the granularity being displayed. This works perfectly.TimestampAgoFormatter
etc now get the time ago returned as an object and then callCacheableMetadata::createFromObject($result)->applyTo($build);
to apply the max age from$result
(theFormattedDateDiff
object). This is reasonable.CacheableMetadata::createFromObject
recognisesFormattedDateDiff
as an implementation ofCacheableDependencyInterface
and so get's the max age from the object:meta->cacheMaxAge = $object->getCacheMaxAge();
.FormattedDateDiff::getCacheMaxAge()
is actually inherited fromUnchangingCacheableDependencyTrait
and simply returnsCache::PERMANENT
- So
FormattedDateDiff::$maxAge
is actually completely ignored andFormattedDateDiff::getMaxAge()
which actually returnFormattedDateDiff::$maxAge
is never called in all of Drupal Core as far as I can tell.
Proposed resolution
Rename FormattedDateDiff::getMaxAge()
to FormattedDateDiff::getCacheMaxAge()
to override the trait.
Add proper coverage of the FormattedDateDiff() methods to prevent further regressions.
Remaining tasks
None.
User interface changes
None.
API changes
Technically, a public method that shouldn't be on FormattedDateDiff is being removed. Don't think this warrants a CR, as it was a typo in the original patch that slipped through.
Data model changes
None.
Patch / Beta Eligibility
Per https://www.drupal.org/core/d8-allowed-changes#beta this qualifies for inclusion in 8.1.x and 8.2.x this would qualify under
- bug fixes and contributed project blockers, if they are non-disruptive, or if the impact outweighs the disruption
- minor API additions or internal API changes to fix bugs (or for other prioritized changes), if the impact outweighs the disruption
Comment | File | Size | Author |
---|---|---|---|
#49 | 2780549-2-48.patch | 2.61 KB | alexpott |
#49 | 34-48-interdiff.txt | 1.35 KB | alexpott |
#34 | 2780549-34-testFormattedDateDiff.patch | 2.13 KB | andrewbelcher |
#34 | 2780549-34-testFormattedDateDiff.test_only.patch | 1.67 KB | andrewbelcher |
Comments
Comment #2
alexpott@andrewbelcher your analysis looks spot on. Nice find. Looks like a patch and some tests are needed.
Comment #3
alexpottComment #4
andrewbelcher CreditAttribution: andrewbelcher at FreelyGive commentedAh, you've already done a patch in the time it took me to put what I'd done into patches.
I've taken a slightly different approach with tests, not sure which approach is better...
Comment #5
alexpott@andrewbelcher let's see what test bot says - your patch looks good. Because even if mine fail it would still need your added coverage.
Comment #6
andrewbelcher CreditAttribution: andrewbelcher at FreelyGive commentedI had a typo in mine so cancelled, just updating and waiting for composer to install so I can run it locally first.
Comment #7
andrewbelcher CreditAttribution: andrewbelcher at FreelyGive commentedOk, these fail/pass appropriately locally.
Comment #10
alexpottSo it looks like we're missing proper test coverage to toRenderable too. Given that the test only patch in #3 passed.
Comment #12
andrewbelcher CreditAttribution: andrewbelcher at FreelyGive commentedHere's some basic test coverage for
FormattedDateDiff::toRenderable()
. Don't think a data provider or anything more is necessary as it doesn't really do anything other than build the array.Comment #13
mpdonadioNice catch. Let's make sure both new tests fail w/o the fix. This patch is small, and easy to review, but it helps to post an interdiff between different versions.
Comment #14
mpdonadioComment #16
mpdonadioThis should now be an {@inheritdoc}.
Not sure if this is a valid test.
I think this after this hunk:
adding
would be more appropriate since it relies on ::formatDiff() building something that can call ::toRenderable() and not building a FormattedDateDiff() object directly in which ::toRenderable() is essentially a pass-though getter. And add the additional @covers and some comments.
?
Comment #17
andrewbelcher CreditAttribution: andrewbelcher at FreelyGive commented1. This is done, good spot.
2. I'm not quite sure why it's not a valid test. We are specifically testing the pass through of it, as the building of it is already tested when we assert the result object matches our expected object.
To that end, I've created 2 sets of patches, one which does as you've suggested of putting it into
testformatDiff
, the other moves all of it intotestFormattedDateDiff
adding in a check ongetString
as well. My preference is the latter, doesn't seem much point running that test multiple times with the provider fortestformatDiff
...Comment #20
dawehnerI kinda like the additional test method, so https://www.drupal.org/files/issues/2780549-16-testFormattedDateDiff.tes...
Comment #21
mpdonadioLooks like this got in by accident.
I'm not sure if we normally allow this syntax, though phpunit didn't complain about it. I think we just need the two lines w/o eg,
Even though the two approaches are similar, this is the approach that makes the most sense to me for the long run.
With those two small adjustments, this is RTBC.
Comment #22
andrewbelcher CreditAttribution: andrewbelcher at FreelyGive commentedGood spots. Not in front of my computer atm, will try and get the updated patch up today.
Comment #23
andrewbelcher CreditAttribution: andrewbelcher at FreelyGive commentedI've fixed the bits from #21. I've also added the coverage for
FormattedDateDiff::getString
toDateTest::testformatDiff
so that both approaches have equal/full coverage.Comment #24
andrewbelcher CreditAttribution: andrewbelcher at FreelyGive commentedHmm... only the last file actually uploaded. Here are the rest.
Comment #27
mpdonadioWe are starting to get into scope creep on this now; the ::getString() coverage isn't really related to the bug at hand. I preferred the other approach, but am not necessarily opposed adding this coverage in this issue if we adding a new test method here which consolidates the coverage of these methods (a committer may disagree and push back on this).
This part
needs to be updated, though. We don't have @covers for whole classes in core, just individual methods. This needs to be
If we make that change, and just post one version of a new patch (ie, just update 2780549-23-testFormattedDateDiff.patch and post a test-only version), then I think we are good and I will set RTBC.
Comment #28
andrewbelcher CreditAttribution: andrewbelcher at FreelyGive commentedDidn't know we didn't do whole class coverage. Makes sense in case things get added in the future.
I've updated the patch.
Comment #29
andrewbelcher CreditAttribution: andrewbelcher at FreelyGive commentedJust spotted a typo, was testFormattedDataDiff, not testFormattedDateDiff. Updated patches attached.
Comment #34
andrewbelcher CreditAttribution: andrewbelcher at FreelyGive commentedTurns out DrupalStandardsListener doesn't like the trailing
()
on covers. I've attached an updated set of patches.Comment #35
andrewbelcher CreditAttribution: andrewbelcher at FreelyGive commentedComment #37
mpdonadioOk, looks good. Thanks.
Comment #38
alexpottSo theres a question of whether FormatterDateDiff::getMaxAge() is public API. I don't think so. This was just an error of implementation and maintaining a BC layer feels pointless.
Comment #39
alexpottCommitted and pushed abe6951 to 8.3.x and f465ed3 to 8.2.x. Thanks!
Discussed with @catch we agreed that the getMaxAge() is dead code.
If we want this to go inot 8.1.x then we should reroll leaving getMaxAge() as a bc layer for the tiny chance that someone is using this as a public API.
Comment #42
andrewbelcher CreditAttribution: andrewbelcher at FreelyGive commentedIf we need a backward compatibility later for 8.1.x, do we not also need it all the way to 9? People will no more expect the change between minor as they would patch... Perhaps a change record would suffice? Would be great to get this into 8.1.x so the cache works as expected.
If you think we do need a BC layer or a change record, I'm happy to write.
Comment #43
xjmI actually do think it would be good to make the old, incorrect method a wrapper for the correct one and deprecate it, in all branches, similar to what @andrewbelcher suggests.
Comment #44
mpdonadioOk, so it sounds like the plan should be
- roll the patch against 8.1.X
- write change record
- apply final patch to 8.1.X
- revert f465ed3, apply new patch to 8.2.X
- revert f465ed3, apply new patch to 8.3.X
?
Comment #45
mpdonadioMade followup to handle this, #2783491: Add BC and Deprecate FormattedDateDiff::getMaxAge(), so the commit log is more better.
Comment #46
alexpottComment #49
alexpottHere's a patch the adds the (tested) BC layer.
Comment #50
alexpottI decided that the plan to revert was better because if we're going to add a BC layer it should be in the same commit as the fix.
Comment #51
mpdonadioAssuming this patch actually runs and come up green, the new version is good; the test passes locally for me.
The comment on the deprecated method matches CacheableDependencyInterface::getCacheMaxAge(). The BC shim calls the replacement function instead of just doing the same thing. The shim has test coverage that looks correct. The deprecation docs look good.
Made draft CR.
Comment #52
andrewbelcher CreditAttribution: andrewbelcher at FreelyGive commentedAll looks great to me!
Comment #53
alexpottCommitted and pushed 1bd3a04 to 8.3.x and b845102 to 8.2.x and 76b777f to 8.1.x. Thanks!
Since we've added the BC and this issue would result in caching issues on site cherry-picked to 8.1.x too.