Skip to content

[2.2] [WIP] ResourceWatcher component refactored #3961

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 72 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
72 commits
Select commit Hold shift + click to select a range
a30ef7e
[ResourceWatcher] resource change event created
everzet Mar 25, 2011
443c2b4
[ResourceWatcher] resource event listener interface described
everzet Mar 25, 2011
b9f0ab8
[ResourceWatcher] created basic resource event listener object
everzet Mar 25, 2011
937882b
[ResourceWatcher] resource state checker interface described
everzet Mar 25, 2011
2b4be01
[ResourceWatcher] created recursive iterator resource state checker
everzet Mar 25, 2011
cb11c9b
[ResourceWatcher] resources tracker interface described
everzet Mar 25, 2011
d97d728
[ResourceWatcher] recursive iterator resources tracker created
everzet Mar 25, 2011
752dc6c
[ResourceWatcher] resource watcher object created
everzet Mar 25, 2011
893acfb
[ResourceWatcher] inotify tracker added
everzet Mar 25, 2011
8dd8e9f
[ResourceWatcher] use best tracker by default
everzet Mar 25, 2011
51d54c7
[ResourceWatcher] renamed Event::handes to Event::supports to be cons…
everzet Mar 25, 2011
38c92ea
[ResourceWatcher] fixed non-empty directory events
everzet Aug 20, 2011
f3389ce
[Config] updated resources API to be more explicit
everzet Nov 19, 2011
c3a710b
[Config] moved DirectoryResource childs retrieving to the special get…
everzet Nov 19, 2011
690507b
[ResourceWatcher] cleaned code little bit
everzet Nov 19, 2011
f7e2267
[ResourceWatcher] refactored recursive state checkers into 2 separate…
everzet Nov 19, 2011
7f720a4
[Config] getFilteredChildResources() method added to DirectoryResource
everzet Nov 19, 2011
b8349ec
[ResourceWatcher] refactored recursive iterator tracker to support ne…
everzet Nov 19, 2011
3d0e65b
[Config] updated DirectoryResource tests
everzet Nov 25, 2011
ab746a3
[Config] update FileResourceTest
everzet Nov 25, 2011
f3dafd6
[ResourceWatcher] removed InotifyTracker as i have no ability to test…
everzet Nov 25, 2011
ed39212
[Config] added new methods and their tests to File and Directory reso…
everzet Nov 29, 2011
bd5079f
[ResourceWatcher] updated ResourceWatcher and TrackerInterface
everzet Nov 29, 2011
bcbf12d
[ResourceWatcher] added time information to events
everzet Nov 29, 2011
adbac59
[ResourceWatcher] updated FileStateChecker to match FileResource API
everzet Nov 29, 2011
fa5a603
[ResourceWatcher] refactored DirectoryStateChecker
everzet Nov 29, 2011
2132e24
[ResourceWatcher] refactored RecursiveIteratorTracker
everzet Nov 29, 2011
8510398
[ResourceWatcher] updated StateCheckerInterface
everzet Nov 29, 2011
c9fa57f
[ResourceWatcher] return of the InotifyTracker
everzet Nov 29, 2011
688b8c6
[ResourceWatcher] removed unneeded code
fabpot Dec 5, 2011
fff3dce
[ResourceWatcher] added an exception when inotify is not available
fabpot Dec 5, 2011
fe9cacb
[Config] made ResourceInterface extends Serializable
fabpot Dec 5, 2011
7579abc
[ResourceWatcher] removed dead code
fabpot Dec 5, 2011
dda358e
[ResourceWatcher] added the possibility to watch files that do not ex…
fabpot Dec 5, 2011
15e7406
[ResourceWatcher] added exception classes for the component
fabpot Dec 29, 2011
a453dd2
-
fabpot Dec 29, 2011
5daa931
[ResourceWatcher] moved tests into component folder
everzet Apr 7, 2012
662271a
[ResourceWatcher] refactored event subsystem
everzet Apr 16, 2012
b56ab6f
[ResourceWatcher] added TrackedResource class
everzet Apr 16, 2012
0b8a294
[ResourceWatcher] refactored ResourceWatcher
everzet Apr 16, 2012
53d8d6f
[ResourceWatcher] refactored TrackerInterface
everzet Apr 16, 2012
2c170b1
[ResourceWatcher] refactored RecursiveIteratorTracker to support new …
everzet Apr 16, 2012
730e7f6
[ResourceWatcher] added support for events mask in ResourceStateChecker
everzet Apr 16, 2012
b7ab255
[ResourceWatcher] refactored state checkers to support new interfaces…
everzet Apr 16, 2012
0aa1ee9
[ResourceWatcher] refactored TrackerTest and added missing test cases
everzet Apr 16, 2012
7d244af
[ResourceWatcher] added missing TrackerTest cases
everzet Apr 16, 2012
a34f4b1
[ResourceWatcher] optimized TrackerTest cases
everzet Apr 16, 2012
e3c260b
[ResourceWatcher] started InotifyTracker refactoring
everzet Apr 16, 2012
0018ed7
[ResourceWatcher] cleaned ResourceWatcher API to be more consistent w…
everzet Apr 16, 2012
d297832
[ResourceWatcher] fixed intofiy function call
everzet Apr 17, 2012
2514795
[Config] skip dots in getFilteredChilds() (fixes test suite on Linux)
everzet Apr 20, 2012
71d72ef
[ResourceWatcher] removed InotifyTracker as it was not finished anywa…
everzet Apr 20, 2012
2e63fb1
[ResourceWatcher] added functional test for ResourceWatcher class
everzet Apr 20, 2012
1f2217e
[ResourceWatcher] prevent temp folder flooding by test suite
everzet Apr 20, 2012
6d9eac5
[ResourceWatcher] Inotify Tracker.
Dattaya May 24, 2012
0c1fe95
Merge pull request #2 from Dattaya/resource-watcher-rebuilt-inotify-r…
everzet May 24, 2012
be0b05e
[ResourceWatcher] Typos, docblock clear.
Dattaya May 24, 2012
2fab315
Merge pull request #3 from Dattaya/resource-watcher-typos-docblock
everzet May 24, 2012
49d78ed
[ResourceWatcher] DirectoryStateCheckerTest, onConsecutiveCalls issue.
Dattaya May 24, 2012
a9193eb
Merge pull request #4 from Dattaya/resource-watcher-tests-issues
everzet May 24, 2012
21cbd27
Moved previously added assertions from `testTrackDeepDirChanges` to t…
Dattaya May 26, 2012
0132949
[ResourceWatcher] NewDirectoryStateChecker: removed unnecessary `$re…
Dattaya May 27, 2012
0bec395
[ResourceWatcher] Ran CS Fixer against code + fixed some CS issues by…
Dattaya May 27, 2012
0564b07
Merge pull request #5 from Dattaya/resource-watcher-issues
everzet Jun 9, 2012
3aaf29b
[Config] added type prefixes to resource ids
everzet Jun 9, 2012
2cf953d
[Config] use is_file in FileResource::exists()
everzet Jun 9, 2012
4c4c55f
[ResourceWatcher] added php-inotify extension setup to vendors.php
everzet Jun 9, 2012
e20cff0
[ResourceWatcher] added composer configuration
everzet Jun 13, 2012
a4e903e
[ResourceWatcher] ResourceWatcher functional test, small addition.
Dattaya Jun 13, 2012
633268d
[ResourceWatcher] Get rid of FilesystemEvent events' "IN_" prefix.
Dattaya Jun 13, 2012
8a9e652
Merge pull request #6 from Dattaya/resource-watcher-tests-and-event-n…
everzet Jun 13, 2012
019d5a6
added symfony/config as resource watcher dependency
everzet Jun 13, 2012
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@
"symfony/browser-kit": "self.version",
"symfony/class-loader": "self.version",
"symfony/config": "self.version",
"symfony/resource-watcher": "self.version",
"symfony/console": "self.version",
"symfony/css-selector": "self.version",
"symfony/dependency-injection": "self.version",
Expand Down
165 changes: 148 additions & 17 deletions src/Symfony/Component/Config/Resource/DirectoryResource.php
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
*
* @author Fabien Potencier <fabien@symfony.com>
*/
class DirectoryResource implements ResourceInterface, \Serializable
class DirectoryResource implements ResourceInterface
{
private $resource;
private $pattern;
Expand All @@ -33,6 +33,82 @@ public function __construct($resource, $pattern = null)
$this->pattern = $pattern;
}

/**
* Returns the list of filtered file and directory childs of directory resource.
*
* @return array An array of files
*/
public function getFilteredChilds()
{
if (!$this->exists()) {
return array();
}

$iterator = new \RecursiveIteratorIterator(
new \RecursiveDirectoryIterator($this->resource, \FilesystemIterator::SKIP_DOTS),
\RecursiveIteratorIterator::SELF_FIRST
);

$childs = array();
foreach ($iterator as $file) {
// if regex filtering is enabled only return matching files
if ($file->isFile() && !$this->hasFile($file)) {
continue;
}

// always monitor directories for changes, except the .. entries
// (otherwise deleted files wouldn't get detected)
if ($file->isDir() && '/..' === substr($file, -3)) {
continue;
}

$childs[] = $file;
}

return $childs;
}

/**
* Returns child resources that matches directory filters.
*
* @return array
*/
public function getFilteredResources()
{
if (!$this->exists()) {
return array();
}

$iterator = new \DirectoryIterator($this->resource);

$resources = array();
foreach ($iterator as $file) {
// if regex filtering is enabled only return matching files
if ($file->isFile() && !$this->hasFile($file)) {
continue;
}

// always monitor directories for changes, except the .. entries
// (otherwise deleted files wouldn't get detected)
if ($file->isDir() && '/..' === substr($file, -3)) {
continue;
}

// if file is dot - continue
if ($file->isDot()) {
continue;
}

if ($file->isFile()) {
$resources[] = new FileResource($file->getRealPath());
} elseif ($file->isDir()) {
$resources[] = new DirectoryResource($file->getRealPath());
}
}

return $resources;
}

/**
* Returns a string representation of the Resource.
*
Expand All @@ -53,11 +129,62 @@ public function getResource()
return $this->resource;
}

/**
* Returns check pattern.
*
* @return mixed
*/
public function getPattern()
{
return $this->pattern;
}

/**
* Checks that passed file exists in resource and matches resource filters.
*
* @param SplFileInfo|string $file
*
* @return Boolean
*/
public function hasFile($file)
{
if (!$file instanceof \SplFileInfo) {
$file = new \SplFileInfo($file);
}

if (0 !== strpos($file->getRealPath(), realpath($this->resource))) {
return false;
}

if ($this->pattern) {
return (bool) preg_match($this->pattern, $file->getBasename());
}

return true;
}

/**
* Returns resource mtime.
*
* @return integer
*/
public function getModificationTime()
{
if (!$this->exists()) {
return -1;
}

clearstatcache(true, $this->resource);
$newestMTime = filemtime($this->resource);

foreach ($this->getFilteredChilds() as $file) {
clearstatcache(true, (string) $file);
$newestMTime = max($file->getMTime(), $newestMTime);
}

return $newestMTime;
}

/**
* Returns true if the resource has not been updated since the given timestamp.
*
Expand All @@ -67,27 +194,31 @@ public function getPattern()
*/
public function isFresh($timestamp)
{
if (!is_dir($this->resource)) {
if (!$this->exists()) {
return false;
}

$newestMTime = filemtime($this->resource);
foreach (new \RecursiveIteratorIterator(new \RecursiveDirectoryIterator($this->resource), \RecursiveIteratorIterator::SELF_FIRST) as $file) {
// if regex filtering is enabled only check matching files
if ($this->pattern && $file->isFile() && !preg_match($this->pattern, $file->getBasename())) {
continue;
}

// always monitor directories for changes, except the .. entries
// (otherwise deleted files wouldn't get detected)
if ($file->isDir() && '/..' === substr($file, -3)) {
continue;
}
return $this->getModificationTime() < $timestamp;
}

$newestMTime = max($file->getMTime(), $newestMTime);
}
/**
* Returns true if the resource exists in the filesystem.
*
* @return Boolean
*/
public function exists()
{
return is_dir($this->resource);
}

return $newestMTime < $timestamp;
/**
* Returns unique resource ID.
*
* @return string
*/
public function getId()
{
return md5('d'.$this->resource.$this->pattern);
}

public function serialize()
Expand Down
44 changes: 40 additions & 4 deletions src/Symfony/Component/Config/Resource/FileResource.php
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
*
* @author Fabien Potencier <fabien@symfony.com>
*/
class FileResource implements ResourceInterface, \Serializable
class FileResource implements ResourceInterface
{
private $resource;

Expand All @@ -29,7 +29,7 @@ class FileResource implements ResourceInterface, \Serializable
*/
public function __construct($resource)
{
$this->resource = realpath($resource);
$this->resource = file_exists($resource) ? realpath($resource) : $resource;
}

/**
Expand All @@ -52,6 +52,22 @@ public function getResource()
return $this->resource;
}

/**
* Returns resource mtime.
*
* @return integer
*/
public function getModificationTime()
{
if (!$this->exists()) {
return -1;
}

clearstatcache(true, $this->resource);

return filemtime($this->resource);
}

/**
* Returns true if the resource has not been updated since the given timestamp.
*
Expand All @@ -61,11 +77,31 @@ public function getResource()
*/
public function isFresh($timestamp)
{
if (!file_exists($this->resource)) {
if (!$this->exists()) {
return false;
}

return filemtime($this->resource) < $timestamp;
return $this->getModificationTime() <= $timestamp;
}

/**
* Returns true if the resource exists in the filesystem.
*
* @return Boolean
*/
public function exists()
{
return is_file($this->resource);
}

/**
* Returns unique resource ID.
*
* @return string
*/
public function getId()
{
return md5('f'.$this->resource);
}

public function serialize()
Expand Down
23 changes: 22 additions & 1 deletion src/Symfony/Component/Config/Resource/ResourceInterface.php
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
*
* @author Fabien Potencier <fabien@symfony.com>
*/
interface ResourceInterface
interface ResourceInterface extends \Serializable
{
/**
* Returns a string representation of the Resource.
Expand All @@ -34,10 +34,31 @@ function __toString();
*/
function isFresh($timestamp);

/**
* Returns resource mtime.
*
* @return integer
*/
function getModificationTime();

/**
* Returns true if the resource exists in the filesystem.
*
* @return Boolean
*/
function exists();

/**
* Returns the resource tied to this Resource.
*
* @return mixed The resource
*/
function getResource();

/**
* Returns unique resource ID.
*
* @return string
*/
function getId();
}
Loading