8000 Improved speed of DirectoryResource by SimonHeimberg · Pull Request #21440 · symfony/symfony · GitHub
[go: up one dir, main page]

Skip to content

Improved speed of DirectoryResource #21440

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

Closed
wants to merge 1 commit into from

Conversation

SimonHeimberg
Copy link
Contributor
Q A
Branch? master
Bug fix? no
New feature? no
BC breaks? no
Deprecations? no
Tests pass? ?
Fixed tickets
License MIT
Doc PR

isFresh() quits as soon as a newer resource is found.

@@ -87,10 +89,12 @@ public function isFresh($timestamp)
continue;
}

$newestMTime = max($file->getMTime(), $newestMTime);
if ($file->getMTime() < $timestamp) {
return true
Copy link
Member

Choose a reason for hiding this comment

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

missing ;

@nicolas-grekas
Copy link
Member

I doubt this really works.
To my knowledge, the mtime of directories is not changed when a nested file is changed.

@nicolas-grekas nicolas-grekas added this to the 3.x milestone Jan 29, 2017
@robfrawley
Copy link
Contributor

@nicolas-grekas With regard to modification time behavior

#!/bin/bash

TMPDIR="/tmp/mtime-test/"
TMPFILE="$TMPDIR/test-file"
TMPINNERDIR="$TMPDIR/test-dir/"
TMPINNERFILE="$TMPINNERDIR/test-file"

rm -fr $TMPDIR && mkdir $TMPDIR

CREATIONTIME="$(stat -c %Y $TMPDIR)"

sleep 2
touch $TMPFILE
TOUCHTIME="$(stat -c %Y $TMPDIR)"

if [[ "$CREATIOBTIME" == "$TOUCHTIME" ]]; then
  echo ":-( Touching inner file doesn't modify time."
else
  echo ":-) Touching inner file modified time!"
fi
echo "Before Time : $CREATIONTIME"
echo -e "After Time  : $TOUCHTIME\n"

sleep 2
echo "IDK" > $TMPFILE
MODTIME="$(stat -c %Y $TMPDIR)"

if [[ "$TOUCHTIME" == "$MODTIME" ]]; then
  echo ":-( Modifying inner file doesn't modify time."
else
  echo ":-) Modifying inner file modified time!"
fi
echo "Before Time : $TOUCHTIME"
echo -e "After Time  : $MODTIME\n"

sleep 2
mkdir $TMPINNERDIR
INNERMKDIRTIME="$(stat -c %Y $TMPDIR)"

if [[ "$MODTIME" == "$INNERMKDIRTIME" ]]; then
  echo ":-( Creating inner dir doesn't modify time."
else
  echo ":-) Creating inner dir modified time!"
fi
echo "After Time  : $MODTIME"
echo -e "Before Time : $INNERMKDIRTIME\n"

sleep 2
touch $TMPINNERFILE
INNERFILETIME="$(stat -c %Y $TMPDIR)"

if [[ "$INNERMKDIRTIME" == "$INNERFILETIME" ]]; then
  echo ":-( Creating inner^2 file doesn't modify time."
else
  echo ":-) Creating inner^2 file modified time!"
fi
echo "Before Time : $INNERMKDIRTIME"
echo "After Time  : $INNERFILETIME"

Results:

:-) Touching inner file modified time!
Before Time : 1485721881
After Time  : 1485721883

:-( Modifying inner file doesn't modify time.
Before Time : 1485721883
After Time  : 1485721883

:-) Creating inner dir modified time!
After Time  : 1485721883
Before Time : 1485721887

