Exemple #1
0
        protected override async Task ExecuteAsync(CancellationToken stoppingToken)
        {
            using var scope = _factory.CreateScope();
            _logger.LogInformation($"Worker {_options.Value.Name} is starting");

            #region Initialize Hostname and Box

            var process = new Process
            {
                StartInfo = new ProcessStartInfo
                {
                    FileName  = "/bin/hostname",
                    Arguments = "-i",
                    RedirectStandardOutput = true
                }
            };
            process.Start();
            await process.WaitForExitAsync();

            if (process.ExitCode != 0)
            {
                throw new Exception($"E: Cannot obtain hostname, exit code {process.ExitCode}.");
            }

            var hostname = process.StandardOutput.ReadToEnd().Trim();
            var boxId    = hostname.Split('.').ToList().Last();
            _options.Value.Name = _options.Value.Name + '-' + boxId;
            Box.InitBoxAsync(boxId); // Use ip obtained by hostname as the unique ID of worker
            _logger.LogInformation($"Worker works at {hostname}, renaming to {_options.Value.Name}");

            #endregion

            #region Initialize RabbitMq

            var factory           = new RabbitMqConnectionFactory(scope.ServiceProvider);
            var requestConsumer   = scope.ServiceProvider.GetRequiredService <JobRequestConsumer>();
            var completeProducer  = scope.ServiceProvider.GetRequiredService <JobCompleteProducer>();
            var heartbeatProducer = scope.ServiceProvider.GetRequiredService <WorkerHeartbeatProducer>();

            var connection = factory.GetConnection();
            if (!stoppingToken.IsCancellationRequested) // Application may be aborted in GetConnection().
            {
                heartbeatProducer.Start(connection);
                completeProducer.Start(connection);
                requestConsumer.Start(connection);
            }

            #endregion

            while (!stoppingToken.IsCancellationRequested)
            {
                await Task.Delay(1000, stoppingToken);
            }

            _logger.LogInformation($"Worker {_options.Value.Name} is stopping");
            requestConsumer.Stop();
            completeProducer.Stop();
            heartbeatProducer.Stop();
            factory.CloseConnection();
        }
Exemple #2
0
        // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
        public void Configure(IApplicationBuilder app, IWebHostEnvironment env, IServiceProvider provider,
                              IHostApplicationLifetime lifetime)
        {
            ConfigureDatabase(provider).Wait();

            app.Use(async(ctx, next) =>
            {
                ctx.SetIdentityServerOrigin(Configuration["Application:Host"]);
                await next();
            });

            if (env.IsDevelopment())
            {
                app.UseDeveloperExceptionPage();
                app.UseMigrationsEndPoint(); // https://github.com/aspnet/Announcements/issues/432
            }
            else
            {
                app.UseExceptionHandler("/Error");
                // app.UseHsts();
            }

            // app.UseHttpsRedirection();
            app.UseStaticFiles(); // wwwroot

            if (!env.IsDevelopment())
            {
                app.UseSpaStaticFiles();
            }

            app.UseRouting();
            app.UseCors("default");

            app.UseAuthentication()
            .UseCookiePolicy(new CookiePolicyOptions
            {
                MinimumSameSitePolicy = SameSiteMode.Lax
            });
            app.UseIdentityServer();
            app.UseAuthorization();

            // Handle plagiarism report static files.
            // This should come after UseAuthorization() for auth.
            var options           = provider.GetRequiredService <IOptions <ApplicationConfig> >();
            var plagiarismsFolder = Path.Combine(options.Value.DataPath, "plagiarisms");

            if (!Directory.Exists(plagiarismsFolder))
            {
                Directory.CreateDirectory(plagiarismsFolder);
            }
            app.UseStaticFiles(new StaticFileOptions
            {
                FileProvider      = new PhysicalFileProvider(plagiarismsFolder),
                RequestPath       = "/plagiarisms",
                OnPrepareResponse = async(ctx) =>
                {
                    var authorized = ctx.Context.User.IsAuthenticated() &&
                                     (ctx.Context.User.IsInRole(ApplicationRoles.Administrator) ||
                                      ctx.Context.User.IsInRole(ApplicationRoles.ContestManager) ||
                                      ctx.Context.User.IsInRole(ApplicationRoles.SubmissionManager));
                    if (!authorized)
                    {
                        const string unauthorizedBody   = "Unauthorized";
                        ctx.Context.Response.StatusCode = StatusCodes.Status401Unauthorized;
                        ctx.Context.Response.Headers["Cache-Control"]  = "no-store";
                        ctx.Context.Response.Headers["Content-Length"] = unauthorizedBody.Length.ToString();
                        ctx.Context.Response.Headers["Content-Type"]   = "text/html";
                        await ctx.Context.Response.WriteAsync(unauthorizedBody);
                    }
                }
            });

            app.UseEndpoints(endpoints =>
            {
                endpoints.MapControllerRoute(
                    name: "default",
                    pattern: "{controller}/{action=Index}/{id?}");
                endpoints.MapRazorPages();
            });

            app.UseSpa(spa =>
            {
                if (env.IsDevelopment())
                {
                    // Check https://github.com/dotnet/aspnetcore/issues/17277
                    // spa.UseProxyToSpaDevelopmentServer("http://localhost:4200");
                    spa.Options.SourcePath = "../Client";
                    spa.UseAngularCliServer(npmScript: "start:dotnet");
                }
            });

            lifetime.ApplicationStarted.Register(() =>
            {
                var factory    = new RabbitMqConnectionFactory(app.ApplicationServices);
                var connection = factory.GetConnection();
                app.ApplicationServices.GetRequiredService <JobRequestProducer>().Start(connection);
                app.ApplicationServices.GetRequiredService <JobCompleteConsumer>().Start(connection);
                app.ApplicationServices.GetRequiredService <WorkerHeartbeatConsumer>().Start(connection);
            });

            lifetime.ApplicationStopping.Register(() =>
            {
                var factory = new RabbitMqConnectionFactory(app.ApplicationServices);
                app.ApplicationServices.GetRequiredService <WorkerHeartbeatConsumer>().Stop();
                app.ApplicationServices.GetRequiredService <JobCompleteConsumer>().Stop();
                app.ApplicationServices.GetRequiredService <JobRequestProducer>().Stop();
                factory.CloseConnection();
            });
        }