Example #1
0
        /// <summary>
        /// Unlocks the item in the remote storage. The item must implement <see cref="IVirtualLock"/> interface.
        /// </summary>
        /// <exception cref="ClientLockFailedException">
        /// Thrown when a file can not be locked. For example when a lock-token file is blocked
        /// from another thread, during update, lock and unlock operations.
        /// </exception>
        public async Task UnlockAsync()
        {
            // Verify that the item supports locking.
            if (!(await GetItemAsync(userFileSystemPath) is IVirtualLock))
            {
                throw new NotSupportedException(nameof(IVirtualLock));
            }

            using (LockSync lockSync = await lockManager.LockAsync())
            {
                await UnlockAsync(lockSync);
            }
        }
Example #2
0
        /// <summary>
        /// Locks the item in the remote storage. The item must implement <see cref="IVirtualLock"/> interface.
        /// </summary>
        /// <param name="lockSync">Sync lock.</param>
        /// <param name="lockMode">Indicates automatic or manual lock.</param>
        private async Task <ServerLockInfo> LockAsync(LockSync lockSync, LockMode lockMode)
        {
            ServerLockInfo lockInfo = null;

            try
            {
                logger.LogMessage("Locking in remote storage", userFileSystemPath);

                // Set lock-pending icon.
                await userFileSystemRawItem.SetLockPendingIconAsync(true);

                // Lock file in remote storage.
                IVirtualLock userLock = await GetItemAsync(userFileSystemPath) as IVirtualLock;

                lockInfo = await userLock.LockAsync();

                // Save lock-token and lock-mode.
                await lockManager.SetLockInfoAsync(lockInfo);

                await lockManager.SetLockModeAsync(lockMode);

                logger.LogMessage("Locked in remote storage succesefully.", userFileSystemPath);
            }
            catch (Exception ex)
            {
                logger.LogError("Locking in remote storage failed.", userFileSystemPath, null, ex);

                // Delete lock-token and lock-mode files.
                await lockManager.DeleteLockAsync();

                // Clear lock icon.
                await userFileSystemRawItem.SetLockInfoAsync(null);

                // Rethrow the exception preserving stack trace of the original exception.
                System.Runtime.ExceptionServices.ExceptionDispatchInfo.Capture(ex).Throw();
            }

            // Set locked icon and all lock properties.
            await userFileSystemRawItem.SetLockInfoAsync(lockInfo);

            return(lockInfo);
        }
Example #3
0
        /// <summary>
        /// Unlocks the file in the remote storage using existing <see cref="LockSync"/>.
        /// </summary>
        /// <param name="lockSync">Sync lock.</param>
        private async Task UnlockAsync(LockSync lockSync)
        {
            logger.LogMessage("Unlocking in remote storage", userFileSystemPath);

            // Set pending icon.
            await userFileSystemRawItem.SetLockPendingIconAsync(true);

            // Read lock-token from lock-info file.
            string lockToken = (await lockManager.GetLockInfoAsync()).LockToken;

            // Unlock file in remote storage.
            IVirtualLock userLock = await GetItemAsync(userFileSystemPath) as IVirtualLock;

            await userLock.UnlockAsync(lockToken);

            // Delete lock-mode and lock-token files.
            await lockManager.DeleteLockAsync();

            // Remove lock icon.
            await userFileSystemRawItem.SetLockInfoAsync(null);

            logger.LogMessage("Unlocked in remote storage succesefully", userFileSystemPath);
        }
Example #4
0
        /// <inheritdoc/>
        public async Task UpdateAsync()
        {
            // This protects from ocationally calling update on moved items.
            if (PlaceholderItem.GetItem(userFileSystemPath).IsMoved())
            {
                string originalPath = PlaceholderItem.GetItem(userFileSystemPath).GetOriginalPath();
                throw new ConflictException(Modified.Client, $"The item was moved. Original path: {originalPath}");
            }

            LockSync lockSync = null;

            try
            {
                if (!PlaceholderItem.GetItem(userFileSystemPath).GetInSync())
                {
                    // This will make sure only one thread can do the lock-update-unlock sequence.
                    lockSync = await lockManager.LockAsync();

                    IVirtualFileSystemItem userFileSystemItem = await GetItemAsync(userFileSystemPath);

                    ServerLockInfo lockInfo = null;
                    if (userFileSystemItem is IVirtualLock)
                    {
                        // Get lock info in case of manual lock or failed lock/update/unlock
                        if (await lockManager.IsLockedAsync())
                        {
                            lockInfo = await lockManager.GetLockInfoAsync();
                        }

                        // Lock file if auto-locking is enabled.
                        else if (virtualDrive.Settings.AutoLock)
                        {
                            // Lock file in remote storage.
                            lockInfo = await LockAsync(lockSync, LockMode.Auto);
                        }
                    }

                    // Update item in remote storage.
                    logger.LogMessage("Sending to remote storage", userFileSystemPath);
                    await CreateOrUpdateAsync(FileMode.Open, lockInfo);

                    //await new UserFileSystemRawItem(userFileSystemPath).ClearStateAsync();
                    logger.LogMessage("Sent to remote storage succesefully", userFileSystemPath);
                }

                // Unlock if auto-locked.
                if (await lockManager.GetLockModeAsync() == LockMode.Auto)
                {
                    // Required in case the file failed to unlock during previous update.
                    lockSync ??= await lockManager.LockAsync();

                    // Send unlock request to remote storage.
                    await UnlockAsync(lockSync);
                }
            }
            catch (ClientLockFailedException ex)
            {
                // Failed to lock file. Possibly blocked from another thread. This is a normal behaviour.
                logger.LogMessage(ex.Message, userFileSystemPath);
            }
            catch (Exception ex)
            {
                // Some error when locking, updating or unlocking occured.
                await userFileSystemRawItem.SetUploadErrorStateAsync(ex);

                // Rethrow the exception preserving stack trace of the original exception.
                System.Runtime.ExceptionServices.ExceptionDispatchInfo.Capture(ex).Throw();
            }
            finally
            {
                if (lockSync != null)
                {
                    lockSync.Dispose();
                }
                // Do not delete lock-token and lock-mode files here, it is required if IUserLock
                // interfce is implemented and the file was locked manually.
            }
        }