Commit 2b74d941 authored by skummer's avatar skummer

ZP-237 #comment z-push-admin shows all folders which are not yet fully...

ZP-237 #comment z-push-admin shows all folders which are not yet fully synchronized (initial sync) #time 9h

git-svn-id: https://z-push.org/svn/z-push/trunk@1591 b7dd7b3b-3a3c-0410-9da9-bee62a6cc5b5
parent 89f4db59
...@@ -48,6 +48,7 @@ class ASDevice extends StateObject { ...@@ -48,6 +48,7 @@ class ASDevice extends StateObject {
const FOLDERUUID = 1; const FOLDERUUID = 1;
const FOLDERTYPE = 2; const FOLDERTYPE = 2;
const FOLDERSUPPORTEDFIELDS = 3; const FOLDERSUPPORTEDFIELDS = 3;
const FOLDERSYNCSTATUS = 4;
// expected values for not set member variables // expected values for not set member variables
protected $unsetdata = array( protected $unsetdata = array(
...@@ -636,6 +637,50 @@ class ASDevice extends StateObject { ...@@ -636,6 +637,50 @@ class ASDevice extends StateObject {
$this->contentData = $contentData; $this->contentData = $contentData;
return true; return true;
} }
/**
* Gets the current sync status of a certain folder
*
* @param string $folderid
*
* @access public
* @return mixed/boolean false means the status is not available
*/
public function GetFolderSyncStatus($folderid) {
if (isset($this->contentData) && isset($this->contentData[$folderid]) &&
isset($this->contentData[$folderid][self::FOLDERUUID]) && $this->contentData[$folderid][self::FOLDERUUID] !== false &&
isset($this->contentData[$folderid][self::FOLDERSYNCSTATUS]) )
return $this->contentData[$folderid][self::FOLDERSYNCSTATUS];
return false;
}
/**
* Sets the current sync status of a certain folder
*
* @param string $folderid
* @param mixed $status if set to false the current status is deleted
*
* @access public
* @return boolean
*/
public function SetFolderSyncStatus($folderid, $status) {
$contentData = $this->contentData;
if (!isset($contentData[$folderid]) || !is_array($contentData[$folderid]))
$contentData[$folderid] = array();
if ($status !== false) {
$contentData[$folderid][self::FOLDERSYNCSTATUS] = $status;
}
else if (isset($contentData[$folderid][self::FOLDERSYNCSTATUS])) {
unset($contentData[$folderid][self::FOLDERSYNCSTATUS]);
}
$this->contentData = $contentData;
return true;
}
} }
?> ?>
\ No newline at end of file
...@@ -51,6 +51,10 @@ class DeviceManager { ...@@ -51,6 +51,10 @@ class DeviceManager {
const MSG_BROKEN_CAUSINGLOOP = 2; const MSG_BROKEN_CAUSINGLOOP = 2;
const MSG_BROKEN_SEMANTICERR = 4; const MSG_BROKEN_SEMANTICERR = 4;
const FLD_SYNC_INITIALIZED = 1;
const FLD_SYNC_INPROGRESS = 2;
const FLD_SYNC_COMPLETED = 4;
private $device; private $device;
private $deviceHash; private $deviceHash;
private $statemachine; private $statemachine;
...@@ -637,6 +641,36 @@ class DeviceManager { ...@@ -637,6 +641,36 @@ class DeviceManager {
return $this->loopdetection->SetSyncStateUsage($folderid, $uuid, $counter); return $this->loopdetection->SetSyncStateUsage($folderid, $uuid, $counter);
} }
/**
* Sets the current status of the folder
*
* @param string $folderid folder id
* @param int $statusflag current status: DeviceManager::FLD_SYNC_INITIALIZED, DeviceManager::FLD_SYNC_INPROGRESS, DeviceManager::FLD_SYNC_COMPLETED
*
* @access public
* @return
*/
public function SetFolderSyncStatus($folderid, $statusflag) {
$currentStatus = $this->device->GetFolderSyncStatus($folderid);
// status available or just initialized
if (isset($currentStatus[ASDevice::FOLDERSYNCSTATUS]) || $statusflag == self::FLD_SYNC_INITIALIZED) {
// only update if there is a change
if ($statusflag !== $currentStatus[ASDevice::FOLDERSYNCSTATUS] && $statusflag != self::FLD_SYNC_COMPLETED) {
$this->device->SetFolderSyncStatus($folderid, array(ASDevice::FOLDERSYNCSTATUS => $statusflag));
ZLog::Write(LOGLEVEL_WARN, sprintf("SetFolderSyncStatus(): set %s for %s", $statusflag, $folderid));
}
// if completed, remove the status
else if ($statusflag == self::FLD_SYNC_COMPLETED) {
$this->device->SetFolderSyncStatus($folderid, false);
ZLog::Write(LOGLEVEL_WARN, sprintf("SetFolderSyncStatus(): completed for %s", $folderid));
}
}
return true;
}
/** /**
* Indicates if the device needs an AS version update * Indicates if the device needs an AS version update
* *
......
...@@ -368,28 +368,6 @@ class SyncCollections implements Iterator { ...@@ -368,28 +368,6 @@ class SyncCollections implements Iterator {
return $this->lastSyncTime; return $this->lastSyncTime;
} }
/**
* Returns the timestamp of the last synchronization of a device.
*
* @param $device an ASDevice
*
* @access public
* @return int timestamp
*/
static public function GetLastSyncTimeOfDevice(&$device) {
// we need a StateManager for this operation
$stateManager = new StateManager();
$stateManager->SetDevice($device);
$sc = new SyncCollections();
$sc->SetStateManager($stateManager);
// load all collections of device without loading states or checking permissions
$sc->LoadAllCollections(true, false, false);
return $sc->GetLastSyncTime();
}
/** /**
* Checks if the currently known collections for changes for $lifetime seconds. * Checks if the currently known collections for changes for $lifetime seconds.
* If the backend provides a ChangesSink the sink will be used. * If the backend provides a ChangesSink the sink will be used.
......
...@@ -68,7 +68,9 @@ class SyncParameters extends StateObject { ...@@ -68,7 +68,9 @@ class SyncParameters extends StateObject {
'deletesasmoves' => false, 'deletesasmoves' => false,
'conversationmode' => false, 'conversationmode' => false,
'windowsize' => 5, 'windowsize' => 5,
'contentparameters' => array() 'contentparameters' => array(),
'foldersynctotal' => false,
'foldersyncremaining' => false,
); );
/** /**
......
...@@ -693,10 +693,15 @@ class Sync extends RequestProcessor { ...@@ -693,10 +693,15 @@ class Sync extends RequestProcessor {
$status = $stex->getCode(); $status = $stex->getCode();
} }
if (! $spa->HasSyncKey()) if (! $spa->HasSyncKey()) {
self::$topCollector->AnnounceInformation(sprintf("Exporter registered. %d objects queued.", $changecount), true); self::$topCollector->AnnounceInformation(sprintf("Exporter registered. %d objects queued.", $changecount), true);
// update folder status as initialized
$spa->SetFolderSyncTotal($changecount);
self::$deviceManager->SetFolderSyncStatus($folderid, DeviceManager::FLD_SYNC_INITIALIZED);
}
else if ($status != SYNC_STATUS_SUCCESS) else if ($status != SYNC_STATUS_SUCCESS)
self::$topCollector->AnnounceInformation(sprintf("StatusException code: %d", $status), true); self::$topCollector->AnnounceInformation(sprintf("StatusException code: %d", $status), true);
} }
} }
...@@ -877,7 +882,6 @@ class Sync extends RequestProcessor { ...@@ -877,7 +882,6 @@ class Sync extends RequestProcessor {
ZLog::Write(LOGLEVEL_DEBUG, sprintf("HandleSync(): Exported maxItems of messages: %d / %d", $n, $changecount)); ZLog::Write(LOGLEVEL_DEBUG, sprintf("HandleSync(): Exported maxItems of messages: %d / %d", $n, $changecount));
break; break;
} }
} }
// $progress is not an array when exporting the last message // $progress is not an array when exporting the last message
...@@ -888,6 +892,13 @@ class Sync extends RequestProcessor { ...@@ -888,6 +892,13 @@ class Sync extends RequestProcessor {
self::$encoder->endTag(); self::$encoder->endTag();
self::$topCollector->AnnounceInformation(sprintf("Outgoing %d objects%s", $n, ($n >= $windowSize)?" of ".$changecount:""), true); self::$topCollector->AnnounceInformation(sprintf("Outgoing %d objects%s", $n, ($n >= $windowSize)?" of ".$changecount:""), true);
// update folder status
$spa->SetFolderSyncRemaining($changecount);
if ($changecount == 0)
self::$deviceManager->SetFolderSyncStatus($folderid, DeviceManager::FLD_SYNC_COMPLETED);
else
self::$deviceManager->SetFolderSyncStatus($folderid, DeviceManager::FLD_SYNC_INPROGRESS);
} }
self::$encoder->endTag(); self::$encoder->endTag();
...@@ -1042,8 +1053,8 @@ class Sync extends RequestProcessor { ...@@ -1042,8 +1053,8 @@ class Sync extends RequestProcessor {
if ($this->importer == false) if ($this->importer == false)
throw StatusException(sprintf("Sync->importMessage(): importer not available", SYNC_STATUS_SERVERERROR)); throw StatusException(sprintf("Sync->importMessage(): importer not available", SYNC_STATUS_SERVERERROR));
// mark this state as used, e.g. for HeartBeat // mark this state as used, e.g. for HeartBeat
self::$deviceManager->SetHeartbeatStateIntegrity($spa->GetFolderId(), $spa->GetUuid(), $spa->GetUuidCounter()); self::$deviceManager->SetHeartbeatStateIntegrity($spa->GetFolderId(), $spa->GetUuid(), $spa->GetUuidCounter());
// Detect incoming loop // Detect incoming loop
// messages which were created/removed before will not have the same action executed again // messages which were created/removed before will not have the same action executed again
......
...@@ -99,9 +99,37 @@ class ZPushAdmin { ...@@ -99,9 +99,37 @@ class ZPushAdmin {
$device->StripData(); $device->StripData();
try { try {
$lastsync = SyncCollections::GetLastSyncTimeOfDevice($device); // we need a StateManager for this operation
if ($lastsync) $stateManager = new StateManager();
$device->SetLastSyncTime($lastsync); $stateManager->SetDevice($device);
$sc = new SyncCollections();
$sc->SetStateManager($stateManager);
// load all collections of device without loading states or checking permissions
$sc->LoadAllCollections(true, false, false);
if ($sc->GetLastSyncTime())
$device->SetLastSyncTime($sc->GetLastSyncTime());
// get information about the folder synchronization status from SyncCollections
$folders = $device->GetAllFolderIds();
foreach ($folders as $folderid) {
$fstatus = $device->GetFolderSyncStatus($folderid);
if ($fstatus !== false && isset($fstatus[ASDevice::FOLDERSYNCSTATUS])) {
$spa = $sc->GetCollection($folderid);
$total = $spa->GetFolderSyncTotal();
$todo = $spa->GetFolderSyncRemaining();
$fstatus['status'] = ($fstatus[ASDevice::FOLDERSYNCSTATUS] == 1)?'Initialized':'Synchronizing';
$fstatus['total'] = $total;
$fstatus['done'] = $total - $todo;
$fstatus['todo'] = $todo;
$device->SetFolderSyncStatus($folderid, $fstatus);
}
}
} }
catch (StateInvalidException $sive) { catch (StateInvalidException $sive) {
ZLog::Write(LOGLEVEL_WARN, sprintf("ZPushAdmin::GetDeviceDetails(): device '%s' of user '%s' has invalid states. Please sync to solve this issue.", $devid, $user)); ZLog::Write(LOGLEVEL_WARN, sprintf("ZPushAdmin::GetDeviceDetails(): device '%s' of user '%s' has invalid states. Please sync to solve this issue.", $devid, $user));
......
...@@ -514,6 +514,7 @@ class ZPushAdminCLI { ...@@ -514,6 +514,7 @@ class ZPushAdminCLI {
$folders = $device->GetAllFolderIds(); $folders = $device->GetAllFolderIds();
$synchedFolders = 0; $synchedFolders = 0;
$synchedFolderTypes = array(); $synchedFolderTypes = array();
$syncedFoldersInProgress = 0;
foreach ($folders as $folderid) { foreach ($folders as $folderid) {
if ($device->GetFolderUUID($folderid)) { if ($device->GetFolderUUID($folderid)) {
$synchedFolders++; $synchedFolders++;
...@@ -542,6 +543,15 @@ class ZPushAdminCLI { ...@@ -542,6 +543,15 @@ class ZPushAdminCLI {
if (!isset($synchedFolderTypes[$gentype])) if (!isset($synchedFolderTypes[$gentype]))
$synchedFolderTypes[$gentype] = 0; $synchedFolderTypes[$gentype] = 0;
$synchedFolderTypes[$gentype]++; $synchedFolderTypes[$gentype]++;
// set the folder name for all folders which are not fully synchronized yet
$fstatus = $device->GetFolderSyncStatus($folderid);
if ($fstatus !== false && is_array($fstatus)) {
// TODO would be nice if we could see the real name of the folder, right now we use the folder type as name
$fstatus['name'] = $gentype;
$device->SetFolderSyncStatus($folderid, $fstatus);
$syncedFoldersInProgress++;
}
} }
} }
$folderinfo = ""; $folderinfo = "";
...@@ -580,8 +590,21 @@ class ZPushAdminCLI { ...@@ -580,8 +590,21 @@ class ZPushAdminCLI {
echo "First sync:\t\t". strftime("%Y-%m-%d %H:%M", $device->GetFirstSyncTime()) ."\n"; echo "First sync:\t\t". strftime("%Y-%m-%d %H:%M", $device->GetFirstSyncTime()) ."\n";
echo "Last sync:\t\t". ($device->GetLastSyncTime() ? strftime("%Y-%m-%d %H:%M", $device->GetLastSyncTime()) : "never")."\n"; echo "Last sync:\t\t". ($device->GetLastSyncTime() ? strftime("%Y-%m-%d %H:%M", $device->GetLastSyncTime()) : "never")."\n";
echo "Total folders:\t\t". count($folders). "\n"; echo "Total folders:\t\t". count($folders). "\n";
echo "Synchronized folders:\t". $synchedFolders . "\n"; echo "Synchronized folders:\t". $synchedFolders;
if ($syncedFoldersInProgress > 0)
echo " (". $syncedFoldersInProgress. " in progress)";
echo "\n";
echo "Synchronized data:\t$folderinfo\n"; echo "Synchronized data:\t$folderinfo\n";
if ($syncedFoldersInProgress > 0) {
echo "Synchronization progress:\n";
foreach ($folders as $folderid) {
$d = $device->GetFolderSyncStatus($folderid);
if ($d) {
$percent = round($d['done']*100/$d['total']);
printf("\tFolder: %s%s Sync: %s Status: %s%d%% (%d/%d)\n", $d['name'], str_repeat(" ", 12-strlen($d['name'])), $d['status'], ($percent < 10)?" ":"", $percent, $d['done'], $d['total'] );
}
}
}
echo "Status:\t\t\t"; echo "Status:\t\t\t";
switch ($device->GetWipeStatus()) { switch ($device->GetWipeStatus()) {
case SYNC_PROVISION_RWSTATUS_OK: case SYNC_PROVISION_RWSTATUS_OK:
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment