Skip to content

Commit

Permalink
move important stuff
Browse files Browse the repository at this point in the history
  • Loading branch information
roman-koshchei committed Feb 11, 2024
1 parent a6a9962 commit 6540c49
Show file tree
Hide file tree
Showing 20 changed files with 1,124 additions and 3 deletions.
30 changes: 30 additions & 0 deletions .dockerignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
**/.classpath
**/.dockerignore
**/.env
**/.git
**/.gitignore
**/.project
**/.settings
**/.toolstarget
**/.vs
**/.vscode
**/*.*proj.user
**/*.dbmdl
**/*.jfm
**/azds.yaml
**/bin
**/charts
**/docker-compose*
**/Dockerfile*
**/node_modules
**/npm-debug.log
**/obj
**/secrets.dev.yaml
**/values.dev.yaml
LICENSE
README.md
!**/.gitignore
!.git/HEAD
!.git/config
!.git/packed-refs
!.git/refs/heads/**
12 changes: 12 additions & 0 deletions Unator.sln
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,10 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Web", "src\Web\Web.csproj",
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Unator", "src\Unator\Unator.csproj", "{DE0C969B-DF8E-45D1-88B9-FE373CE48BD0}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Asp", "src\Asp\Asp.csproj", "{74D8ED91-2321-461E-B5C8-A91344384A7C}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Unator.Extensions", "src\Unator.Extensions\Unator.Extensions.csproj", "{4AE47118-6AA9-41E5-AA04-DD52F5EDB8FC}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Expand All @@ -21,6 +25,14 @@ Global
{DE0C969B-DF8E-45D1-88B9-FE373CE48BD0}.Debug|Any CPU.Build.0 = Debug|Any CPU
{DE0C969B-DF8E-45D1-88B9-FE373CE48BD0}.Release|Any CPU.ActiveCfg = Release|Any CPU
{DE0C969B-DF8E-45D1-88B9-FE373CE48BD0}.Release|Any CPU.Build.0 = Release|Any CPU
{74D8ED91-2321-461E-B5C8-A91344384A7C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{74D8ED91-2321-461E-B5C8-A91344384A7C}.Debug|Any CPU.Build.0 = Debug|Any CPU
{74D8ED91-2321-461E-B5C8-A91344384A7C}.Release|Any CPU.ActiveCfg = Release|Any CPU
{74D8ED91-2321-461E-B5C8-A91344384A7C}.Release|Any CPU.Build.0 = Release|Any CPU
{4AE47118-6AA9-41E5-AA04-DD52F5EDB8FC}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{4AE47118-6AA9-41E5-AA04-DD52F5EDB8FC}.Debug|Any CPU.Build.0 = Debug|Any CPU
{4AE47118-6AA9-41E5-AA04-DD52F5EDB8FC}.Release|Any CPU.ActiveCfg = Release|Any CPU
{4AE47118-6AA9-41E5-AA04-DD52F5EDB8FC}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
Expand Down
21 changes: 21 additions & 0 deletions src/Asp/Asp.csproj
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
<Project Sdk="Microsoft.NET.Sdk.Web">

<PropertyGroup>
<TargetFramework>net8.0</TargetFramework>
<Nullable>enable</Nullable>
<ImplicitUsings>enable</ImplicitUsings>
<InvariantGlobalization>true</InvariantGlobalization>
<UserSecretsId>ae75a417-1fe1-40c5-917d-7bbee2fdf269</UserSecretsId>
<DockerDefaultTargetOS>Linux</DockerDefaultTargetOS>
<DockerfileContext>..\..</DockerfileContext>
</PropertyGroup>

<ItemGroup>
<PackageReference Include="Microsoft.VisualStudio.Azure.Containers.Tools.Targets" Version="1.19.5" />
</ItemGroup>

<ItemGroup>
<ProjectReference Include="..\Unator\Unator.csproj" />
</ItemGroup>

</Project>
6 changes: 6 additions & 0 deletions src/Asp/Asp.http
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
@Asp_HostAddress = http://localhost:5014

GET {{Asp_HostAddress}}/weatherforecast/
Accept: application/json

###
25 changes: 25 additions & 0 deletions src/Asp/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
#See https://aka.ms/customizecontainer to learn how to customize your debug container and how Visual Studio uses this Dockerfile to build your images for faster debugging.

FROM mcr.microsoft.com/dotnet/aspnet:8.0 AS base
USER app
WORKDIR /app
EXPOSE 8080
EXPOSE 8081

FROM mcr.microsoft.com/dotnet/sdk:8.0 AS build
ARG BUILD_CONFIGURATION=Release
WORKDIR /src
COPY ["src/Asp/Asp.csproj", "src/Asp/"]
RUN dotnet restore "./src/Asp/./Asp.csproj"
COPY . .
WORKDIR "/src/src/Asp"
RUN dotnet build "./Asp.csproj" -c $BUILD_CONFIGURATION -o /app/build

FROM build AS publish
ARG BUILD_CONFIGURATION=Release
RUN dotnet publish "./Asp.csproj" -c $BUILD_CONFIGURATION -o /app/publish /p:UseAppHost=false

FROM base AS final
WORKDIR /app
COPY --from=publish /app/publish .
ENTRYPOINT ["dotnet", "Asp.dll"]
80 changes: 80 additions & 0 deletions src/Asp/Program.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
using Microsoft.AspNetCore.Mvc;
using Unator;

var builder = WebApplication.CreateBuilder(args);

builder.Services.AddScoped<Loader>();
builder.Services.AddScoped<ExampleService>();
builder.Services.AddScoped<AnnoyingService>();

var app = builder.Build();

app.UseHttpsRedirection();

app.Use(async (context, next) =>
{
var startTime = DateTime.UtcNow;

await next.Invoke();

var endTime = DateTime.UtcNow;

var processingTime = endTime - startTime;
Console.WriteLine($"Request {context.Request.Path} time: {processingTime.Ticks} ticks");
});

app.MapGet("/a", ([FromServices] Loader l) =>
{
l.Service.Get.PrintServiceUsageCount();
l.Service.Get.PrintServiceUsageCount();
l.Service.Get.PrintServiceUsageCount();
l.AnnoyingService.Get.Annoy();
l.AnnoyingService.Get.Annoy();
l.AnnoyingService.Get.Annoy();
return Results.Ok();
});

app.MapGet("/b", ([FromServices] ExampleService ex, [FromServices] AnnoyingService ann) =>
{
ex.PrintServiceUsageCount();
ex.PrintServiceUsageCount();
ex.PrintServiceUsageCount();
ann.Annoy();
ann.Annoy();
ann.Annoy();
return Results.Ok();
});

app.Run();

public class Loader
{
public CachedService<ExampleService> Service { get; } = new();
public CachedService<AnnoyingService> AnnoyingService { get; } = new();
}

public class ExampleService
{
private int count = 1;

public void PrintServiceUsageCount()
{
Console.WriteLine($"Service used {count} times");
count += 1;
}
}

public class AnnoyingService
{
private int count = 1;

public void Annoy()
{
for (int i = 0; i < count; i++)
{
Console.WriteLine("AAAA");
}

count += 1;
}
}
52 changes: 52 additions & 0 deletions src/Asp/Properties/launchSettings.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
{
"profiles": {
"http": {
"commandName": "Project",
"launchBrowser": true,
"launchUrl": "weatherforecast",
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
},
"dotnetRunMessages": true,
"applicationUrl": "http://localhost:5014"
},
"https": {
"commandName": "Project",
"launchBrowser": true,
"launchUrl": "weatherforecast",
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
},
"dotnetRunMessages": true,
"applicationUrl": "https://localhost:7137;http://localhost:5014"
},
"IIS Express": {
"commandName": "IISExpress",
"launchBrowser": true,
"launchUrl": "weatherforecast",
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
}
},
"Docker": {
"commandName": "Docker",
"launchBrowser": true,
"launchUrl": "{Scheme}://{ServiceHost}:{ServicePort}/weatherforecast",
"environmentVariables": {
"ASPNETCORE_HTTPS_PORTS": "8081",
"ASPNETCORE_HTTP_PORTS": "8080"
},
"publishAllPorts": true,
"useSSL": true
}
},
"$schema": "http://json.schemastore.org/launchsettings.json",
"iisSettings": {
"windowsAuthentication": false,
"anonymousAuthentication": true,
"iisExpress": {
"applicationUrl": "http://localhost:37943",
"sslPort": 44324
}
}
}
8 changes: 8 additions & 0 deletions src/Asp/appsettings.Development.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
{
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft.AspNetCore": "Warning"
}
}
}
9 changes: 9 additions & 0 deletions src/Asp/appsettings.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
{
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft.AspNetCore": "Warning"
}
},
"AllowedHosts": "*"
}
103 changes: 103 additions & 0 deletions src/Unator.Extensions/BackgroundQueue.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;
using System.Threading.Channels;

namespace Unator.Extensions;

/// <summary>
/// Background queue implemented with channels. Perform tasks in background.
/// <example>
/// Oriented to use with ASP NET Core:
/// <code>
/// builder.Services.AddSingleton&lt;BackgroundQueue&gt;();
/// builder.Services.AddHostedService&lt;BackgroundQueue.HostedService&gt;();
/// </code>
/// </example>
/// </summary>
public class BackgroundQueue
{
private readonly Channel<Func<IServiceProvider, Task>> queue;

public BackgroundQueue()
{
var options = new UnboundedChannelOptions
{
// Queue is supposed to be singleton, otherwith change it to false
SingleReader = true
};
queue = Channel.CreateUnbounded<Func<IServiceProvider, Task>>(options);
}

/// <summary>
/// Add new task to background queue.
/// <example>
/// For example:
/// <code>
/// await background.Enqueue(async (provider) =>
/// {
/// using IServiceScope scope = provider.CreateScope();
/// var service = scope.ServiceProvider.GetRequiredService&lt;IEmailSender&gt;();
/// await service.Send(
/// fromEmail: "[email protected]",
/// fromName: "Roman Koshchei",
/// to: new List&lt;string&gt; { "[email protected]" },
/// subject: "Showing example of Background queue",
/// text: "Check it on GitHub repo: roman-koshchei/unator",
/// html: "Check it on GitHub repo: roman-koshchei/unator"
/// )
/// });
/// </code>
/// </example>
/// </summary>
/// <param name="task">
/// Action to perform in background queuqe.
/// If action is sync then just return <c>Task.CompletedTask</c>
/// </param>
/// <returns></returns>
public async Task Enqueue(Func<IServiceProvider, Task> task)
{
await queue.Writer.WriteAsync(task);
}

public class HostedService : BackgroundService
{
private readonly ILogger<HostedService> logger;
private readonly BackgroundQueue queue;
private readonly IServiceProvider serviceProvider;

public HostedService(
ILogger<HostedService> logger,
BackgroundQueue queue,
IServiceProvider serviceProvider
)
{
this.logger = logger;
this.queue = queue;
this.serviceProvider = serviceProvider;
}

protected override async Task ExecuteAsync(CancellationToken stoppingToken)
{
logger.LogInformation("Background queue Hostend service is started.");

while (!stoppingToken.IsCancellationRequested)
{
var job = await queue.queue.Reader.ReadAsync(stoppingToken);
try
{
await job(serviceProvider);
}
catch (Exception ex)
{
logger.LogError(ex, $"Exception appeared during execution of Background queue job: {nameof(job)}.");
}
}
}

public override async Task StopAsync(CancellationToken stoppingToken)
{
logger.LogInformation("Background queue Hosted Service is stopping.");
await base.StopAsync(stoppingToken);
}
}
}
Loading

0 comments on commit 6540c49

Please sign in to comment.