add filesystem watcher to detect updates

This commit is contained in:
Robin Appelman 2012-10-28 11:26:31 +01:00
parent c4a793913c
commit fba7be1194
4 changed files with 164 additions and 2 deletions

View file

@ -234,7 +234,7 @@ class Cache {
$entry = $this->get($file);
if ($entry['mimetype'] === 'httpd/unix-directory') {
$children = $this->getFolderContents($file);
foreach($children as $child){
foreach ($children as $child) {
$this->remove($child['path']);
}
}
@ -325,7 +325,9 @@ class Cache {
$query = \OC_DB::prepare('SELECT `size` FROM `*PREFIX*filecache` WHERE `parent` = ? AND `storage` = ?');
$result = $query->execute(array($id, $this->storageId));
$totalSize = 0;
$hasChilds = 0;
while ($row = $result->fetchRow()) {
$hasChilds = true;
$size = (int)$row['size'];
if ($size === -1) {
$totalSize = -1;
@ -335,7 +337,9 @@ class Cache {
}
}
$this->update($id, array('size' => $totalSize));
if ($hasChilds) {
$this->update($id, array('size' => $totalSize));
}
return $totalSize;
}

70
lib/files/cache/watcher.php vendored Normal file
View file

@ -0,0 +1,70 @@
<?php
/**
* Copyright (c) 2012 Robin Appelman <icewind@owncloud.com>
* This file is licensed under the Affero General Public License version 3 or
* later.
* See the COPYING-README file.
*/
namespace OC\Files\Cache;
/**
* check the storage backends for updates and change the cache accordingly
*/
class Watcher {
/**
* @var \OC\Files\Storage\Storage $storage
*/
private $storage;
/**
* @var Cache $cache
*/
private $cache;
/**
* @var Scanner $scanner;
*/
private $scanner;
/**
* @param \OC\Files\Storage\Storage $storage
*/
public function __construct(\OC\Files\Storage\Storage $storage) {
$this->storage = $storage;
$this->cache = $storage->getCache();
$this->scanner = $storage->getScanner();
}
/**
* check $path for updates
*
* @param string $path
*/
public function checkUpdate($path) {
$cachedEntry = $this->cache->get($path);
if ($this->storage->hasUpdated($path, $cachedEntry['mtime'])) {
if ($cachedEntry['mimetype'] === 'httpd/unix-directory') {
$this->scanner->scan($path, Scanner::SCAN_SHALLOW);
$this->cleanFolder($path);
} else {
$this->scanner->scanFile($path);
}
$this->scanner->correctFolderSize($path);
}
}
/**
* remove deleted files in $path from the cache
*
* @param string $path
*/
public function cleanFolder($path) {
$cachedContent = $this->cache->getFolderContents($path);
foreach ($cachedContent as $entry) {
if (!$this->storage->file_exists($entry['path'])) {
$this->cache->remove($entry['path']);
}
}
}
}

86
tests/lib/files/cache/watcher.php vendored Normal file
View file

@ -0,0 +1,86 @@
<?php
/**
* Copyright (c) 2012 Robin Appelman <icewind@owncloud.com>
* This file is licensed under the Affero General Public License version 3 or
* later.
* See the COPYING-README file.
*/
namespace Test\Files\Cache;
class Watcher extends \PHPUnit_Framework_TestCase {
/**
* @var \OC\Files\Storage\Storage[] $storages;
*/
private $storages = array();
public function setUp() {
\OC\Files\Filesystem::clearMounts();
}
public function tearDown() {
foreach ($this->storages as $storage) {
$cache = $storage->getCache();
$ids = $cache->getAll();
\OC\Files\Cache\Permissions::removeMultiple($ids, \OC_User::getUser());
$cache->clear();
}
}
function testWatcher() {
$storage = $this->getTestStorage();
$cache = $storage->getCache();
$updater = new \OC\Files\Cache\Watcher($storage);
//set the mtime to the past so it can detect an mtime change
$cache->put('', array('mtime' => 10));
$this->assertTrue($cache->inCache('folder/bar.txt'));
$this->assertTrue($cache->inCache('folder/bar2.txt'));
$this->assertFalse($cache->inCache('bar.test'));
$storage->file_put_contents('bar.test', 'foo');
$updater->checkUpdate('');
$this->assertTrue($cache->inCache('bar.test'));
$cachedData = $cache->get('bar.test');
$this->assertEquals(3, $cachedData['size']);
$cache->put('bar.test', array('mtime' => 10));
$storage->file_put_contents('bar.test', 'test data');
$updater->checkUpdate('bar.test');
$cachedData = $cache->get('bar.test');
$this->assertEquals(9, $cachedData['size']);
$cache->put('folder', array('mtime' => 10));
$storage->unlink('folder/bar2.txt');
$updater->checkUpdate('folder');
$this->assertTrue($cache->inCache('folder/bar.txt'));
$this->assertFalse($cache->inCache('folder/bar2.txt'));
}
/**
* @param bool $scan
* @return \OC\Files\Storage\Storage
*/
private function getTestStorage($scan = true) {
$storage = new \OC\Files\Storage\Temporary(array());
$textData = "dummy file data\n";
$imgData = file_get_contents(\OC::$SERVERROOT . '/core/img/logo.png');
$storage->mkdir('folder');
$storage->file_put_contents('foo.txt', $textData);
$storage->file_put_contents('foo.png', $imgData);
$storage->file_put_contents('folder/bar.txt', $textData);
$storage->file_put_contents('folder/bar2.txt', $textData);
if ($scan) {
$scanner = $storage->getScanner();
$scanner->scan('');
}
$this->storages[] = $storage;
return $storage;
}
}

View file

@ -20,6 +20,8 @@ class View extends \PHPUnit_Framework_TestCase {
public function tearDown() {
foreach ($this->storages as $storage) {
$cache = $storage->getCache();
$ids = $cache->getAll();
\OC\Files\Cache\Permissions::removeMultiple($ids, \OC_User::getUser());
$cache->clear();
}
}