Skip to content

Commit

Permalink
Add DiagnosticScenarios
Browse files Browse the repository at this point in the history
Add sample debug target for use in C# Guide diagnostics scenarios.
  • Loading branch information
sdmaclea committed Aug 29, 2019
1 parent 7567646 commit f39ae09
Show file tree
Hide file tree
Showing 8 changed files with 350 additions and 0 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,162 @@
using System;
using System.Diagnostics;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
using System.Threading;

namespace testwebapi.Controllers
{
[Route("api/[controller]")]
[ApiController]
public class DiagScenarioController : ControllerBase
{
object o1 = new object();
object o2 = new object();

private static Processor p = new Processor();

[HttpGet]
[Route("deadlock/")]
public ActionResult<string> deadlock()
{
(new System.Threading.Thread(() => {
DeadlockFunc();
})).Start();

Thread.Sleep(5000);

Thread[] threads = new Thread[300];
for(int i=0; i<300;i++)
{
(threads[i] = new Thread(() => {
lock (o1) {Thread.Sleep(100);}
})).Start();
}

foreach(Thread thread in threads)
{
thread.Join();
}

return "success:deadlock";
}

private void DeadlockFunc()
{
lock (o1)
{
(new Thread(() => {
lock (o2) { Monitor.Enter(o1); }
})).Start();

Thread.Sleep(2000);
Monitor.Enter(o2);
}
}

[HttpGet]
[Route("memspike/{seconds}")]
public ActionResult<string> memspike(int seconds)
{
Stopwatch watch=new Stopwatch();
watch.Start();

while(true)
{
p = new Processor();
watch.Stop();
if(watch.ElapsedMilliseconds > seconds*1000)
break;
watch.Start();

int it = (200000*1000) / 100;
for(int i=0; i<it; i++)
{
p.ProcessTransaction(new Customer(Guid.NewGuid().ToString()));
}

Thread.Sleep(5000); // Sleep for 5 seconds before cleaning up

// Cleanup
p = null;
GC.Collect();
GC.Collect();

Thread.Sleep(5000); // Sleep for 5 seconds before spiking memory again
}
return "success:memspike";
}

[HttpGet]
[Route("memleak/{kb}")]
public ActionResult<string> memleak(int kb)
{
int it = (kb*1000) / 100;
for(int i=0; i<it; i++)
{
p.ProcessTransaction(new Customer(Guid.NewGuid().ToString()));
}

return "success:memleak";
}

[HttpGet]
[Route("exception")]
public ActionResult<string> exception()
{
throw new Exception("bad, bad code");
}


[HttpGet]
[Route("highcpu/{milliseconds}")]
public ActionResult<string> highcpu(int milliseconds)
{
Stopwatch watch=new Stopwatch();
watch.Start();

while (true)
{
watch.Stop();
if(watch.ElapsedMilliseconds > milliseconds)
break;
watch.Start();
}

return "success:highcpu";
}

}

class Customer
{
private string id;

public Customer(string id)
{
this.id = id;
}
}

class CustomerCache
{
private List<Customer> cache = new List<Customer>();

public void AddCustomer(Customer c)
{
cache.Add(c);
}
}

class Processor
{
private CustomerCache cache = new CustomerCache();

public void ProcessTransaction(Customer customer)
{
cache.AddCustomer(customer);
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;

namespace DiagnosticScenarios.Controllers
{
[Route("api/[controller]")]
[ApiController]
public class ValuesController : ControllerBase
{
// GET api/values
[HttpGet]
public ActionResult<IEnumerable<string>> Get()
{
return new string[] { "value1", "value2" };
}

// GET api/values/5
[HttpGet("{id}")]
public ActionResult<string> Get(int id)
{
return "value";
}

// POST api/values
[HttpPost]
public void Post([FromBody] string value)
{
}

// PUT api/values/5
[HttpPut("{id}")]
public void Put(int id, [FromBody] string value)
{
}

// DELETE api/values/5
[HttpDelete("{id}")]
public void Delete(int id)
{
}
}
}
11 changes: 11 additions & 0 deletions core/diagnostics/DiagnosticScenarios/DiagnosticScenarios.csproj
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
<Project Sdk="Microsoft.NET.Sdk.Web">

<PropertyGroup>
<TargetFramework>netcoreapp3.0</TargetFramework>
</PropertyGroup>

<ItemGroup>
<PackageReference Include="Microsoft.AspNetCore.Mvc.NewtonsoftJson" Version="3.0.0-preview5-19227-01" />
</ItemGroup>

</Project>
26 changes: 26 additions & 0 deletions core/diagnostics/DiagnosticScenarios/Program.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;

namespace DiagnosticScenarios
{
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>();
});
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
{
"$schema": "http://json.schemastore.org/launchsettings.json",
"iisSettings": {
"windowsAuthentication": false,
"anonymousAuthentication": true,
"iisExpress": {
"applicationUrl": "http://localhost:26127",
"sslPort": 44359
}
},
"profiles": {
"IIS Express": {
"commandName": "IISExpress",
"launchBrowser": true,
"launchUrl": "api/values",
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
}
},
"DiagnosticScenarios": {
"commandName": "Project",
"launchBrowser": true,
"launchUrl": "api/values",
"applicationUrl": "https://localhost:5001;http://localhost:5000",
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
}
}
}
}
57 changes: 57 additions & 0 deletions core/diagnostics/DiagnosticScenarios/Startup.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.HttpsPolicy;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;

namespace DiagnosticScenarios
{
public class Startup
{
public Startup(IConfiguration configuration)
{
Configuration = configuration;
}

public IConfiguration Configuration { get; }

// This method gets called by the runtime. Use this method to add services to the container.
public void ConfigureServices(IServiceCollection services)
{
services.AddControllers()
.AddNewtonsoftJson();
}

// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
else
{
// 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.UseRouting();

app.UseAuthorization();

app.UseEndpoints(endpoints =>
{
endpoints.MapControllers();
});
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
{
"Logging": {
"LogLevel": {
"Default": "Debug",
"System": "Information",
"Microsoft": "Information"
}
}
}
10 changes: 10 additions & 0 deletions core/diagnostics/DiagnosticScenarios/appsettings.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
{
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft": "Warning",
"Microsoft.Hosting.Lifetime": "Information"
}
},
"AllowedHosts": "*"
}

0 comments on commit f39ae09

Please sign in to comment.