Exemplo n.º 1
0
        /* ----------------------------------------------------------------- */
        ///
        /// SetDestination
        ///
        /// <summary>
        /// Subscribes the message to select the save path.
        /// </summary>
        ///
        /// <param name="src">Source ViewModel.</param>
        /// <param name="value">Save path to set when requested.</param>
        ///
        /// <returns>Object to clear the subscription.</returns>
        ///
        /* ----------------------------------------------------------------- */
        public static IDisposable SetDestination(this ProgressViewModel src, string value)
        {
            var dest = new DisposableContainer();

            dest.Add(src.Subscribe <OpenDirectoryMessage>(e =>
            {
                e.Value  = value;
                e.Cancel = false;
            }));

            dest.Add(src.Subscribe <SaveFileMessage>(e => {
                e.Value  = value;
                e.Cancel = false;
            }));

            return(dest);
        }
Exemplo n.º 2
0
 /* ----------------------------------------------------------------- */
 ///
 /// Hook
 ///
 /// <summary>
 /// Adds the specified object and returns it.
 /// </summary>
 ///
 /// <param name="src">Source container.</param>
 /// <param name="obj">Object to be added.</param>
 ///
 /// <returns>Same as the specified object.</returns>
 ///
 /* ----------------------------------------------------------------- */
 public static T Hook <T>(this DisposableContainer src, T obj) where T : IDisposable
 {
     src.Add(obj);
     return(obj);
 }
Exemplo n.º 3
0
        public async Task <IEnumerable <FtpEntry> > ListFilesRecursiveAsync(string startPath = null, Predicate <FtpEntry> skipFolder = null, CancellationToken ctk = default)
        {
            startPath = startPath ?? "./";

            if (skipFolder == null)
            {
                skipFolder = x => false;
            }

            List <Task <IEnumerable <FtpEntry> > > pending = new List <Task <IEnumerable <FtpEntry> > >();
            IEnumerable <FtpEntry> files = new List <FtpEntry>();

            using (var d = new DisposableContainer())
            {
                var clientsQueue = new AsyncQueue <FluentFTP.IFtpClient>(5);
                for (int i = 0; i < 5; i++)
                {
                    var c = _getClient();
                    d.Add(c);
                    await clientsQueue.Enqueue(c, ctk);
                }

                Func <string, CancellationToken, Task <IEnumerable <FtpEntry> > > listFolderAsync = async(string path, CancellationToken ct) =>
                {
                    var c = await clientsQueue.Dequeue(ct);

                    try
                    {
                        var retrier = Policy
                                      .Handle <Exception>()
                                      .WaitAndRetryAsync(new[]
                        {
                            TimeSpan.FromSeconds(1),
                            TimeSpan.FromSeconds(5),
                            TimeSpan.FromSeconds(15)
                        }, (ex, ts) =>
                        {
                            _logger.Warn(ex, "Failed to list folder {0}. Try again soon ...", path);
                        });
                        var res = await retrier.ExecuteAsync(ct1 =>
                        {
                            return(c.Value.GetListingAsync(path));
                        }, ct).ConfigureAwait(false);

                        return(res.Select(x => new FtpEntry()
                        {
                            FullPath = x.FullName,
                            IsDirectory = x.Type == FtpFileSystemObjectType.Directory,
                            Modified = x.Modified,
                            Name = x.Name,
                            Size = x.Size
                        }).ToList());
                    } finally
                    {
                        await clientsQueue.Enqueue(c.Value, ct);
                    }
                };

                pending.Add(listFolderAsync(startPath, ctk));

                while (pending.Count > 0 && !ctk.IsCancellationRequested)
                {
                    var completedTask = await Task.WhenAny(pending).ConfigureAwait(false);

                    pending.Remove(completedTask);

                    // task could have completed with errors ... strange, let them progate.
                    var list = await completedTask.ConfigureAwait(false);

                    //we want to exclude folders . and .. that we dont want to search
                    foreach (var dir in list.Where(x => x.IsDirectory && !x.Name.Equals(".") && !x.Name.Equals("..")))
                    {
                        if (skipFolder.Invoke(dir))
                        {
                            _logger.Debug("Skipping folder: {0}", dir.FullPath);
                        }
                        else
                        {
                            pending.Add(listFolderAsync(dir.FullPath, ctk));
                        }
                    }

                    files = files.Concat(list.Where(x => !x.IsDirectory));
                }

                ctk.ThrowIfCancellationRequested();

                return(files.ToList());
            }
        }