/// <summary>
 /// Initializes a new instance of the <see cref="DmbProvider"/> class.
 /// </summary>
 /// <param name="compileJob">The value of <see cref="CompileJob"/>.</param>
 /// <param name="ioManager">The value of <see cref="ioManager"/>.</param>
 /// <param name="onDispose">The value of <see cref="onDispose"/>.</param>
 /// <param name="directoryAppend">The optional value of <see cref="directoryAppend"/>.</param>
 public DmbProvider(CompileJob compileJob, IIOManager ioManager, Action onDispose, string directoryAppend = null)
 {
     CompileJob           = compileJob ?? throw new ArgumentNullException(nameof(compileJob));
     this.ioManager       = ioManager ?? throw new ArgumentNullException(nameof(ioManager));
     this.onDispose       = onDispose ?? throw new ArgumentNullException(nameof(onDispose));
     this.directoryAppend = directoryAppend ?? String.Empty;
 }
Example #2
0
        /// <inheritdoc />
        public async Task LoadCompileJob(CompileJob job, CancellationToken cancellationToken)
        {
            if (job == null)
            {
                throw new ArgumentNullException(nameof(job));
            }

            var newProvider = await FromCompileJob(job, cancellationToken).ConfigureAwait(false);

            if (newProvider == null)
            {
                return;
            }

            // Do this first, because it's entirely possible when we set the tcs it will immediately need to be applied
            if (started)
            {
                await gitHubDeploymentManager.StageDeployment(
                    newProvider.CompileJob,
                    cancellationToken)
                .ConfigureAwait(false);
            }

            lock (jobLockCounts)
            {
                nextDmbProvider?.Dispose();
                nextDmbProvider = newProvider;

                // Oh god dammit
                var temp = newerDmbTcs;
                newerDmbTcs = new TaskCompletionSource <object>();
                temp.SetResult(nextDmbProvider);
            }
        }
Example #3
0
 /// <inheritdoc />
 protected override string FormatTestMerge(
     RepositorySettings repositorySettings,
     CompileJob compileJob,
     TestMerge testMerge,
     string remoteRepositoryOwner,
     string remoteRepositoryName,
     bool updated) => String.Format(
     CultureInfo.InvariantCulture,
     "#### Test Merge {4}{0}{0}##### Server Instance{0}{5}{1}{0}{0}##### Revision{0}Origin: {6}{0}Pull Request: {2}{0}Server: {7}{3}{8}",
     Environment.NewLine,
     repositorySettings.ShowTestMergeCommitters.Value
                         ? String.Format(
         CultureInfo.InvariantCulture,
         "{0}{0}##### Merged By{0}{1}",
         Environment.NewLine,
         testMerge.MergedBy.Name)
                         : String.Empty,
     testMerge.TargetCommitSha,
     testMerge.Comment != null
                         ? String.Format(
         CultureInfo.InvariantCulture,
         "{0}{0}##### Comment{0}{1}",
         Environment.NewLine,
         testMerge.Comment)
                         : String.Empty,
     updated ? "Updated" : "Deployed",
     Metadata.Name,
     compileJob.RevisionInformation.OriginCommitSha,
     compileJob.RevisionInformation.CommitSha,
     compileJob.GitHubDeploymentId.HasValue
                         ? $"{Environment.NewLine}[GitHub Deployments](https://github.com/{remoteRepositoryOwner}/{remoteRepositoryName}/deployments/activity_log?environment=TGS%3A%20{Metadata.Name})"
                         : String.Empty);
Example #4
0
        public void Dispose() => cleanupCts.Dispose();         // we don't dispose nextDmbProvider here, since it might be the only thing we have

        /// <summary>
        /// Delete the <see cref="Api.Models.Internal.CompileJob.DirectoryName"/> of <paramref name="job"/>
        /// </summary>
        /// <param name="job">The <see cref="CompileJob"/> to clean</param>
        void CleanJob(CompileJob job)
        {
            async Task HandleCleanup()
            {
                var deleteJob = ioManager.DeleteDirectory(job.DirectoryName.ToString(), cleanupCts.Token);
                var remoteDeploymentManager = remoteDeploymentManagerFactory.CreateRemoteDeploymentManager(
                    metadata,
                    job);

                // DCT: None available
                var deploymentJob = remoteDeploymentManager.MarkInactive(job, default);
                var otherTask     = cleanupTask;
                await Task.WhenAll(otherTask, deleteJob, deploymentJob).ConfigureAwait(false);
            }

            lock (jobLockCounts)
                if (!jobLockCounts.TryGetValue(job.Id, out var currentVal) || currentVal == 1)
                {
                    jobLockCounts.Remove(job.Id);
                    logger.LogDebug("Cleaning lock-free compile job {0} => {1}", job.Id, job.DirectoryName);
                    cleanupTask = HandleCleanup();
                }
                else
                {
                    var decremented = --jobLockCounts[job.Id];
                    logger.LogTrace("Compile job {0} lock count now: {1}", job.Id, decremented);
                }
        }
