Skip to content

Commit

Permalink
fixes #368
Browse files Browse the repository at this point in the history
  • Loading branch information
raffis committed Aug 21, 2019
1 parent 5a3f9fa commit 7aba98a
Show file tree
Hide file tree
Showing 5 changed files with 48 additions and 48 deletions.
7 changes: 7 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,10 @@
## 2.6.3
**Maintainer**: Raffael Sahli <[email protected]>\
**Date**: Wed Aug 21 10:30:42 CEST 2019

* CORE: [FIX] SMB folder does not get synced correctly (failed sync child node) #368


## 2.6.2
**Maintainer**: Raffael Sahli <[email protected]>\
**Date**: Thu Jul 11 12:25:42 CEST 2019
Expand Down
55 changes: 22 additions & 33 deletions src/lib/Async/SmbScanner.php
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@

use Balloon\Filesystem\Node\Collection;
use Balloon\Filesystem\Node\File;
use Balloon\Filesystem\Node\NodeInterface;
use Balloon\Filesystem\Storage\Adapter\Blackhole;
use Balloon\Filesystem\Storage\Adapter\Smb;
use Balloon\Helper;
Expand Down Expand Up @@ -44,21 +43,26 @@ class SmbScanner extends AbstractJob
*/
protected $logger;

/**
* Dummy storage.
*/
protected $dummy;

/**
* Constructor.
*/
public function __construct(Server $server, LoggerInterface $logger)
{
$this->server = $server;
$this->logger = $logger;
$this->dummy = new Blackhole();
}

/**
* {@inheritdoc}
*/
public function start(): bool
{
$dummy = new Blackhole();
$fs = $this->server->getFilesystem();
$mount = $collection = $fs->findNodeById($this->data['id']);
$user = $this->server->getUserById($collection->getOwner());
Expand All @@ -73,7 +77,7 @@ public function start(): bool

$collection
->setFilesystem($user_fs)
->setStorage($dummy);
->setStorage($this->dummy);

$path = $smb->getRoot();
if (isset($this->data['path'])) {
Expand All @@ -88,7 +92,7 @@ public function start(): bool
$parent_path = dirname($path);
if ($path !== '.') {
$collection = $this->getParent($collection, $share, $parent_path, $action);
$collection->setStorage($dummy);
$collection->setStorage($this->dummy);
}
}

Expand All @@ -97,7 +101,7 @@ public function start(): bool
$recursive = $this->data['recursive'];
}

$this->recursiveIterator($collection, $mount, $share, $dummy, $user, $smb, $path, $recursive, $action);
$this->recursiveIterator($collection, $mount, $share, $user, $smb, $path, $recursive, $action);

