Esempio n. 1
0
        /// <inheritdoc />
        protected sealed override async Task <IDmbProvider> PrepServerForLaunch(IDmbProvider dmbToUse, CancellationToken cancellationToken)
        {
            if (ActiveSwappable != null)
            {
                throw new InvalidOperationException("Expected activeSwappable to be null!");
            }
            if (startupDmbProvider != null)
            {
                throw new InvalidOperationException("Expected startupDmbProvider to be null!");
            }

            Logger.LogTrace("Prep for server launch. pendingSwappable is {0}available", pendingSwappable == null ? "not " : String.Empty);

            // Add another lock to the startup DMB because it'll be used throughout the lifetime of the watchdog
            startupDmbProvider = await DmbFactory.FromCompileJob(dmbToUse.CompileJob, cancellationToken).ConfigureAwait(false);

            pendingSwappable ??= new SwappableDmbProvider(dmbToUse, GameIOManager, symlinkFactory);
            ActiveSwappable  = pendingSwappable;
            pendingSwappable = null;

            try
            {
                await InitialLink(cancellationToken).ConfigureAwait(false);
            }
            catch
            {
                // We won't worry about disposing activeSwappable here as we can't dispose dmbToUse here.
                ActiveSwappable = null;
                throw;
            }

            return(ActiveSwappable);
        }
Esempio n. 2
0
        /// <inheritdoc />
        protected override async Task DisposeAndNullControllersImpl()
        {
            await base.DisposeAndNullControllersImpl().ConfigureAwait(false);

            // If we reach this point, we can guarantee PrepServerForLaunch will be called before starting again.
            ActiveSwappable = null;
            pendingSwappable?.Dispose();
            pendingSwappable = null;

            startupDmbProvider?.Dispose();
            startupDmbProvider = null;
        }
Esempio n. 3
0
        /// <inheritdoc />
        protected override MonitorAction HandleNormalReboot()
        {
            if (pendingSwappable != null)
            {
                Logger.LogTrace("Replacing activeSwappable with pendingSwappable...");
                Server.ReplaceDmbProvider(pendingSwappable);
                ActiveSwappable  = pendingSwappable;
                pendingSwappable = null;
            }
            else
            {
                Logger.LogTrace("Nothing to do as pendingSwappable is null.");
            }

            return(MonitorAction.Continue);
        }
        /// <inheritdoc />
        protected override async Task <MonitorAction> HandleNormalReboot(CancellationToken cancellationToken)
        {
            if (pendingSwappable != null)
            {
                var updateTask = BeforeApplyDmb(pendingSwappable.CompileJob, cancellationToken);
                Logger.LogTrace("Replacing activeSwappable with pendingSwappable...");
                Server.ReplaceDmbProvider(pendingSwappable);
                ActiveSwappable  = pendingSwappable;
                pendingSwappable = null;

                await updateTask.ConfigureAwait(false);
            }
            else
            {
                Logger.LogTrace("Nothing to do as pendingSwappable is null.");
            }

            return(MonitorAction.Continue);
        }
Esempio n. 5
0
        /// <inheritdoc />
        protected override async Task HandleNewDmbAvailable(CancellationToken cancellationToken)
        {
            IDmbProvider compileJobProvider = DmbFactory.LockNextDmb(1);
            bool         canSeamlesslySwap  = true;

            if (compileJobProvider.CompileJob.ByondVersion != ActiveCompileJob.ByondVersion)
            {
                // have to do a graceful restart
                Logger.LogDebug(
                    "Not swapping to new compile job {0} as it uses a different BYOND version ({1}) than what is currently active {2}. Queueing graceful restart instead...",
                    compileJobProvider.CompileJob.Id,
                    compileJobProvider.CompileJob.ByondVersion,
                    ActiveCompileJob.ByondVersion);
                canSeamlesslySwap = false;
            }

            if (compileJobProvider.CompileJob.DmeName != ActiveCompileJob.DmeName)
            {
                Logger.LogDebug(
                    "Not swapping to new compile job {0} as it uses a different .dmb name ({1}) than what is currently active {2}. Queueing graceful restart instead...",
                    compileJobProvider.CompileJob.Id,
                    compileJobProvider.CompileJob.DmeName,
                    ActiveCompileJob.DmeName);
                canSeamlesslySwap = false;
            }

            if (!canSeamlesslySwap)
            {
                compileJobProvider.Dispose();
                await base.HandleNewDmbAvailable(cancellationToken).ConfigureAwait(false);

                return;
            }

            SwappableDmbProvider windowsProvider = null;
            bool suspended = false;

            try
            {
                windowsProvider = new SwappableDmbProvider(compileJobProvider, GameIOManager, symlinkFactory);

                Logger.LogDebug("Swapping to compile job {0}...", windowsProvider.CompileJob.Id);
                try
                {
                    Server.Suspend();
                    suspended = true;
                }
                catch (Exception ex)
                {
                    Logger.LogWarning(ex, "Exception while suspending server!");
                }

                await windowsProvider.MakeActive(cancellationToken).ConfigureAwait(false);
            }
            catch (Exception ex)
            {
                Logger.LogError(ex, "Exception while swapping");
                IDmbProvider providerToDispose = windowsProvider ?? compileJobProvider;
                providerToDispose.Dispose();
                throw;
            }

            // Let this throw hard if it fails
            if (suspended)
            {
                Server.Resume();
            }

            pendingSwappable?.Dispose();
            pendingSwappable = windowsProvider;
        }