Example #5
0
        /// <inheritdoc />
        public async Task LoadCompileJob(CompileJob job, CancellationToken cancellationToken)
        {
            if (job == null)
            {
                throw new ArgumentNullException(nameof(job));
            }

            CompileJob finalCompileJob = null;
            //now load the entire compile job tree
            await databaseContextFactory.UseContext(async db => finalCompileJob = await db.CompileJobs.Where(x => x.Id == job.Id)
                                                    .Include(x => x.Job).ThenInclude(x => x.StartedBy)
                                                    .Include(x => x.RevisionInformation).ThenInclude(x => x.PrimaryTestMerge).ThenInclude(x => x.MergedBy)
                                                    .Include(x => x.RevisionInformation).ThenInclude(x => x.ActiveTestMerges).ThenInclude(x => x.TestMerge).ThenInclude(x => x.MergedBy)
                                                    .FirstOrDefaultAsync(cancellationToken).ConfigureAwait(false)).ConfigureAwait(false); //can't wait to see that query

            if (finalCompileJob == null)
            {
                //lol git f****d
                return;
            }

            var newProvider = await FromCompileJob(finalCompileJob, cancellationToken).ConfigureAwait(false);

            if (newProvider == null)
            {
                return;
            }
            lock (this)
            {
                nextDmbProvider?.Dispose();
                nextDmbProvider = newProvider;
                newerDmbTcs.SetResult(nextDmbProvider);
                newerDmbTcs = new TaskCompletionSource <object>();
            }
        }
Example #6
0
 /// <inheritdoc />
 public Task PostDeploymentComments(
     CompileJob compileJob,
     RevisionInformation previousRevisionInformation,
     RepositorySettings repositorySettings,
     string repoOwner,
     string repoName,
     CancellationToken cancellationToken) => Task.CompletedTask;
 /// <summary>
 /// Formats a comment for a given <paramref name="testMerge"/>.
 /// </summary>
 /// <param name="repositorySettings">The <see cref="RepositorySettings"/> to use.</param>
 /// <param name="compileJob">The test merge's <see cref="CompileJob"/>.</param>
 /// <param name="testMerge">The <see cref="TestMerge"/>.</param>
 /// <param name="remoteRepositoryOwner">The <see cref="Api.Models.Internal.IGitRemoteInformation.RemoteRepositoryOwner"/>.</param>
 /// <param name="remoteRepositoryName">The <see cref="Api.Models.Internal.IGitRemoteInformation.RemoteRepositoryName"/>.</param>
 /// <param name="updated">If <see langword="false"/> <paramref name="testMerge"/> is new, otherwise it has been updated to a different <see cref="Api.Models.TestMergeParameters.TargetCommitSha"/>.</param>
 /// <returns>A <see cref="Task"/> representing the running operation.</returns>
 protected abstract string FormatTestMerge(
     RepositorySettings repositorySettings,
     CompileJob compileJob,
     TestMerge testMerge,
     string remoteRepositoryOwner,
     string remoteRepositoryName,
     bool updated);
