Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

.NET 8 Upgrade #1

Open
wants to merge 9 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 18 additions & 0 deletions .github/workflows/docker-image.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
name: Docker Image CI

on:
push:
branches: [ "main" ]
pull_request:
branches: [ "main" ]

jobs:

build:

runs-on: ubuntu-latest

steps:
- uses: actions/checkout@v4
- name: Build the Docker image
run: docker build . --file src/BuggyBits/Dockerfile --tag my-image-name:$(date +%s)
30 changes: 30 additions & 0 deletions src/.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/**
16 changes: 12 additions & 4 deletions src/BuggyBits/BuggyBits.csproj
Original file line number Diff line number Diff line change
@@ -1,7 +1,15 @@
<Project Sdk="Microsoft.NET.Sdk.Web">
<Project Sdk="Microsoft.NET.Sdk.Web">

<PropertyGroup>
<TargetFramework>netcoreapp3.1</TargetFramework>
</PropertyGroup>
<PropertyGroup>
<TargetFramework>net8.0</TargetFramework>
<Nullable>enable</Nullable>
<ImplicitUsings>enable</ImplicitUsings>
<UserSecretsId>32ddb074-9842-41a4-a9a2-0a2e3a5b869d</UserSecretsId>
<DockerDefaultTargetOS>Linux</DockerDefaultTargetOS>
</PropertyGroup>

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

</Project>
108 changes: 108 additions & 0 deletions src/BuggyBits/Controllers/LeakController.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,108 @@
using Microsoft.AspNetCore.Mvc;
using System.Diagnostics;
using System.Net.Http;
using System.Threading;
using System.Collections.Generic;
using System.Net;

namespace BuggyBits.Controllers
{
[ApiController]
[Route("[controller]")]
public class LeakController : Controller
{
private static int _callCount = 0;
private static int _threadCount = 0;
private static List<byte[]> _memoryLeaks = new List<byte[]>();
private static List<int> _allocatedSizes = new List<int>();
private static long _totalMemoryLeaks = 0;

[HttpGet]
public IActionResult Index()
{
return View();
}

[HttpGet("LeakConnections")]
public IActionResult LeakConnections()
{
_callCount = 0;
MakeRequest();
return View("LeakConnections");
}

private void MakeRequest()
{
if (_callCount >= 500)
return;

_callCount++;

// Buggy code: WebClient is not disposed
WebClient client = new WebClient();
var response = client.DownloadString("https://www.bing.com");

// Wait for 100 ms before making the next request
Thread.Sleep(100);
Console.WriteLine($"Request {_callCount} completed");
// Recursive call
MakeRequest();
}

[HttpGet("LeakThreads")]
public IActionResult LeakThreads()
{
_threadCount = 0;
CreateNewThread();
return View("LeakThreads");
}

private void CreateNewThread()
{
if (_threadCount >= 500)
return;

_threadCount++;

// Start the stopwatch to measure thread start duration
Stopwatch stopwatch = Stopwatch.StartNew();

// Create a new thread
Thread newThread = new Thread(() =>
{

// Simulate some work
Thread.Sleep(100000); // Sleep for 10 seconds
});

newThread.Start();
// Stop the stopwatch and log the duration
stopwatch.Stop();
Console.WriteLine($"Thread {_threadCount} created in {stopwatch.ElapsedMilliseconds} ms");
CreateNewThread();
}

[HttpGet("LeakMemory")]
public IActionResult LeakMemory()
{
// Generate a random size between 85KB and 100MB
Random random = new Random();
int size = random.Next(85 * 1024, 100 * 1024 * 1024);

// Allocate memory with the generated size
byte[] memoryLeak = new byte[size];
_memoryLeaks.Add(memoryLeak);
_allocatedSizes.Add(size);
_totalMemoryLeaks += size;

// Log the size of the created array and the total memory leaks
Console.WriteLine($"Allocated {size / 1024.0 / 1024.0:F2} MB, total leaks: {_totalMemoryLeaks / 1024.0 / 1024.0:F2} MB");

// Pass the allocated sizes and total memory leaks to the view
ViewBag.AllocatedSizes = _allocatedSizes;
ViewBag.TotalMemoryLeaks = _totalMemoryLeaks;

return View("LeakMemory");
}
}
}
38 changes: 38 additions & 0 deletions src/BuggyBits/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
# 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.

# This stage is used when running from VS in fast mode (Default for Debug configuration)
FROM mcr.microsoft.com/dotnet/aspnet:8.0 AS base
USER app
WORKDIR /app
EXPOSE 8080
EXPOSE 8081

# This stage is used to build the service project
FROM mcr.microsoft.com/dotnet/sdk:8.0 AS build
ARG BUILD_CONFIGURATION=Release
WORKDIR /src
COPY ["BuggyBits/BuggyBits.csproj", "BuggyBits/"]
RUN dotnet restore "./BuggyBits/BuggyBits.csproj"
COPY . .
WORKDIR "/src/BuggyBits"
RUN dotnet build "./BuggyBits.csproj" -c $BUILD_CONFIGURATION -o /app/build

# Install dotnet-dump tool
RUN dotnet tool install -g dotnet-dump
ENV PATH="/root/.dotnet/tools:${PATH}"


# This stage is used to publish the service project to be copied to the final stage
FROM build AS publish
ARG BUILD_CONFIGURATION=Release
RUN dotnet publish "./BuggyBits.csproj" -c $BUILD_CONFIGURATION -o /app/publish /p:UseAppHost=false

# This stage is used in production or when running from VS in regular mode (Default when not using the Debug configuration)
FROM base AS final
WORKDIR /app

# Copy the dotnet-dump tool from the build stage
COPY --from=build /root/.dotnet/tools/dotnet-dump /usr/local/bin/

COPY --from=publish /app/publish .
ENTRYPOINT ["dotnet", "BuggyBits.dll"]
52 changes: 28 additions & 24 deletions src/BuggyBits/Program.cs
Original file line number Diff line number Diff line change
@@ -1,26 +1,30 @@
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;

namespace BuggyBits
using BuggyBits.Models;

var builder = WebApplication.CreateBuilder(args);

// Add services to the container.
builder.Services.AddControllersWithViews();
builder.Services.AddSingleton(_ => new DataLayer());

var app = builder.Build();

// Configure the HTTP request pipeline.
if (!app.Environment.IsDevelopment())
{
public class Program
{
public static void Main(string[] args)
{
CreateHostBuilder(args).Build().Run();
}

public static IHostBuilder CreateHostBuilder(string[] args) =>
Host.CreateDefaultBuilder(args)
.ConfigureWebHostDefaults(webBuilder =>
{
webBuilder.UseStartup<Startup>();
});
}
app.UseExceptionHandler("/Home/Error");
// The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts.
app.UseHsts();
}

app.UseHttpsRedirection();
app.UseStaticFiles();

app.UseRouting();

app.UseAuthorization();

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

app.Run();
35 changes: 23 additions & 12 deletions src/BuggyBits/Properties/launchSettings.json
Original file line number Diff line number Diff line change
@@ -1,12 +1,4 @@
{
"iisSettings": {
"windowsAuthentication": false,
"anonymousAuthentication": true,
"iisExpress": {
"applicationUrl": "http://localhost:52206",
"sslPort": 44350
}
},
{
"profiles": {
"IIS Express": {
"commandName": "IISExpress",
Expand All @@ -18,10 +10,29 @@
"BuggyBits": {
"commandName": "Project",
"launchBrowser": true,
"applicationUrl": "https://localhost:5001;http://localhost:5000",
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
}
},
"applicationUrl": "https://localhost:5001;http://localhost:5000"
},
"Container (Dockerfile)": {
"commandName": "Docker",
"launchBrowser": true,
"launchUrl": "{Scheme}://{ServiceHost}:{ServicePort}",
"environmentVariables": {
"ASPNETCORE_HTTPS_PORTS": "8081",
"ASPNETCORE_HTTP_PORTS": "8080"
},
"publishAllPorts": true,
"useSSL": true
}
},
"iisSettings": {
"windowsAuthentication": false,
"anonymousAuthentication": true,
"iisExpress": {
"applicationUrl": "http://localhost:52206",
"sslPort": 44350
}
}
}
}
52 changes: 0 additions & 52 deletions src/BuggyBits/Startup.cs

This file was deleted.

16 changes: 16 additions & 0 deletions src/BuggyBits/Views/Leak/Index.cshtml
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
@{
ViewData["Title"] = "Leak";
}

<div class="text-center">
<h1 class="display-4">Leak</h1>
<p>
<a asp-controller="Leak" asp-action="LeakConnections" class="btn btn-primary">Leak Connections</a>
</p>
<p>
<a asp-controller="Leak" asp-action="LeakThreads" class="btn btn-secondary">Leak Threads</a>
</p>
<p>
<a asp-controller="Leak" asp-action="LeakMemory" class="btn btn-danger">Leak Memory</a>
</p>
</div>
Loading