jsreport / jsreport-dotnet-aspnetcore

Asp.net core and MVC support for jsreport c# sdk
MIT License
11 stars 9 forks source link

passing cancellationToken to RenderAsync does nothing #10

Closed shai-glat closed 2 weeks ago

shai-glat commented 5 years ago

Hello, I am using JSReport as web server in my Asp.Net Core app, and everything seems to be working great. My problem is i have a cancellation token i pass and RenderAsync seems to ignore it. Any idea what can cause this?

JSReport initialization in startup: var js = new LocalReporting() .UseBinary(reportingBinary) .Configure(c => { c = c.CreateSamples(); c.HttpPort = 12121; c.Chrome = new ChromeConfiguration {Timeout = 10000000}; return c; }) .KillRunningJsReportProcesses() .AsWebServer() .Create(); services.AddJsReport(js); Usage of JSReport: var template = new Template { Content = await GenerateTemplate(templateName, model), Engine = Engine.None, Recipe = Recipe.ChromePdf, Chrome = new Chrome { Landscape = false } }; var report = await _jsReportMvcService.RenderAsync(new RenderRequest { Template = template,Options = new RenderOptions { Timeout = 10000000 } }, _token); NOTE: When RenderAsync() is called, _token is already cancelled.

pofider commented 5 years ago

Do you see anything wrong with this code? We pass the cancelation token to the http client, so it seems to be fine. https://github.com/jsreport/jsreport-dotnet-client/blob/master/jsreport.Client/ReportingService.cs#L170

jaccil commented 2 weeks ago

Hi,

I'm experiencing the same problem: cancellation has not effect. The JsReportMVCService instance implementing LocalReporting does not use the jsreport.Client.ReportService.RenderAsync code provided.

It uses jsreport.Local.Internal.LocalUtilityReportingService.RenderAsync which does not use the cancellation token at all, even though the RenderAsync signature has the ct because it implements IRenderService (through ILocalUtilityReportingService). This does not use the httpClient.PostAsync, but instead uses _binaryProcess.ExecuteExe as you can see here:

https://github.com/jsreport/jsreport-dotnet-local/blob/2aaf2c552b3a36c8533a39f8e909d83033f99394/jsreport.Local/Internal/LocalUtilityReportingService.cs#L74

jaccil commented 2 weeks ago

In BinaryProcessor.InnerExecute, an instance of Process (worker) is created and started. https://github.com/jsreport/jsreport-dotnet-local/blob/2aaf2c552b3a36c8533a39f8e909d83033f99394/jsreport.Local/Internal/BinaryProcess.cs#L171

In order to cancel the process using the cancellationToken, you can use one of two techniques.

Using Process.Handle and CancellationToken.WaitHandle as used here: https://gist.github.com/mxpv/3798871#file-processutil-cs-L78

Or using cancellationToken.Register(() => process.Kill()) but note the two potential problems explained here: https://stackoverflow.com/a/34226000

jaccil commented 2 weeks ago

I notices that there is the following method in jsreport.Local.Internal.LocalUtilityReportingService:

    public Task KillAsync()
    {
        return _binaryProcess.ExecuteExe("kill");
    }

I've used the CancellationToken to call this method as well as actually cancel the WaitForExitAsync task in jsreport.Local.Internal.BinaryProcess. There was also a bug in jsreport.AspNetCore.JsReportMVCService where the CancellationToken was not passed on by RenderAsync. I have created PRs for these issues.

https://github.com/jsreport/jsreport-dotnet-aspnetcore/pull/18 https://github.com/jsreport/jsreport-dotnet-local/pull/6

pofider commented 2 weeks ago

Thank you @jaccil for your investigation and the PRs.

The packages should be now published to nuget jsreport.Local 3.8.2 jsreport.AspNetCore 3.8.1