14
Custom services that are exposed on FinOps as SOAP and "REST" endpoints are not interruptible.

When timeouts occur at the client side, an exception is generated but the service in FinOps continues to run and most probably succeeds in its operation without notifying the client of that success.

As possible in asp.net core we could introduce an (optional?) CancellationToken to keep track of the status with the client that calls the service.

Please find an example of such an implementation in C# below and the corresponding output when
1/ calling the service in the browser
2/ calling the service in the browser and interrupting the call by pressing escape (browser cancels the request)

---
// This class is based on the WeatherForecastController.cs in a new asp.net core api project as created in VS2019
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Logging;

namespace InterruptableWebServices.Controllers
{
[ApiController]
[Route("[controller]")]
public class WeatherForecastController : ControllerBase
{
private static readonly string[] Summaries = new[]
{
"Freezing", "Bracing", "Chilly", "Cool", "Mild", "Warm", "Balmy", "Hot", "Sweltering", "Scorching"
};

private readonly ILogger _logger;

public WeatherForecastController(ILogger logger)
{
_logger = logger;
}

[HttpGet]
public async Task<IEnumerable> Get(CancellationToken ct)
{
_logger.LogInformation("Starting to do slow work");

IEnumerable retval;

try
{
retval = await getWeatherForecastImpl(ct);
}
catch (Exception e)
{
_logger.LogError("Caught exception in the long operation: " + e.Message);
throw;
}

_logger.LogInformation("Finished to do slow work");

return retval
.ToArray();
}

private async Task<IEnumerable> getWeatherForecastImpl(CancellationToken ct)
{
var rng = new Random();
var a = new WeatherForecast[5];
foreach (var i in Enumerable.Range(1,5))
{
a[i-1] = new WeatherForecast
{
Date = DateTime.Now.AddDays(i),
TemperatureC = rng.Next(-20, 55),
Summary = Summaries[rng.Next(Summaries.Length)]
};

if (ct.IsCancellationRequested)
{
throw new TaskCanceledException();
}

await Task.Delay(10000);

}
return a;
}
}
}

---
OUTPUT 1/
InterruptableWebServices.Controllers.WeatherForecastController: Information: Starting to do slow work
InterruptableWebServices.Controllers.WeatherForecastController: Information: Finished to do slow work

OUTPUT 2/
InterruptableWebServices.Controllers.WeatherForecastController: Information: Starting to do slow work
Exception thrown: 'System.Threading.Tasks.TaskCanceledException' in InterruptableWebServices.dll
Exception thrown: 'System.Threading.Tasks.TaskCanceledException' in System.Private.CoreLib.dll
InterruptableWebServices.Controllers.WeatherForecastController: Error: Caught exception in the long operation: A task was canceled.
Category: General
STATUS DETAILS
Needs Votes