Example #8
0
        public void Dispose() => cleanupCts.Dispose();         // we don't dispose nextDmbProvider here, since it might be the only thing we have

        /// <summary>
        /// Delete the <see cref="Api.Models.Internal.CompileJob.DirectoryName"/> of <paramref name="job"/>
        /// </summary>
        /// <param name="job">The <see cref="CompileJob"/> to clean</param>
        void CleanJob(CompileJob job)
        {
            async Task HandleCleanup()
            {
                var  deleteJob = ioManager.DeleteDirectory(job.DirectoryName.ToString(), cleanupCts.Token);
                Task otherTask;

                // lock (this) //already locked below
                otherTask = cleanupTask;
                await Task.WhenAll(otherTask, deleteJob).ConfigureAwait(false);
            }

            lock (this)
                if (!jobLockCounts.TryGetValue(job.Id, out var currentVal) || currentVal == 1)
                {
                    jobLockCounts.Remove(job.Id);
                    logger.LogDebug("Cleaning compile job {0} => {1}", job.Id, job.DirectoryName);
                    cleanupTask = HandleCleanup();
                }
                else
                {
                    var decremented = --jobLockCounts[job.Id];
                    logger.LogTrace("Compile job {0} lock count now: {1}", job.Id, decremented);
                }
        }
 /// <inheritdoc />
 protected override string FormatTestMerge(
     RepositorySettings repositorySettings,
     CompileJob compileJob,
     TestMerge testMerge,
     string remoteRepositoryOwner,
     string remoteRepositoryName,
     bool updated) => String.Format(
     CultureInfo.InvariantCulture,
     "#### Test Merge {4}{0}{0}##### Server Instance{0}{5}{1}{0}{0}##### Revision{0}Origin: {6}{0}Merge Request: {2}{0}Server: {7}{3}",
     Environment.NewLine,
     repositorySettings.ShowTestMergeCommitters.Value
                         ? String.Format(
         CultureInfo.InvariantCulture,
         "{0}{0}##### Merged By{0}{1}",
         Environment.NewLine,
         testMerge.MergedBy.Name)
                         : String.Empty,
     testMerge.TargetCommitSha,
     testMerge.Comment != null
                         ? String.Format(
         CultureInfo.InvariantCulture,
         "{0}{0}##### Comment{0}{1}",
         Environment.NewLine,
         testMerge.Comment)
                         : String.Empty,
     updated ? "Updated" : "Deployed",
     Metadata.Name,
     compileJob.RevisionInformation.OriginCommitSha,
     compileJob.RevisionInformation.CommitSha);
Example #10
0
        /// <inheritdoc />
        public async Task StartAsync(CancellationToken cancellationToken)
        {
            CompileJob cj = null;
            await databaseContextFactory.UseContext(async (db) =>
            {
                cj = await db
                     .CompileJobs
                     .AsQueryable()
                     .Where(x => x.Job.Instance.Id == metadata.Id)
                     .OrderByDescending(x => x.Job.StoppedAt)
                     .FirstOrDefaultAsync(cancellationToken)
                     .ConfigureAwait(false);
            })
            .ConfigureAwait(false);

            if (cj == default(CompileJob))
            {
                return;
            }
            await LoadCompileJob(cj, cancellationToken).ConfigureAwait(false);

            started = true;

            // we dont do CleanUnusedCompileJobs here because the watchdog may have plans for them yet
        }
 /// <inheritdoc />
 public Task StageDeployment(
     CompileJob compileJob,
     CancellationToken cancellationToken)
 => UpdateDeployment(
     compileJob,
     "The deployment succeeded and will be applied a the next server reboot.",
     DeploymentState.Pending,
     cancellationToken);
Example #12
0
        private static void CleanupCompile()
        {
            UdonSharpUtils.ClearAsyncProgressBar();
            
            EditorApplication.UnlockReloadAssemblies();

            CurrentJob = null;
        }
    public static int QueueCompileJob(string code, string[] assemblyPaths, bool sync = false)
    {
        CompileJob job = new CompileJob(NextJobId);

        compileJobs.Add(job);
        job.Start(code, assemblyPaths, sync);
        return(job.jobId);
    }
