示例#1
0
                #pragma warning restore CA1506

        /// <inheritdoc />
        public async Task <ISessionController> Reattach(ReattachInformation reattachInformation, CancellationToken cancellationToken)
        {
            if (reattachInformation == null)
            {
                throw new ArgumentNullException(nameof(reattachInformation));
            }

            SessionController result    = null;
            var basePath                = reattachInformation.IsPrimary ? reattachInformation.Dmb.PrimaryDirectory : reattachInformation.Dmb.SecondaryDirectory;
            var chatJsonTrackingContext = await chat.TrackJsons(basePath, reattachInformation.ChatChannelsJson, reattachInformation.ChatCommandsJson, cancellationToken).ConfigureAwait(false);

            try
            {
                var byondLock = await byond.UseExecutables(Version.Parse(reattachInformation.Dmb.CompileJob.ByondVersion), cancellationToken).ConfigureAwait(false);

                try
                {
                    var context = new CommContext(ioManager, loggerFactory.CreateLogger <CommContext>(), basePath, reattachInformation.ServerCommandsJson);
                    try
                    {
                        var process = processExecutor.GetProcess(reattachInformation.ProcessId);

                        if (process != null)
                        {
                            try
                            {
                                networkPromptReaper.RegisterProcess(process);
                                result = new SessionController(reattachInformation, process, byondLock, byondTopicSender, chatJsonTrackingContext, context, chat, loggerFactory.CreateLogger <SessionController>(), null, null);

                                process   = null;
                                context   = null;
                                byondLock = null;
                                chatJsonTrackingContext = null;
                            }
                            finally
                            {
                                process?.Dispose();
                            }
                        }
                    }
                    finally
                    {
                        context?.Dispose();
                    }
                }
                finally
                {
                    byondLock?.Dispose();
                }
            }
            finally
            {
                chatJsonTrackingContext?.Dispose();
            }

            return(result);
        }
        /// <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);
        }