return true;
}
Expand All @@ -110,7 +114,6 @@ protected function getParent(Collection $mount, IShare $share, string $path, int
$parent = $mount;
$nodes = explode(DIRECTORY_SEPARATOR, $path);
$sub = '';
$dummy = $mount->getStorage();

foreach ($nodes as $child) {
if ($child === '.') {
Expand All @@ -120,7 +123,7 @@ protected function getParent(Collection $mount, IShare $share, string $path, int
try {
$sub .= DIRECTORY_SEPARATOR.$child;
$parent = $parent->getChild($child);
$parent->setStorage($dummy);
$parent->setStorage($this->dummy);
} catch (\Exception $e) {
if ($action === INotifyHandler::NOTIFY_REMOVED) {
throw $e;
Expand All @@ -139,28 +142,16 @@ protected function getParent(Collection $mount, IShare $share, string $path, int
}

/**
* Delete node.
* Iterate recursively through smb share.
*/
protected function deleteNode(NodeInterface $node, Blackhole $dummy): bool
protected function recursiveIterator(Collection $parent, Collection $mount, IShare $share, User $user, Smb $smb, string $path, bool $recursive, int $action): void
{
if ($node instanceof Collection) {
$node->doRecursiveAction(function (NodeInterface $node) use ($dummy) {
if ($node instanceof Collection) {
$node->setStorage($dummy);
}
});
}

$node->delete(true);
$system_path = $path.DIRECTORY_SEPARATOR.$smb->getSystemFolder();

return true;
}
if ($path === $system_path) {
return;
}

/**
* Iterate recursively through smb share.
*/
protected function recursiveIterator(Collection $parent, Collection $mount, IShare $share, Blackhole $dummy, User $user, Smb $smb, string $path, bool $recursive, int $action): void
{
$this->logger->debug('sync smb path ['.$path.'] in mount ['.$mount->getId().'] from operation ['.$action.']', [
'category' => get_class($this),
'recursive' => $recursive,
Expand All @@ -177,16 +168,14 @@ protected function recursiveIterator(Collection $parent, Collection $mount, ISha
} catch (NotFoundException $e) {
if ($action === INotifyHandler::NOTIFY_REMOVED) {
$node = $parent->getChild(Helper::mb_basename($path));
$node->getParent()->setStorage($dummy);
$this->deleteNode($node, $dummy);
$node->getParent()->setStorage($this->dummy);
$node->delete(true);
}

return;
}

if ($node->isDirectory()) {
$parent->setStorage($dummy);

if ($path === DIRECTORY_SEPARATOR) {
$child = $parent;
} else {
Expand All @@ -198,7 +187,7 @@ protected function recursiveIterator(Collection $parent, Collection $mount, ISha
}

if ($recursive === true) {
$child->setStorage($dummy);
$child->setStorage($this->dummy);
$nodes = [];

foreach ($share->dir($path) as $node) {
Expand All @@ -210,7 +199,7 @@ protected function recursiveIterator(Collection $parent, Collection $mount, ISha
$child_path = ($path === DIRECTORY_SEPARATOR) ? $path.$node->getName() : $path.DIRECTORY_SEPARATOR.$node->getName();

try {
$this->recursiveIterator($child, $mount, $share, $dummy, $user, $smb, $child_path, $recursive, $action);
$this->recursiveIterator($child, $mount, $share, $user, $smb, $child_path, $recursive, $action);
} catch (\Exception $e) {
$this->logger->error('failed sync child node ['.$child_path.'] in smb mount', [
'category' => get_class($this),
Expand All @@ -219,11 +208,11 @@ protected function recursiveIterator(Collection $parent, Collection $mount, ISha
}
}

foreach ($child->getChildren() as $sub_child) {
foreach ($child->getChildNodes() as $sub_child) {
$sub_name = Normalizer::normalize($sub_child->getName());

if (!in_array($sub_name, $nodes)) {
$this->deleteNode($sub_child, $dummy);
$sub_child->delete(true);
}
}
}
Expand Down
22 changes: 11 additions & 11 deletions src/lib/Filesystem.php
Original file line number Diff line number Diff line change
Expand Up @@ -237,9 +237,9 @@ public function findNodeById($id, ?string $class = null, int $deleted = NodeInte
/**
* Find one.
*/
public function findOne(array $filter, int $deleted = NodeInterface::DELETED_INCLUDE): NodeInterface
public function findOne(array $filter, int $deleted = NodeInterface::DELETED_INCLUDE, ?Collection $parent = null): NodeInterface
{
$result = iterator_to_array($this->findNodesByFilterRecursiveChildren($filter, $deleted, 0, 1));
$result = iterator_to_array($this->findNodesByFilterRecursiveChildren($filter, $deleted, 0, 1, $parent));

if (count($result) === 0) {
throw new Exception\NotFound(
Expand Down Expand Up @@ -512,7 +512,7 @@ public function getTrash(array $query = [], ?int $offset = null, ?int $limit = n
/**
* Find nodes with custom filter recursive.
*/
public function findNodesByFilterRecursiveChildren(array $parent_filter, int $deleted, ?int $offset = null, ?int $limit = null): Generator
public function findNodesByFilterRecursiveChildren(array $parent_filter, int $deleted, ?int $offset = null, ?int $limit = null, ?Collection $parent = null): Generator
{
$query = [
['$match' => $parent_filter],
Expand All @@ -538,7 +538,7 @@ public function findNodesByFilterRecursiveChildren(array $parent_filter, int $de
['$group' => ['_id' => null, 'total' => ['$sum' => 1]]],
];

return $this->executeAggregation($query, $offset, $limit);
return $this->executeAggregation($query, $offset, $limit, $parent);
}

/**
Expand All @@ -565,7 +565,7 @@ public function findNodesByFilterRecursive(Collection $collection, array $filter
['$group' => ['_id' => null, 'total' => ['$sum' => 1]]],
];

return $this->executeAggregation($query, $offset, $limit);
return $this->executeAggregation($query, $offset, $limit, $collection);
}

/**
Expand Down Expand Up @@ -598,7 +598,7 @@ public function findNodesByFilterUser(int $deleted, array $filter, ?int $offset
/**
* Init node.
*/
public function initNode(array $node): NodeInterface
public function initNode(array $node, ?Collection $parent = null): NodeInterface
{
$id = $node['_id'];

Expand All @@ -607,11 +607,11 @@ public function initNode(array $node): NodeInterface
}

if (isset($node['parent'])) {
$parent = $this->findNodeById($node['parent']);
if ($parent === null || $parent->getId() != $node['parent']) {
$parent = $this->findNodeById($node['parent']);
}
} elseif ($node['_id'] !== null) {
$parent = $this->getRoot();
} else {
$parent = null;
}

if (!array_key_exists('directory', $node)) {
Expand Down Expand Up @@ -733,7 +733,7 @@ protected function prepareChildrenFilter(int $deleted)
/**
* Execute complex aggregation.
*/
protected function executeAggregation(array $query, ?int $offset = null, ?int $limit = null): Generator
protected function executeAggregation(array $query, ?int $offset = null, ?int $limit = null, ?Collection $parent = null): Generator
{
$result = $this->db->storage->aggregate($query);

Expand All @@ -751,7 +751,7 @@ protected function executeAggregation(array $query, ?int $offset = null, ?int $l

foreach ($result as $node) {
try {
yield $this->initNode($node);
yield $this->initNode($node, $parent);
} catch (\Exception $e) {
$this->logger->error('remove node from result list, failed load node', [
'category' => get_class($this),
Expand Down
8 changes: 4 additions & 4 deletions src/lib/Filesystem/Node/Collection.php
Original file line number Diff line number Diff line change
Expand Up @@ -243,7 +243,7 @@ public function getChildNodes(int $deleted = NodeInterface::DELETED_EXCLUDE, arr
$filter = $this->getChildrenFilter($deleted, $filter);

if ($recursive === false) {
return $this->_fs->findNodesByFilterRecursiveChildren($filter, $deleted, $offset, $limit);
return $this->_fs->findNodesByFilterRecursiveChildren($filter, $deleted, $offset, $limit, $this);
}

unset($filter['parent']);
Expand Down Expand Up @@ -320,7 +320,7 @@ public function getChild($name, int $deleted = NodeInterface::DELETED_EXCLUDE, a
$filter = $this->getChildrenFilter($deleted, $filter);
$filter['name'] = new Regex('^'.preg_quote($name).'$', 'i');

return $this->_fs->findOne($filter);
return $this->_fs->findOne($filter, $deleted, $this);
}

/**
Expand Down Expand Up @@ -606,7 +606,7 @@ public function addDirectory($name, array $attributes = [], int $conflict = Node
$this->changed = $save['changed'];
$this->save('changed');

$new = $this->_fs->initNode($save);
$new = $this->_fs->initNode($save, $this);
$this->_hook->run('postCreateCollection', [$this, $new, $clone]);

return $new;
Expand Down Expand Up @@ -676,7 +676,7 @@ public function addFile($name, ?ObjectId $session = null, array $attributes = []
$this->changed = $save['changed'];
$this->save('changed');

$file = $this->_fs->initNode($save);
$file = $this->_fs->initNode($save, $this);

if ($session !== null) {
$file->setContent($session, $attributes);
Expand Down
4 changes: 4 additions & 0 deletions src/lib/Filesystem/Node/Factory.php
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,10 @@ public function build(Filesystem $fs, array $node, ?Collection $parent): NodeInt

$storage = $this->storage;

if ($parent !== null) {
$storage = $parent->getStorage();
}

if (isset($node['reference'])) {
$share = $fs->findRawNode($node['reference']);
if (isset($share['mount'])) {
Expand Down

0 comments on commit 7aba98a

Please sign in to comment.