Revert "Add profiler base" (#260)

Reverts TeamOctolings/Octobot#235
See #244
This commit is contained in:
Octol1ttle 2024-02-06 23:35:33 +05:00 committed by GitHub
parent 5483bbd203
commit 58bd439aa7
Signed by: GitHub
GPG key ID: B5690EEEBB952194
4 changed files with 0 additions and 153 deletions

View file

@ -4,7 +4,6 @@ using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging; using Microsoft.Extensions.Logging;
using Octobot.Commands.Events; using Octobot.Commands.Events;
using Octobot.Services; using Octobot.Services;
using Octobot.Services.Profiler;
using Octobot.Services.Update; using Octobot.Services.Update;
using Remora.Discord.API.Abstractions.Gateway.Commands; using Remora.Discord.API.Abstractions.Gateway.Commands;
using Remora.Discord.API.Abstractions.Objects; using Remora.Discord.API.Abstractions.Objects;
@ -87,8 +86,6 @@ public sealed class Octobot
.AddPreparationErrorEvent<LoggingPreparationErrorEvent>() .AddPreparationErrorEvent<LoggingPreparationErrorEvent>()
.AddPostExecutionEvent<ErrorLoggingPostExecutionEvent>() .AddPostExecutionEvent<ErrorLoggingPostExecutionEvent>()
// Services // Services
.AddTransient<Profiler>()
.AddSingleton<ProfilerFactory>()
.AddSingleton<Utility>() .AddSingleton<Utility>()
.AddSingleton<GuildDataService>() .AddSingleton<GuildDataService>()
.AddHostedService<GuildDataService>(provider => provider.GetRequiredService<GuildDataService>()) .AddHostedService<GuildDataService>(provider => provider.GetRequiredService<GuildDataService>())

View file

@ -1,114 +0,0 @@
using System.Diagnostics;
using System.Text;
using Microsoft.Extensions.Logging;
using Remora.Results;
// TODO: remove in future profiler PRs
// ReSharper disable All
namespace Octobot.Services.Profiler;
/// <summary>
/// Provides the ability to profile how long certain parts of code take to complete using <see cref="Stopwatch"/>es.
/// </summary>
/// <remarks>Resolve <see cref="ProfilerFactory"/> instead in singletons.</remarks>
public sealed class Profiler
{
private const int MaxProfilerTime = 1000; // milliseconds
private readonly List<ProfilerEvent> _events = [];
private readonly ILogger<Profiler> _logger;
public Profiler(ILogger<Profiler> logger)
{
_logger = logger;
}
/// <summary>
/// Pushes an event to the profiler.
/// </summary>
/// <param name="id">The ID of the event.</param>
public void Push(string id)
{
_events.Add(new ProfilerEvent
{
Id = id,
Stopwatch = Stopwatch.StartNew()
});
}
/// <summary>
/// Pops the last pushed event from the profiler.
/// </summary>
/// <exception cref="InvalidOperationException">Thrown if the profiler contains no events.</exception>
public void Pop()
{
if (_events.Count is 0)
{
throw new InvalidOperationException("Nothing to pop");
}
_events.Last().Stopwatch.Stop();
}
/// <summary>
/// If the profiler took too long to execute, this will log a warning with per-event time usage
/// </summary>
/// <exception cref="InvalidOperationException"></exception>
private void Report()
{
var main = _events[0];
if (main.Stopwatch.ElapsedMilliseconds < MaxProfilerTime)
{
return;
}
var unprofiled = main.Stopwatch.ElapsedMilliseconds;
var builder = new StringBuilder().AppendLine();
for (var i = 1; i < _events.Count; i++)
{
var profilerEvent = _events[i];
if (profilerEvent.Stopwatch.IsRunning)
{
throw new InvalidOperationException(
$"Tried to report on a profiler with running stopwatches: {profilerEvent.Id}");
}
builder.AppendLine($"{profilerEvent.Id}: {profilerEvent.Stopwatch.ElapsedMilliseconds}ms");
unprofiled -= profilerEvent.Stopwatch.ElapsedMilliseconds;
}
builder.AppendLine($"<unprofiled>: {unprofiled}ms");
_logger.LogWarning("Profiler {ID} took {Elapsed} milliseconds to execute (max: {Max}ms):{Events}", main.Id,
main.Stopwatch.ElapsedMilliseconds, MaxProfilerTime, builder.ToString());
}
/// <summary>
/// <see cref="Pop"/> the profiler and <see cref="Report"/> on it afterwards.
/// </summary>
public void PopAndReport()
{
Pop();
Report();
}
/// <summary>
/// <see cref="PopAndReport"/> on the profiler and return a <see cref="Result{TEntity}"/>.
/// </summary>
/// <param name="result"></param>
/// <returns></returns>
public Result ReportWithResult(Result result)
{
PopAndReport();
return result;
}
/// <summary>
/// Calls <see cref="ReportWithResult"/> with <see cref="Result.FromSuccess"/>
/// </summary>
/// <returns>A successful result.</returns>
public Result ReportWithSuccess()
{
return ReportWithResult(Result.FromSuccess());
}
}

View file

@ -1,9 +0,0 @@
using System.Diagnostics;
namespace Octobot.Services.Profiler;
public struct ProfilerEvent
{
public string Id { get; init; }
public Stopwatch Stopwatch { get; init; }
}

View file

@ -1,27 +0,0 @@
using Microsoft.Extensions.DependencyInjection;
namespace Octobot.Services.Profiler;
/// <summary>
/// Provides a method to create a <see cref="Profiler"/>. Useful in singletons.
/// </summary>
public sealed class ProfilerFactory
{
private readonly IServiceScopeFactory _scopeFactory;
public ProfilerFactory(IServiceScopeFactory scopeFactory)
{
_scopeFactory = scopeFactory;
}
/// <summary>
/// Creates a new <see cref="Profiler"/>.
/// </summary>
/// <returns>A new <see cref="Profiler"/>.</returns>
// TODO: remove in future profiler PRs
// ReSharper disable once UnusedMember.Global
public Profiler Create()
{
return _scopeFactory.CreateScope().ServiceProvider.GetRequiredService<Profiler>();
}
}