Example #14
0
                #pragma warning restore CA1506

        /// <inheritdoc />
                #pragma warning disable CA1506 // TODO: Decomplexify
        public async Task CleanUnusedCompileJobs(CompileJob exceptThisOne, CancellationToken cancellationToken)
        {
            List <long> jobIdsToSkip;

            // don't clean locked directories
            lock (this)
                jobIdsToSkip = jobLockCounts.Select(x => x.Key).ToList();

            List <string> jobUidsToNotErase = null;

            // find the uids of locked directories
            await databaseContextFactory.UseContext(async db =>
            {
                jobUidsToNotErase = await db.CompileJobs.Where(x => x.Job.Instance.Id == instance.Id && jobIdsToSkip.Contains(x.Id)).Select(x => x.DirectoryName.Value.ToString().ToUpperInvariant()).ToListAsync(cancellationToken).ConfigureAwait(false);
            }).ConfigureAwait(false);

            // add the other exemption
            if (exceptThisOne != null)
            {
                jobUidsToNotErase.Add(exceptThisOne.DirectoryName.Value.ToString().ToUpperInvariant());
            }

            // cleanup
            await ioManager.CreateDirectory(".", cancellationToken).ConfigureAwait(false);

            var directories = await ioManager.GetDirectories(".", cancellationToken).ConfigureAwait(false);

            int deleting = 0;
            var tasks    = directories.Select(async x =>
            {
                var nameOnly = ioManager.GetFileName(x);
                if (jobUidsToNotErase.Contains(nameOnly.ToUpperInvariant()))
                {
                    return;
                }
                try
                {
                    ++deleting;
                    await ioManager.DeleteDirectory(x, cancellationToken).ConfigureAwait(false);
                }
                catch (OperationCanceledException)
                {
                    throw;
                }
                catch (Exception e)
                {
                    logger.LogWarning("Error deleting directory {0}! Exception: {1}", x, e);
                }
            }).ToList();

            if (deleting > 0)
            {
                logger.LogDebug("Cleaning {0} unused game folders...", deleting);
                await Task.WhenAll().ConfigureAwait(false);
            }
        }
        async Task UpdateDeployment(
            CompileJob compileJob,
            string description,
            DeploymentState deploymentState,
            CancellationToken cancellationToken)
        {
            if (compileJob == null)
            {
                throw new ArgumentNullException(nameof(compileJob));
            }

            if (!compileJob.GitHubRepoId.HasValue || !compileJob.GitHubDeploymentId.HasValue)
            {
                logger.LogTrace("Not updating deployment as it is missing a repo ID or deployment ID.");
                return;
            }

            logger.LogTrace("Updating deployment {0} to {1}...", compileJob.GitHubDeploymentId.Value, deploymentState);

            string gitHubAccessToken = null;
            await databaseContextFactory.UseContext(
                async databaseContext =>
                gitHubAccessToken = await databaseContext
                .RepositorySettings
                .AsQueryable()
                .Where(x => x.InstanceId == metadata.Id)
                .Select(x => x.AccessToken)
                .FirstAsync(cancellationToken)
                .ConfigureAwait(false))
            .ConfigureAwait(false);

            if (gitHubAccessToken == null)
            {
                logger.LogWarning(
                    "GitHub access token disappeared during deployment, can't update to {0}!",
                    deploymentState);
                return;
            }

            var gitHubClient = gitHubClientFactory.CreateClient(gitHubAccessToken);

            await gitHubClient
            .Repository
            .Deployment
            .Status
            .Create(
                compileJob.GitHubRepoId.Value,
                compileJob.GitHubDeploymentId.Value,
                new NewDeploymentStatus(deploymentState)
            {
                Description = description
            })
            .WithToken(cancellationToken)
            .ConfigureAwait(false);
        }
Example #16
0
        async Task CheckDMApiFail(CompileJob compileJob, CancellationToken cancellationToken)
        {
            var failFile = Path.Combine(instanceClient.Metadata.Path, "Game", compileJob.DirectoryName.Value.ToString(), "A", Path.GetDirectoryName(compileJob.DmeName), "test_fail_reason.txt");

            if (!File.Exists(failFile))
            {
                return;
            }

            var text = await File.ReadAllTextAsync(failFile, cancellationToken);

            Assert.Fail(text);
        }
