Skip to content

Timestamp returned for trait last modification times in the cached reader should be an integer, is an array #105

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

Merged
merged 2 commits into from
Dec 30, 2016

Conversation

trsteel88
Copy link
Contributor

This PR fixes an issue where the cache is constantly being written - wasting IO.

After looking into this further, I found that the problem I'm having with excessive IO is because getLastModification is merging the timestamps incorrectly.

The result of the following can't be merged:

dump(array_merge(
    [$filename ? filemtime($filename) : 0],
    array_map([$this, 'getTraitLastModificationTimes'], $class->getTraits()),
    array_map([$this, 'getLastModification'], $class->getInterfaces()),
    $parent ? [$this->getLastModification($parent)] : []
));

screen shot 2016-11-14 at 11 29 03 am

The result of this is that it can't work out the max() of the traits.

To resolve this, I updated getTraitLastModificationTimes to always return the max timestamp.

Using this PR in favour of another change I made: #104

@mikeSimonson
Copy link
Contributor

mikeSimonson commented Nov 14, 2016

@trsteel88 Thanks.
Can you add a test case for this ?

/**
* @param ReflectionClass $reflectionTrait
* @return int
*/
private function getTraitLastModificationTimes(ReflectionClass $reflectionTrait)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

the name should be changed, as it does not return several times anymore

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This method returns an int[], which is then passed to max() in private function getLastModification(). If I get it correctly, the fix is different, and it is to change that function's body instead:

         return max(array_merge(
             [$filename ? filemtime($filename) : 0],
            // notice the three dots:
             ...array_map([$this, 'getTraitLastModificationTimes'], $class->getTraits()),
             array_map([$this, 'getLastModification'], $class->getInterfaces()),
             $parent ? [$this->getLastModification($parent)] : []
         ));

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The three dots don't work.

Compile Error: Cannot use positional argument after argument unpacking

Copy link
Member

@Ocramius Ocramius left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A test case demonstrating the current issue is also needed.

/**
* @param ReflectionClass $reflectionTrait
* @return int
*/
private function getTraitLastModificationTimes(ReflectionClass $reflectionTrait)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This method returns an int[], which is then passed to max() in private function getLastModification(). If I get it correctly, the fix is different, and it is to change that function's body instead:

         return max(array_merge(
             [$filename ? filemtime($filename) : 0],
            // notice the three dots:
             ...array_map([$this, 'getTraitLastModificationTimes'], $class->getTraits()),
             array_map([$this, 'getLastModification'], $class->getInterfaces()),
             $parent ? [$this->getLastModification($parent)] : []
         ));

@Ocramius Ocramius added the bug label Nov 14, 2016
@trsteel88
Copy link
Contributor Author

@Ocramius @mikeSimonson where should this test go? I can't see any existing tests for the CachedReacher class.

I'm assuming we just need a single test to ensure that getLastModification returns an int (and never an array)?

@mikeSimonson
Copy link
Contributor

@trsteel88 The test should go there with the other tests of cachedReader.

@trsteel88
Copy link
Contributor Author

Thanks @mikeSimonson - I'll add one in.

Also, I noticed that within fetchFromCache() it has the following:

     if (($data = $this->cache->fetch($cacheKey)) !== false) {
            if (!$this->debug || $this->isCacheFresh($cacheKey, $class)) {
                return $data;
            }
        }

In dev, debug is always going to be false. This is rendering the cache completely useless. Is this meant to be there?

@Ocramius
Copy link
Member

In dev mode, caches should really not be hit at all, so that's intentional.

Ocramius added a commit that referenced this pull request Dec 30, 2016
@Ocramius Ocramius added this to the v1.3.1 milestone Dec 30, 2016
@Ocramius Ocramius self-assigned this Dec 30, 2016
@Ocramius Ocramius merged commit 6b4221c into doctrine:master Dec 30, 2016
Ocramius added a commit that referenced this pull request Dec 30, 2016
Ocramius added a commit that referenced this pull request Dec 30, 2016
@Ocramius
Copy link
Member

@trsteel88 merged, I added a test to it :-)

master: 8ac9494
1.3.x: bc1963d

@Ocramius Ocramius changed the title Return single max timestamp Timestamp returned for trait last modification times in the cached reader should be an integer, is an array Dec 30, 2016
@chosroes
Copy link

This caused the error in #117 =/

@Ocramius
Copy link
Member

@chosroes I still need a test case for that - can't do anything without it, and I'm not bootstrapping a symfony application for that.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants