public async Task WriteAsync(ulong offset, byte[] data) { using (var semLock = await _writeLock.LockAsync().ConfigureAwait(false)) { if (IsDone) { return; } await Target.WriteAsync(offset, data); WrittenBytes += (ulong)data.Length; Target.WrittenBytes = WrittenBytes; if (WrittenBytes == ExpectedBytes) { await Target.CompleteAsync().ConfigureAwait(false); IsDone = true; if (_handler.FileDownloaded != null) { _handler.RunEventHandler(() => _handler.FileDownloaded.Invoke(_handler, ManifestFile)); } } } }
/// <summary> /// Create an SSH connection to a remote machine. /// </summary> /// <param name="remoteSSHConnectionString"></param> /// <returns></returns> /// <remarks>Should only get called by the _connection initalizer</remarks> private async Task <SSHRecoveringConnection> CreateSSHConnectionTo(string remoteSSHConnectionString = null, Action <string> dumpLine = null) { // Use the default remoteSSHConnectionString = remoteSSHConnectionString ?? _machine.RemoteSSHConnectionString; Interlocked.Increment(ref NumberOfRecoveringConnections); if (_connectionLock != null) { throw new InvalidOperationException("Connection lock has already been aquired. Interal error"); } _connectionLock = await _gConnectionInterlockLimiter.LockAsync(); TraceHelpers.TraceInfo(25, $"CreateSSHConnectionTo: Aquired RemoteSSH Lock (free: {_gConnectionInterlockLimiter.CurrentCount})", opt: TraceEventType.Start); // Create a recovering connection return(new SSHRecoveringConnection(async() => { return await Policy .Handle <SSHConnectFailureException>() .WaitAndRetryAsync(new[] { TimeSpan.FromSeconds(10), TimeSpan.FromSeconds(10), TimeSpan.FromSeconds(60) }) .ExecuteAsync(async() => { var c = new SSHConnectionTunnel(remoteSSHConnectionString); Interlocked.Increment(ref NumberOfSSHTunnels); if (_machine.ConfigureLines != null) { var logForError = new StringBuilder(); try { // Don't dump setup unless the user really wants to see it! var localdumper = Environment.Verbose | Environment.CompileDebug ? dumpLine : (Action <string>)null; foreach (var line in _machine.ConfigureLines) { var rep = line.Replace("ROOTVersionNumber", ROOTVersionNumber); await c.ExecuteLinuxCommandAsync(rep, processLine: s => RecordLine(logForError, s, localdumper)); } } catch (Exception e) { c.Dispose(); string errMsg = ReformatLog(logForError); Trace.WriteLine($"Error making a SSH connection: {errMsg}"); throw new RemoteBashCommandFailureException($"Error making a SSH connection: {errMsg}", e); } } return c; }); })); }
public async Task WriteAsync(ulong offset, byte[] data) { using (var semLock = await _writeLock.LockAsync()) { await Target.WriteAsync(offset, data); WrittenBytes += (ulong)data.Length; Target.WrittenBytes = WrittenBytes; if (WrittenBytes == ExpectedBytes) { await Target.CompleteAsync(); } } }
public async Task Update() { // TODO: Ensure only one Update is running across all instances of SMA (in case SMA is closed during the update process) // TODO: Offer manual updates // TODO: Add option to wait for user confirmation to update if (UpdateEnabled == false) { return; } try { if (Wininet.HasNetworking() == false) { return; } CancellationTokenSource cts = new CancellationTokenSource(0); cts.Cancel(); using (await _semaphore.LockAsync(cts.Token)) using (var updateMgr = CreateUpdateMgr()) { State = SMAUpdateState.Fetching; var updateInfo = await updateMgr.CheckForUpdate(false, progress => ProgressPct = progress); if (updateInfo?.ReleasesToApply == null) { State = SMAUpdateState.Error; return; } if (updateInfo.ReleasesToApply.None()) { State = SMAUpdateState.UpToDate; return; } State = SMAUpdateState.Downloading; await updateMgr.DownloadReleases(updateInfo.ReleasesToApply, progress => ProgressPct = progress); State = SMAUpdateState.Applying; await updateMgr.ApplyReleases(updateInfo, progress => ProgressPct = progress); State = SMAUpdateState.CreatingUninstaller; await updateMgr.CreateUninstallerRegistryEntry(); State = SMAUpdateState.Updated; } } catch (TaskCanceledException) {} catch (Exception ex) // TODO: Update Squirrel UpdateManager to send sub-classed Exceptions { LogTo.Warning(ex, $"An exception was caught while {State.Name().ToLower()} update"); State = SMAUpdateState.Error; } finally { _semaphore.Release(); } }