Example #17
0
        /// <inheritdoc />
        public async Task <IDmbProvider> FromCompileJob(CompileJob compileJob, CancellationToken cancellationToken)
        {
            logger.LogTrace("Loading compile job {0}...", compileJob.Id);
            var providerSubmitted = false;
            var newProvider       = new DmbProvider(compileJob, ioManager, () =>
            {
                if (providerSubmitted)
                {
                    CleanJob(compileJob);
                }
            });

            try
            {
                var primaryCheckTask   = ioManager.FileExists(ioManager.ConcatPath(newProvider.PrimaryDirectory, newProvider.DmbName), cancellationToken);
                var secondaryCheckTask = ioManager.FileExists(ioManager.ConcatPath(newProvider.PrimaryDirectory, newProvider.DmbName), cancellationToken);

                if (!(await primaryCheckTask.ConfigureAwait(false) && await secondaryCheckTask.ConfigureAwait(false)))
                {
                    logger.LogWarning("Error loading compile job, .dmb missing!");
                    return(null);                       //omae wa mou shinderu
                }

                lock (this)
                {
                    if (!jobLockCounts.TryGetValue(compileJob.Id, out int value))
                    {
                        value = 1;
                        jobLockCounts.Add(compileJob.Id, 1);
                    }
                    else
                    {
                        jobLockCounts[compileJob.Id] = ++value;
                    }

                    logger.LogTrace("Compile job {0} lock count now: {1}", compileJob.Id, value);

                    providerSubmitted = true;
                    return(newProvider);
                }
            }
            finally
            {
                if (!providerSubmitted)
                {
                    newProvider.Dispose();
                }
            }
        }
        /// <inheritdoc />
        public async Task StartAsync(CancellationToken cancellationToken)
        {
            await Task.WhenAll(SetAutoUpdateInterval(metadata.AutoUpdateInterval.Value), Configuration.StartAsync(cancellationToken), ByondManager.StartAsync(cancellationToken), Chat.StartAsync(cancellationToken), compileJobConsumer.StartAsync(cancellationToken)).ConfigureAwait(false);

            // dependent on so many things, its just safer this way
            await Watchdog.StartAsync(cancellationToken).ConfigureAwait(false);

            CompileJob latestCompileJob = null;
            await databaseContextFactory.UseContext(async db =>
            {
                latestCompileJob = await db.CompileJobs.Where(x => x.Job.Instance.Id == metadata.Id).OrderByDescending(x => x.Job.StoppedAt).FirstOrDefaultAsync(cancellationToken).ConfigureAwait(false);
            }).ConfigureAwait(false);

            await dmbFactory.CleanUnusedCompileJobs(latestCompileJob, cancellationToken).ConfigureAwait(false);
        }
    public static bool TryGetJobResult(int jobId, out CompileJobStatus result, out string outputFilePath)
    {
        CompileJob job = compileJobs.Find((j) => {
            return(j.jobId == jobId);
        });

        if (job == null)
        {
            result         = CompileJobStatus.Invalid;
            outputFilePath = null;
            return(false);
        }
        result         = job.status;
        outputFilePath = job.path + ".dll";
        return(true);
    }
Example #20
0
        /// <inheritdoc />
        public async Task StartAsync(CancellationToken cancellationToken)
        {
            CompileJob cj = null;
            await databaseContextFactory.UseContext(async (db) =>
            {
                cj = await db
                     .MostRecentCompletedCompileJobOrDefault(instance, cancellationToken)
                     .ConfigureAwait(false);
            })
            .ConfigureAwait(false);

            if (cj == default(CompileJob))
            {
                return;
            }
            await LoadCompileJob(cj, cancellationToken).ConfigureAwait(false);

            // we dont do CleanUnusedCompileJobs here because the watchdog may have plans for them yet
        }
Example #21
0
        /// <inheritdoc />
        public async Task LoadCompileJob(CompileJob job, CancellationToken cancellationToken)
        {
            if (job == null)
            {
                throw new ArgumentNullException(nameof(job));
            }

            var newProvider = await FromCompileJob(job, cancellationToken).ConfigureAwait(false);

            if (newProvider == null)
            {
                return;
            }
            lock (this)
            {
                nextDmbProvider?.Dispose();
                nextDmbProvider = newProvider;
                newerDmbTcs.SetResult(nextDmbProvider);
                newerDmbTcs = new TaskCompletionSource <object>();
            }
        }
    public static Type CreateScriptableType(string code, string[] assemblyPaths, string typeName = "GeneratedScriptable")
    {
        CompileJob job = new CompileJob(NextJobId);

        compileJobs.Add(job);
        job.Start(code, assemblyPaths, true);
        CompileJobStatus result;
        string           dllPath;

        if (TryGetJobResult(job.jobId, out result, out dllPath))
        {
            if (result == CompileJobStatus.Succeeded)
            {
                Assembly assembly = Assembly.LoadFrom(dllPath);
                try {
                    File.Delete(dllPath);
                }
                catch { }
                return(assembly.GetType(typeName));
            }
        }
        return(null);
    }
