aboutsummaryrefslogtreecommitdiffstats
path: root/Software/Visual_Studio/FSE/Tango.FSE.UI/FileSystem/DefaultFileSystemProvider.cs
diff options
context:
space:
mode:
authorAvi Levkovich <avi@twine-s.com>2020-03-25 17:46:56 +0200
committerAvi Levkovich <avi@twine-s.com>2020-03-25 17:46:56 +0200
commitaa732a33f7c63ce4438ec2b79fedb641ffd22b05 (patch)
tree86ccf57c1dfb6801de16f15d681539c02b007508 /Software/Visual_Studio/FSE/Tango.FSE.UI/FileSystem/DefaultFileSystemProvider.cs
parentd29da53d6f71f45749c0ede5b4cd7281ed3a270e (diff)
parent8f57d4962fa84499c8a153ebfff6e7766434ee1c (diff)
downloadTango-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.cs235
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;
+ }
}
}