mirror of https://github.com/ErsatzTV/ErsatzTV.git
Browse Source
* regularly release memory * don't aggressively GC while legacy streaming * update changelogpull/1128/head
13 changed files with 125 additions and 8 deletions
@ -0,0 +1,3 @@
@@ -0,0 +1,3 @@
|
||||
namespace ErsatzTV.Application.Maintenance; |
||||
|
||||
public record ReleaseMemory(bool ForceAggressive) : IRequest<Unit>, IBackgroundServiceRequest; |
||||
@ -0,0 +1,41 @@
@@ -0,0 +1,41 @@
|
||||
using ErsatzTV.Core.FFmpeg; |
||||
using ErsatzTV.Core.Interfaces.FFmpeg; |
||||
using Microsoft.Extensions.Logging; |
||||
|
||||
namespace ErsatzTV.Application.Maintenance; |
||||
|
||||
public class ReleaseMemoryHandler : IRequestHandler<ReleaseMemory, Unit> |
||||
{ |
||||
private readonly IFFmpegSegmenterService _ffmpegSegmenterService; |
||||
private readonly ILogger<ReleaseMemoryHandler> _logger; |
||||
|
||||
public ReleaseMemoryHandler( |
||||
IFFmpegSegmenterService ffmpegSegmenterService, |
||||
ILogger<ReleaseMemoryHandler> logger) |
||||
{ |
||||
_ffmpegSegmenterService = ffmpegSegmenterService; |
||||
_logger = logger; |
||||
} |
||||
|
||||
public Task<Unit> Handle(ReleaseMemory request, CancellationToken cancellationToken) |
||||
{ |
||||
bool hasActiveWorkers = _ffmpegSegmenterService.SessionWorkers.Any() || FFmpegProcess.ProcessCount > 0; |
||||
if (request.ForceAggressive || !hasActiveWorkers) |
||||
{ |
||||
_logger.LogDebug("Starting aggressive garbage collection"); |
||||
GC.Collect(2, GCCollectionMode.Aggressive, blocking: true, compacting: true); |
||||
} |
||||
else |
||||
{ |
||||
_logger.LogDebug("Starting garbage collection"); |
||||
GC.Collect(2, GCCollectionMode.Forced, blocking: false); |
||||
} |
||||
|
||||
GC.WaitForPendingFinalizers(); |
||||
GC.Collect(); |
||||
|
||||
_logger.LogDebug("Completed garbage collection"); |
||||
|
||||
return Task.FromResult(Unit.Default); |
||||
} |
||||
} |
||||
@ -0,0 +1,20 @@
@@ -0,0 +1,20 @@
|
||||
using System.Diagnostics; |
||||
|
||||
namespace ErsatzTV.Core.FFmpeg; |
||||
|
||||
public class FFmpegProcess : Process |
||||
{ |
||||
public static int ProcessCount; |
||||
|
||||
public FFmpegProcess() |
||||
{ |
||||
Interlocked.Increment(ref ProcessCount); |
||||
} |
||||
|
||||
protected override void Dispose(bool disposing) |
||||
{ |
||||
base.Dispose(disposing); |
||||
|
||||
Interlocked.Decrement(ref ProcessCount); |
||||
} |
||||
} |
||||
@ -0,0 +1,20 @@
@@ -0,0 +1,20 @@
|
||||
using ErsatzTV.Application.Maintenance; |
||||
using MediatR; |
||||
using Microsoft.AspNetCore.Mvc; |
||||
|
||||
namespace ErsatzTV.Controllers.Api; |
||||
|
||||
[ApiController] |
||||
public class MaintenanceController |
||||
{ |
||||
private readonly IMediator _mediator; |
||||
|
||||
public MaintenanceController(IMediator mediator) => _mediator = mediator; |
||||
|
||||
[HttpGet("/api/maintenance/gc")] |
||||
public async Task<IActionResult> GarbageCollection([FromQuery] bool force = false) |
||||
{ |
||||
await _mediator.Send(new ReleaseMemory(force)); |
||||
return new OkResult(); |
||||
} |
||||
} |
||||
Loading…
Reference in new issue