diff options
| author | Avi Levkovich <avi@twine-s.com> | 2020-03-25 17:46:56 +0200 |
|---|---|---|
| committer | Avi Levkovich <avi@twine-s.com> | 2020-03-25 17:46:56 +0200 |
| commit | aa732a33f7c63ce4438ec2b79fedb641ffd22b05 (patch) | |
| tree | 86ccf57c1dfb6801de16f15d681539c02b007508 /Software/Visual_Studio/FSE/Tango.FSE.UI/FileSystem/DefaultFileSystemProvider.cs | |
| parent | d29da53d6f71f45749c0ede5b4cd7281ed3a270e (diff) | |
| parent | 8f57d4962fa84499c8a153ebfff6e7766434ee1c (diff) | |
| download | Tango-aa732a33f7c63ce4438ec2b79fedb641ffd22b05.tar.gz Tango-aa732a33f7c63ce4438ec2b79fedb641ffd22b05.zip | |
merge conflicts -take remote
Diffstat (limited to 'Software/Visual_Studio/FSE/Tango.FSE.UI/FileSystem/DefaultFileSystemProvider.cs')
| -rw-r--r-- | Software/Visual_Studio/FSE/Tango.FSE.UI/FileSystem/DefaultFileSystemProvider.cs | 235 |
1 files changed, 231 insertions, 4 deletions
diff --git a/Software/Visual_Studio/FSE/Tango.FSE.UI/FileSystem/DefaultFileSystemProvider.cs b/Software/Visual_Studio/FSE/Tango.FSE.UI/FileSystem/DefaultFileSystemProvider.cs index bcc39d11d..6f25e1774 100644 --- a/Software/Visual_Studio/FSE/Tango.FSE.UI/FileSystem/DefaultFileSystemProvider.cs +++ b/Software/Visual_Studio/FSE/Tango.FSE.UI/FileSystem/DefaultFileSystemProvider.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using System.Diagnostics; using System.IO; using System.IO.Compression; using System.Linq; @@ -13,16 +14,109 @@ using Tango.FileSystem.Network; using Tango.FSE.Common.Connection; using Tango.FSE.Common.FileSystem; using Tango.Transport; +using Tango.Transport.Transporters; +using Tango.WebRTC; namespace Tango.FSE.UI.FileSystem { public class DefaultFileSystemProvider : ExtendedObject, IFileSystemProvider { private IMachineProvider _machineProvider; + private BasicTransporter _webRtcTransporter; + private const string WEB_RTC_CHANNEL_NAME = "FileSystemChannel"; + private const long MAX_CHUNK_SIZE = 1024 * 10; + private const long MAX_CHUNK_SIZE_WEB_RTC = 1024 * 50; + private const int WEB_RTC_MAX_RETRIES = 8; + private List<FileSystemHandler> _activeHandlers; + + private bool _enableWebRTC; + public bool EnableWebRTC + { + get { return _enableWebRTC; } + set { _enableWebRTC = value; RaisePropertyChangedAuto(); } + } + + private bool _isWebRtcAvailable; + public bool IsWebRtcAvailable + { + get { return _isWebRtcAvailable; } + private set { _isWebRtcAvailable = value; RaisePropertyChangedAuto(); } + } public DefaultFileSystemProvider(IMachineProvider machineProvider) { + _activeHandlers = new List<FileSystemHandler>(); + + EnableWebRTC = true; //TODO: From Settings.. _machineProvider = machineProvider; + _machineProvider.MachineConnected += _machineProvider_MachineConnected; + _machineProvider.MachineDisconnected += _machineProvider_MachineDisconnected; + } + + private async void _machineProvider_MachineDisconnected(object sender, MachineDisconnectedEventArgs e) + { + IsWebRtcAvailable = false; + + foreach (var handler in _activeHandlers.ToList()) + { + try + { + handler.RaiseFailed(new TransporterDisconnectedException("Machine disconnected.")); + } + catch (Exception ex) + { + Debug.WriteLine(ex); + } + } + + _activeHandlers.Clear(); + + if (_webRtcTransporter != null) + { + try + { + LogManager.Log("Machine disconnected. Disconnecting FileSystem WebRTC Transporter..."); + await _webRtcTransporter.Disconnect(); + } + catch (Exception ex) + { + LogManager.Log(ex, "Error while disconnecting FileSystem WebRTC Transporter."); + } + } + } + + private async void _machineProvider_MachineConnected(object sender, MachineConnectedEventArgs e) + { + if (EnableWebRTC) + { + try + { + IsWebRtcAvailable = false; + + await _machineProvider.MachineOperator.SendGenericRequest<InitWebRtcRequest, InitWebRtcResponse>(new InitWebRtcRequest() + { + DataChannelName = WEB_RTC_CHANNEL_NAME + }, new TransportRequestConfig() + { + Timeout = TimeSpan.FromSeconds(60), + Priority = QueuePriority.Low + }); + + _webRtcTransporter = new BasicTransporter(new WebRtcTransportAdapter(_machineProvider.MachineOperator, WebRtcTransportAdapterMode.Active, WEB_RTC_CHANNEL_NAME)); + _webRtcTransporter.UseKeepAlive = false; + _webRtcTransporter.ComponentName = "File System Active WebRTC Transporter"; + await _webRtcTransporter.Connect(); + + IsWebRtcAvailable = true; + + LogManager.Log("FileSystem via WebRTC is ready."); + } + catch (Exception ex) + { + IsWebRtcAvailable = false; + LogManager.Log(ex, "Error initializing FileSystem via WebRTC."); + } + } } public async Task<IFileSystemContainer> GetFolder(string path) @@ -100,6 +194,8 @@ namespace Tango.FSE.UI.FileSystem } }); + _activeHandlers.Add(handler); + ThreadFactory.StartNew(async () => { try @@ -135,11 +231,14 @@ namespace Tango.FSE.UI.FileSystem } catch (Exception ex) { + _activeHandlers.Remove(handler); handler.RaiseFailed(ex); return; } long position = 0; + bool webRtcFailed = false; + int webRtcRetries = WEB_RTC_MAX_RETRIES; var tempFile = TemporaryManager.CreateFile(); @@ -153,13 +252,48 @@ namespace Tango.FSE.UI.FileSystem try { - var response = await _machineProvider.MachineOperator.SendGenericRequest<ChunkDownloadRequest, ChunkDownloadResponse>( - new ChunkDownloadRequest() + ChunkDownloadResponse response = null; + ChunkDownloadRequest request = new ChunkDownloadRequest() { - MaxChunkSize = 1024 * 10, + MaxChunkSize = MAX_CHUNK_SIZE, OperationId = operationId, Position = position, - }, new TransportRequestConfig() { Timeout = TimeSpan.FromSeconds(30), Priority = QueuePriority.Low }); + }; + + if (_webRtcTransporter != null && _webRtcTransporter.State == TransportComponentState.Connected && EnableWebRTC && !webRtcFailed) + { + try + { + request.MaxChunkSize = MAX_CHUNK_SIZE_WEB_RTC; + response = await _webRtcTransporter.SendGenericRequest<ChunkDownloadRequest, ChunkDownloadResponse>(request, new TransportRequestConfig() + { + Timeout = TimeSpan.FromSeconds(2), + Priority = QueuePriority.Low + }); + + webRtcRetries = WEB_RTC_MAX_RETRIES; + } + catch (Exception ex) + { + webRtcRetries--; + + if (webRtcRetries == 0) + { + webRtcFailed = true; + LogManager.Log(ex, "WebRTC chunk download failed. Falling back to standard download..."); + } + + continue; + } + } + else + { + response = await _machineProvider.MachineOperator.SendGenericRequest<ChunkDownloadRequest, ChunkDownloadResponse>(request, new TransportRequestConfig() + { + Timeout = TimeSpan.FromSeconds(30), + Priority = QueuePriority.Low + }); + } using (FileStream fs = new FileStream(tempFile, FileMode.Append)) { @@ -171,6 +305,7 @@ namespace Tango.FSE.UI.FileSystem } catch (Exception ex) { + _activeHandlers.Remove(handler); tempFile.Delete(); handler.RaiseFailed(ex); return; @@ -203,6 +338,8 @@ namespace Tango.FSE.UI.FileSystem { tempFile.Delete(); } + + _activeHandlers.Remove(handler); }); return Task.FromResult(handler); @@ -212,5 +349,95 @@ namespace Tango.FSE.UI.FileSystem { throw new NotImplementedException(); } + + public async Task Copy(FileSystemItem source, FileSystemItem target) + { + if (source.Type == FileSystemItemType.Drive) + { + throw new NotSupportedException("The source file system item is not supported for copying."); + } + if (target.Type == FileSystemItemType.File) + { + throw new NotSupportedException("The target file system item is not a valid container."); + } + + await _machineProvider.MachineOperator.SendGenericRequest<CopyRequest, CopyResponse>(new CopyRequest() + { + + Source = source.Path, + Destination = Path.Combine(target.Path, source.Name) + + }, new TransportRequestConfig() + { + Timeout = TimeSpan.FromSeconds(120), + }); + } + + public async Task Move(FileSystemItem source, FileSystemItem target) + { + if (source.Type == FileSystemItemType.Drive) + { + throw new NotSupportedException("The source file system item is not supported for copying."); + } + if (target.Type == FileSystemItemType.File) + { + throw new NotSupportedException("The target file system item is not a valid container."); + } + + await _machineProvider.MachineOperator.SendGenericRequest<MoveRequest, MoveResponse>(new MoveRequest() + { + + Source = source.Path, + Destination = Path.Combine(target.Path, source.Name) + + }, new TransportRequestConfig() + { + Timeout = TimeSpan.FromSeconds(120), + }); + } + + public async Task Rename(FileSystemItem source, string newName) + { + if (source.Type == FileSystemItemType.Drive) + { + throw new NotSupportedException("The source file system item is not supported for copying."); + } + if (newName.ToList().Exists(x => Path.GetInvalidFileNameChars().Contains(x))) + { + throw new ArgumentException("The new name contains invalid characters."); + } + + await _machineProvider.MachineOperator.SendGenericRequest<MoveRequest, MoveResponse>(new MoveRequest() + { + + Source = source.Path, + Destination = Path.Combine(Path.GetDirectoryName(source.Path), newName) + + }); + } + + public async Task Delete(FileSystemItem item) + { + if (item.Type == FileSystemItemType.Drive) + { + throw new NotSupportedException("The source file system item is not supported for deletion."); + } + + await _machineProvider.MachineOperator.SendGenericRequest<DeleteRequest, DeleteResponse>(new DeleteRequest() + { + Path = item.Path + }, new TransportRequestConfig() { Timeout = TimeSpan.FromSeconds(120) }); + } + + public async Task<FolderItem> CreateFolder(FileSystemItem parent, string folderName) + { + var response = await _machineProvider.MachineOperator.SendGenericRequest<CreateFolderRequest, CreateFolderResponse>(new CreateFolderRequest() + { + Path = parent.Path, + FolderName = folderName, + }); + + return FileSystemItem.FromDTO(response.FolderItem) as FolderItem; + } } } |