Example #23
0
        /// <inheritdoc />
                #pragma warning disable CA1506 // TODO: Decomplexify
        public async Task <IDmbProvider> FromCompileJob(CompileJob compileJob, CancellationToken cancellationToken)
        {
            if (compileJob == null)
            {
                throw new ArgumentNullException(nameof(compileJob));
            }

            // ensure we have the entire metadata tree
            logger.LogTrace("Loading compile job {0}...", compileJob.Id);
            await databaseContextFactory.UseContext(
                async db => compileJob = await db
                .CompileJobs
                .AsQueryable()
                .Where(x => x.Id == compileJob.Id)
                .Include(x => x.Job)
                .ThenInclude(x => x.StartedBy)
                .Include(x => x.RevisionInformation)
                .ThenInclude(x => x.PrimaryTestMerge)
                .ThenInclude(x => x.MergedBy)
                .Include(x => x.RevisionInformation)
                .ThenInclude(x => x.ActiveTestMerges)
                .ThenInclude(x => x.TestMerge)
                .ThenInclude(x => x.MergedBy)
                .FirstAsync(cancellationToken)
                .ConfigureAwait(false))
            .ConfigureAwait(false);                     // can't wait to see that query

            if (!compileJob.Job.StoppedAt.HasValue)
            {
                // This happens when we're told to load the compile job that is currently finished up
                // It constitutes an API violation if it's returned by the DreamDaemonController so just set it here
                // Bit of a hack, but it works out to be nearly if not the same value that's put in the DB
                logger.LogTrace("Setting missing StoppedAt for CompileJob.Job #{0}...", compileJob.Job.Id);
                compileJob.Job.StoppedAt = DateTimeOffset.UtcNow;
            }

            var providerSubmitted = false;

            void CleanupAction()
            {
                if (providerSubmitted)
                {
                    CleanJob(compileJob);
                }
            }

            var newProvider = new DmbProvider(compileJob, ioManager, CleanupAction);

            try
            {
                const string LegacyADirectoryName = "A";
                const string LegacyBDirectoryName = "B";

                var dmbExistsAtRoot = await ioManager.FileExists(
                    ioManager.ConcatPath(
                        newProvider.Directory,
                        newProvider.DmbName),
                    cancellationToken)
                                      .ConfigureAwait(false);

                if (!dmbExistsAtRoot)
                {
                    logger.LogTrace("Didn't find .dmb at game directory root, checking A/B dirs...");
                    var primaryCheckTask = ioManager.FileExists(
                        ioManager.ConcatPath(
                            newProvider.Directory,
                            LegacyADirectoryName,
                            newProvider.DmbName),
                        cancellationToken);
                    var secondaryCheckTask = ioManager.FileExists(
                        ioManager.ConcatPath(
                            newProvider.Directory,
                            LegacyBDirectoryName,
                            newProvider.DmbName),
                        cancellationToken);

                    if (!(await primaryCheckTask.ConfigureAwait(false) && await secondaryCheckTask.ConfigureAwait(false)))
                    {
                        logger.LogWarning("Error loading compile job, .dmb missing!");
                        return(null);                        // omae wa mou shinderu
                    }

                    // rebuild the provider because it's using the legacy style directories
                    // Don't dispose it
                    logger.LogDebug("Creating legacy two folder .dmb provider targeting {0} directory...", LegacyADirectoryName);
                    newProvider = new DmbProvider(compileJob, ioManager, CleanupAction, Path.DirectorySeparatorChar + LegacyADirectoryName);
                }

                lock (jobLockCounts)
                {
                    if (!jobLockCounts.TryGetValue(compileJob.Id, out int value))
                    {
                        value = 1;
                        jobLockCounts.Add(compileJob.Id, 1);
                    }
                    else
                    {
                        jobLockCounts[compileJob.Id] = ++value;
                    }

                    providerSubmitted = true;

                    logger.LogTrace("Compile job {0} lock count now: {1}", compileJob.Id, value);
                    return(newProvider);
                }
            }
            finally
            {
                if (!providerSubmitted)
                {
                    newProvider.Dispose();
                }
            }
        }
 /// <inheritdoc />
 public override Task StartDeployment(
     Api.Models.Internal.IGitRemoteInformation remoteInformation,
     CompileJob compileJob,
     CancellationToken cancellationToken) => Task.CompletedTask;
 /// <inheritdoc />
 public override Task StageDeployment(CompileJob compileJob, CancellationToken cancellationToken) => Task.CompletedTask;
 /// <inheritdoc />
 public override Task MarkInactive(CompileJob compileJob, CancellationToken cancellationToken) => Task.CompletedTask;
 /// <inheritdoc />
 public override Task FailDeployment(
     CompileJob compileJob,
     string errorMessage,
     CancellationToken cancellationToken) => Task.CompletedTask;
 /// <inheritdoc />
 public override Task ApplyDeployment(
     CompileJob compileJob,
     CompileJob oldCompileJob, CancellationToken cancellationToken) => Task.CompletedTask;
 public static int QueueCompileJob(string code, string[] assemblyPaths, bool sync = false) {
     CompileJob job = new CompileJob(NextJobId);
     compileJobs.Add(job);
     job.Start(code, assemblyPaths, sync);
     return job.jobId;
 }
