/// <inheritdoc /> public Task Save(ReattachInformation reattachInformation, CancellationToken cancellationToken) => databaseContextFactory.UseContext(async(db) => { if (reattachInformation == null) { throw new ArgumentNullException(nameof(reattachInformation)); } logger.LogDebug("Saving reattach information: {0}...", reattachInformation); await db .ReattachInformations .AsQueryable() .Where(x => x.CompileJob.Job.Instance.Id == metadata.Id) .DeleteAsync(cancellationToken) .ConfigureAwait(false); var dbReattachInfo = new Models.ReattachInformation { AccessIdentifier = reattachInformation.AccessIdentifier, CompileJobId = reattachInformation.Dmb.CompileJob.Id, Port = reattachInformation.Port, ProcessId = reattachInformation.ProcessId, RebootState = reattachInformation.RebootState, LaunchSecurityLevel = reattachInformation.LaunchSecurityLevel }; db.ReattachInformations.Add(dbReattachInfo); await db.Save(cancellationToken).ConfigureAwait(false); });
/// <summary> /// Construct a <see cref="ReattachInformation"/> from a given <paramref name="copy"/> and <paramref name="dmb"/> /// </summary> /// <param name="copy">The <see cref="Models.ReattachInformation"/> to copy values from</param> /// <param name="dmb">The value of <see cref="Dmb"/></param> /// <param name="topicRequestTimeout">The value of <see cref="TopicRequestTimeout"/>.</param> public ReattachInformation( Models.ReattachInformation copy, IDmbProvider dmb, TimeSpan topicRequestTimeout) : base(copy) { Dmb = dmb ?? throw new ArgumentNullException(nameof(dmb)); TopicRequestTimeout = topicRequestTimeout; runtimeInformationLock = new object(); }
/// <summary> /// Construct a <see cref="ReattachInformation"/> from a given <paramref name="copy"/> and <paramref name="dmb"/> /// </summary> /// <param name="copy">The <see cref="Models.ReattachInformation"/> to copy values from</param> /// <param name="dmb">The value of <see cref="Dmb"/></param> public ReattachInformation(Models.ReattachInformation copy, IDmbProvider dmb) : base(copy) { Dmb = dmb ?? throw new ArgumentNullException(nameof(dmb)); runtimeInformationLock = new object(); }
/// <inheritdoc /> public async Task <ReattachInformation> Load(CancellationToken cancellationToken) { Models.ReattachInformation result = null; TimeSpan?topicTimeout = null; await databaseContextFactory.UseContext(async (db) => { var dbReattachInfos = await db .ReattachInformations .AsQueryable() .Where(x => x.CompileJob.Job.Instance.Id == metadata.Id) .Include(x => x.CompileJob) .ToListAsync(cancellationToken).ConfigureAwait(false); result = dbReattachInfos.FirstOrDefault(); if (result == default) { return; } var timeoutMilliseconds = await db .Instances .AsQueryable() .Where(x => x.Id == metadata.Id) .Select(x => x.DreamDaemonSettings.TopicRequestTimeout) .FirstOrDefaultAsync(cancellationToken) .ConfigureAwait(false); if (timeoutMilliseconds == default) { logger.LogCritical("Missing TopicRequestTimeout!"); return; } topicTimeout = TimeSpan.FromMilliseconds(timeoutMilliseconds.Value); bool first = true; foreach (var reattachInfo in dbReattachInfos) { if (!first) { logger.LogWarning("Killing PID {0} associated with extra reattach information...", reattachInfo.ProcessId); try { using var process = processExecutor.GetProcess(reattachInfo.ProcessId); process.Terminate(); await process.Lifetime.ConfigureAwait(false); } catch (Exception ex) { logger.LogWarning(ex, "Failed to kill process!"); } } db.ReattachInformations.Remove(reattachInfo); first = false; } await db.Save(cancellationToken).ConfigureAwait(false); }).ConfigureAwait(false); if (!topicTimeout.HasValue) { logger.LogDebug("Reattach information not found!"); return(null); } var dmb = await dmbFactory.FromCompileJob(result.CompileJob, cancellationToken).ConfigureAwait(false); if (dmb == null) { logger.LogError("Unable to reattach! Could not load .dmb!"); return(null); } var info = new ReattachInformation( result, dmb, topicTimeout.Value); logger.LogDebug("Reattach information loaded: {0}", info); return(info); }