:-( Creating inner^2 file doesn't modify time.
Before Time : 1485721887
After Time  : 1485721887

@nicolas-grekas
Copy link
Member

executive summary: do you see anything we can improve in DirectoryResource?

@robfrawley
Copy link
Contributor

Just gave the class a once-over, and nothing specific jumps out to me. This PR does completely break the test suite, though (in line with what I mentioned above):

# vendor/bin/phpunit src/Symfony/Component/Config/Tests/Resource/DirectoryResourceTest.php

Clock-mocked namespaces for SymfonyTestsListener need to be nested in a "time-sensitive" key. This will be enforced in Symfony 4.0.
PHPUnit 5.7.4-9-g94cec03 by Sebastian Bergmann and contributors.

Testing Symfony\Component\Config\Tests\Resource\DirectoryResourceTest
.....FF...FF.F...                                                 17 / 17 (100%)

Time: 185 ms, Memory: 4.00MB

There were 5 failures:

1) Symfony\Component\Config\Tests\Resource\DirectoryResourceTest::testIsFreshUpdateFile
->isFresh() returns false if an existing file is modified
Failed asserting that true is false.

/home/rmf/repositories/symfony/symfony/src/Symfony/Component/Config/Tests/Resource/DirectoryResourceTest.php:93

2) Symfony\Component\Config\Tests\Resource\DirectoryResourceTest::testIsFreshNewFile
->isFresh() returns false if a new file is added
Failed asserting that true is false.

/home/rmf/repositories/symfony/symfony/src/Symfony/Component/Config/Tests/Resource/DirectoryResourceTest.php:100

3) Symfony\Component\Config\Tests\Resource\DirectoryResourceTest::testIsFreshCreateFileInSubdirectory
->isFresh() returns false if a new file in a subdirectory is added
Failed asserting that true is false.

/home/rmf/repositories/symfony/symfony/src/Symfony/Component/Config/Tests/Resource/DirectoryResourceTest.php:133

4) Symfony\Component\Config\Tests\Resource\DirectoryResourceTest::testIsFreshModifySubdirectory
->isFresh() returns false if a subdirectory is modified (e.g. a file gets deleted)
Failed asserting that true is false.

/home/rmf/repositories/symfony/symfony/src/Symfony/Component/Config/Tests/Resource/DirectoryResourceTest.php:144

5) Symfony\Component\Config\Tests\Resource\DirectoryResourceTest::testFilterRegexListMatch
->isFresh() returns false if an new file matching the filter regex is created 
Failed asserting that true is false.

/home/rmf/repositories/symfony/symfony/src/Symfony/Component/Config/Tests/Resource/DirectoryResourceTest.php:160

FAILURES!
Tests: 17, Assertions: 20, Failures: 5.

@robfrawley
Copy link
Contributor

You could possibly change line 90 to something like

            if (($fileMTime = $file->getMTime()) > $timestamp) {
                return false;
            }

            $newestMTime = max($fileMTime, $newestMTime);

But with regard to this PR, you can never break early with a return of true without checking every other file for freshness, right?

@nicolas-grekas
Copy link
Member

Closing a discussed. Thanks for the PR anyway!

@SimonHeimberg
Copy link
Contributor Author

Hm, I wanted to break early when anything found is newer, but this should return false of course, right. We can never quit early with true, but in the end true should be returned.
Replacing trying with thinking is not easy. And I have forgotten to check the test run results when they were ready.
Thanks.

fabpot added a commit that referenced this pull request Feb 12, 2017
This PR was squashed before being merged into the 2.7 branch (closes #21458).

Discussion
----------

[Config] Early return for DirectoryResource

| Q             | A
| ------------- | ---
| Branch?       | 2.7
| Bug fix?      | yes
| New feature?  | sure?
| BC breaks?    | no
| Deprecations? | no
| Tests pass?   | no
| Fixed tickets |
| Related PRs | #21440
| License       | MIT
| Doc PR        | n/a

Alternate PR  that implements an early return for `DirectoryResource` to increase the speed on large file sets. We can never return early with `true` without checking all assets within the resource, as the aforementioned referenced PR did; hence this PR takes the counter approach and returns `false` early where appropriate.

_Conversation about possible bug at #21458 (comment)

Commits
-------

d5746ec fix directory resource considers same timestamp not fresh
96107e2 return false early from directory resource
@nicolas-grekas nicolas-grekas modified the milestones: 3.x, 3.3 Mar 24, 2017
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants
0