Example #30
0
        /// <inheritdoc />
                #pragma warning disable CA1506 // TODO: Decomplexify
        public async Task <IDmbProvider> FromCompileJob(CompileJob compileJob, CancellationToken cancellationToken)
        {
            if (compileJob == null)
            {
                throw new ArgumentNullException(nameof(compileJob));
            }

            // ensure we have the entire compile job tree
            await databaseContextFactory.UseContext(async db => compileJob = await db.CompileJobs.Where(x => x.Id == compileJob.Id)
                                                    .Include(x => x.Job).ThenInclude(x => x.StartedBy)
                                                    .Include(x => x.RevisionInformation).ThenInclude(x => x.PrimaryTestMerge).ThenInclude(x => x.MergedBy)
                                                    .Include(x => x.RevisionInformation).ThenInclude(x => x.ActiveTestMerges).ThenInclude(x => x.TestMerge).ThenInclude(x => x.MergedBy)
                                                    .FirstAsync(cancellationToken).ConfigureAwait(false)).ConfigureAwait(false); // can't wait to see that query

            logger.LogTrace("Loading compile job {0}...", compileJob.Id);
            var providerSubmitted = false;
            var newProvider       = new DmbProvider(compileJob, ioManager, () =>
            {
                if (providerSubmitted)
                {
                    CleanJob(compileJob);
                }
            });

            try
            {
                var primaryCheckTask   = ioManager.FileExists(ioManager.ConcatPath(newProvider.PrimaryDirectory, newProvider.DmbName), cancellationToken);
                var secondaryCheckTask = ioManager.FileExists(ioManager.ConcatPath(newProvider.PrimaryDirectory, newProvider.DmbName), cancellationToken);

                if (!(await primaryCheckTask.ConfigureAwait(false) && await secondaryCheckTask.ConfigureAwait(false)))
                {
                    logger.LogWarning("Error loading compile job, .dmb missing!");
                    return(null);                    // omae wa mou shinderu
                }

                lock (this)
                {
                    if (!jobLockCounts.TryGetValue(compileJob.Id, out int value))
                    {
                        value = 1;
                        jobLockCounts.Add(compileJob.Id, 1);
                    }
                    else
                    {
                        jobLockCounts[compileJob.Id] = ++value;
                    }

                    logger.LogTrace("Compile job {0} lock count now: {1}", compileJob.Id, value);

                    providerSubmitted = true;
                    return(newProvider);
                }
            }
            finally
            {
                if (!providerSubmitted)
                {
                    newProvider.Dispose();
                }
            }
        }
    public static Type CreateScriptableType(string code, string[] assemblyPaths, string typeName = "GeneratedScriptable") {
        CompileJob job = new CompileJob(NextJobId);
        compileJobs.Add(job);
        job.Start(code, assemblyPaths, true);
        CompileJobStatus result;
        string dllPath;
        if (TryGetJobResult(job.jobId, out result, out dllPath)) {
            if (result == CompileJobStatus.Succeeded) {
				Assembly assembly = Assembly.LoadFrom(dllPath);
                try {
                    File.Delete(dllPath);
                }
                catch { }
				return assembly.GetType(typeName);
            }
        }
        return null;
    }
Example #32
0
 /// <summary>
 /// Construct a <see cref="TemporaryDmbProvider"/>
 /// </summary>
 /// <param name="directory">The value of <see cref="Directory"/></param>
 /// <param name="dmb">The value of <see cref="DmbName"/></param>
 /// <param name="compileJob">The value of <see cref="CompileJob"/></param>
 public TemporaryDmbProvider(string directory, string dmb, CompileJob compileJob)
 {
     DmbName    = dmb ?? throw new ArgumentNullException(nameof(dmb));
     Directory  = directory ?? throw new ArgumentNullException(nameof(directory));
     CompileJob = compileJob ?? throw new ArgumentNullException(nameof(compileJob));
 }