Welcome Guest Search | Active Topics | Sign In | Register

Timeout rendering ArcGIS map using HtmlToPdf.ConvertUrl Options
Ditmer
Posted: Monday, October 31, 2016 8:01:16 AM
Rank: Newbie
Groups: Member

Joined: 5/12/2014
Posts: 5
I have a timeout problem with HtmlToPdf.ConvertUrl

After starting a new website I call:
Code: C#
HtmlToPdf.ConvertUrl(myURL, memoryStream, htmlOptions);
HtmlToPdf.ClearResult(); // This seems to have no effect 


myURL points to a page with a lot of javascript rendering an ArcGIS map.

First time the operation goes fine - I get a great PDF after about 20 sec. (It's quite slow considering it takes about 3-4 sec in the browser - but it works.) After that I can use the website, call any URL and use the website normally. I can use functions that generate PDF using the same code - rendering Html with little or no javascript. I can call the URL of the "myURL" ArcGIS map that i just rendered and it works. I get the same result in the browser as in the PDF.

BUT - if I call HtmlToPdf.ConvertUrl a second time on the complex page (or another page that contains the same JavaScript map) - the whole website process locks up, no PDF i rendered. Eventally I get an exception:
"An unhandled exception of type 'System.Exception' occurred in EO.Pdf.dll

Additional information: System.Exception: Times out while loading Url or HTML. Please try to increase HtmlToPdfOptions.MaxWaitTime."

But even with a try-catch block handling the error - the website is dead. I've tries to split the rendering into a different Thread to protect the main thread:
Code: C#
Thread t = new Thread(renderingThread.start);
t.Start();


But the result is exactly the same. Only a stop-start of the website works. After a restart I can again render any pdf I want, with or without an ArcGIS map. But only once - after that, any subsequent call-to-render of an URL with an ArcGIS map will crash the website.

I can, of course, call "myURL" in the browser without error. The website only crashes what myURL is called through ConvertUrl() a second time.

It's like HtmlToPdf goes into a state that only a complete process-restart can resolve. But since the HtmlToPdf object can't be destroyed/reset any other way the whole website must be restarted. (ClearResult() has no effect.)

Any ideas will be much appreciated.
eo_support
Posted: Monday, October 31, 2016 9:16:46 AM
Rank: Administration
Groups: Administration

Joined: 5/27/2007
Posts: 24,229
Hi,

Please try to use ASPXToPDF/MVCToPDF for this purpose. It is very common that you will run into time out/deadlock issue if you call ConvertUrl back to the same site due to how ASP.NET handles session lock. The root of the problem is ASP.NET acquires a lock on your session (so that you don't have to worry about synchronization while accessing session variables). However if your code depends on another request from the very same website that may require the same lock (from another thread), then the two threads will deadlock because they would be waiting for each other. ASPXToPDF/MVCToPDF has special code to avoid this scenario. So you can try that and see if it works for you.

Thanks!
Ditmer
Posted: Monday, October 31, 2016 11:07:43 AM
Rank: Newbie
Groups: Member

Joined: 5/12/2014
Posts: 5
I've used the example on https://www.essentialobjects.com/doc/pdf/web/mvc.aspx

That gets me some of the way. I'm getting a PDF very fast but now with a blank square instead of the ArcGIS map - it's like the page is being returned before javascript has a chance to run.

Before I used to call using these params:
Code: C#
htmlOptions.TriggerMode = HtmlToPdfTriggerMode.Manual;
htmlOptions.Cookies = cookieCollection;
HtmlToPdf.ConvertUrl(url, memoryStream, htmlOptions);


HtmlToPdfTriggerMode.Manual - to ensure the PDF snapshot is not taken until convert() is called
...Cookies = cookieCollection is to ensure the current user-context is used.

I assume cookies are not necessary (?) - but how can I ensure that rendering is delayed until scripts are done?

Also - how can I return a memoryStream? I use that to save the PDF as binary data to the database without the need for an intermediate file.

eo_support
Posted: Monday, October 31, 2016 11:33:26 AM
Rank: Administration
Groups: Administration

Joined: 5/27/2007
Posts: 24,229
Hi,

The cookies will be necessary if your code relies on those cookie values. However make sure you skip ASP.NET session cookies. The session cookie is exactly what caused the deadlock for you on the first place.

You can still use manual trigger mode when using MVCToPDF. Or you can increase HtmlToPdf.Options.MinLoadWaitTime to give your script some time to run.

To save the result to a MemoryStream, take the sample code from here (look for "Save result to a file" section):

https://www.essentialobjects.com/doc/pdf/web/mvc.aspx#save

Just replace the file name argument with a MemoryStream object.

Thanks!
Ditmer
Posted: Tuesday, November 1, 2016 4:53:53 AM
Rank: Newbie
Groups: Member

Joined: 5/12/2014
Posts: 5
Cookies are necessary precisely for the ASP.NET session, it allows us to identify the user making the PDF request to avoid other users accessing thier content and for the system to access external resources based on settings that only apply to the current user. But since MVCToPDF is modifying an ActionResult is seems it's already acting as the current user or is the engine still acting "anonymously" (with its own session-state) like "HtmlToPdf"?

You state that we can use manual trigger mode in MVCToPDF - can you refer to an example?

You mention MinLoadWaitTime - but write "HtmlToPdf.Options.MinLoadWaitTime" which is a property on "HtmlToPdf" - can you refer to an example using MVCToPDF?

eo_support
Posted: Tuesday, November 1, 2016 10:02:02 AM
Rank: Administration
Groups: Administration

Joined: 5/27/2007
Posts: 24,229
Hi,

MVCToPDF will copy your session cookie. So if you store everything in your session variable, then you do not need other cookies.

Internally MVCToPDF uses HTML to PDF to perform the conversion. So you can use most HtmlToPdf.Options properties. You can set them in your PreRender handler. See here for more details:

https://www.essentialobjects.com/doc/pdf/web/mvc.aspx#save

The code in the above link demonstrates how to use the PostRender handler. You will need to use a different overload to supply a PreRendeer handler:

https://www.essentialobjects.com/doc/eo.pdf.mvc.mvctopdf.renderaspdf_overload_1.aspx

In this overload the first argument is the PreRender handler. The sample code in the above link pass null for PreRender handler. You will need to change that to a real handler and then set HtmlToPdf.Options in that handler.

In our next build you will be able to set the options directly before you call RenderAsPDF.

Thanks!
Ditmer
Posted: Thursday, November 3, 2016 5:30:39 AM
Rank: Newbie
Groups: Member

Joined: 5/12/2014
Posts: 5
I've implemented the PreHandler :

Code: C#
public void PrePDFHandler(object sender, EventArgs e)
{
  HtmlToPdf.Options.MinLoadWaitTime = 8000;
}


And from the ActionResult method made sure it's being called:
Code: C#
MVCToPDF.RenderAsPDF(PrePDFHandler, null);


But no matter how much time is allocated for the process (ie. how high the MinLoadWaitTime is) - the PDF never contains the result of the map. It's just a blank square like it is when MinLoadWaitTime is not defined.

If I use:
Code: C#
HtmlToPdf.Options.TriggerMode = HtmlToPdfTriggerMode.Manual;

As I do when using with the old "HtmlToPdf.ConvertUrl" method - the controller never returns a result.

Since it does works (once) using HtmlToPdf.ConvertUrl directly - I must still be missing a piece of the puzzle.

Do you have any other ideas of things I could try?
eo_support
Posted: Thursday, November 3, 2016 10:29:06 AM
Rank: Administration
Groups: Administration

Joined: 5/27/2007
Posts: 24,229
Hi,

The most likely reason is you have some JavaScript errors. You can try to use the debug console feature to help debugging JavaScript code:

https://www.essentialobjects.com/doc/pdf/htmltopdf/js.aspx

The only reason for the conversion not to return when you use manual trigger is when your manual trigger code is not called. This again points to JavaScript error.

Thanks!


You cannot post new topics in this forum.
You cannot reply to topics in this forum.
You cannot delete your posts in this forum.
You cannot edit your posts in this forum.
You cannot create polls in this forum.
You cannot vote in polls in this forum.