-
Notifications
You must be signed in to change notification settings - Fork 116
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Hanging / Freezes when rebuilding solution on IIS #56
Comments
What were you passing in before? |
new StaticDeployment(HttpRuntime.AppDomainAppPath + "/wkhtml")) |
Any better solution? Not sure why I need a brand new copy each time. |
Wait a minute -- you are using the |
|
I've been able to reproduce the issue and correct it. I'll release a patch version tonight. The issue was only surfacing when converting from URL instead of just raw HTML; when the AppDomain unloads the |
Thanks a lot. |
I tried the new changes, and the file is still locked when I try to check-in new changes on TFS, but fortunately when the build crashes, I simply restart it and it works fine. |
If you had an existing one running with the unpatched version, that would probably happen.
|
I have a similar issue with the latest version (v2.0.1). I am calling convert from two IIS hosted web applications (vb.net Web Forms). My environment: • One AppPool The pdfs are generated from a URL. Trying to generate a pdf from one of the two sites works (no matter which site or how many times in a row). After the first generation though, any attempt to generate a pdf from the other site completely locks the AppPool (requires killing the process). Converter is a static (shared in vb.net) field. I am using IIS 8.5 with a 64 bit AppPool (Enable 32-Bit Applications = False). This is how I create the converter: Converter = New ThreadSafeConverter( ANOTHER THING... --Matteo |
If you must have both sites in one app pool (ie one process) then each site will need to point to a unique deployment of wkhtmltox.dll.
|
And giving the StaticDeployment constructor a path with a random string (or a guid) in it could accomplish that (removing the static modifier)? The issue that the dll doesn't get copied in the temp folder remains however... it is copied over in the web applications bin folder though (TuesPechkin.Wkhtmltox.Win64.dll) |
The temp folder will vary by the user your app pool runs under, so be sure you are checking the right one. It could be With 2.1.0 there will be an included
Assuming each of your sites have different base directories, that should work for you. |
>The temp folder will vary by the user your app pool runs under Now it's working, but after having generated at least one pdf from each site, it hangs. It must be that static modifier. Is there a really good reason not to want to instantiate the converter multiple times? I mean, is it a matter of performance or...? And do you have any advice for a .net facility that persist data per site (and not per AppPool as the static modifier does)? |
The reason we don't want to instantiate a converter multiple times is because to do so, we would have to load a unique copy of wkhtmltox.dll into memory for each one. This is due to the nature of unmanaged libraries. Now, an application pool is a process, so by having multiple sites on one pool, they share that process. That means a single unique wkhtmltox.dll file would be loaded only one time for the process. However, each site will run within its own AppDomain, meaning that your static variable in managed code is not the going to share the same reference between your sites. So long story short, did you change it to use a random path or the base directory-scope solution I posted above? As long as each site touches a unique copy of the wkhtmltox.dll file, everything should be alright. |
I am using the converter in a web service run on IIS. What I have done is placed a complete, unzipped copy of the "Wkhtmltox.dll" file at the root directory of my web service, and I branch off that to the .dll file using:
This approach generates pdfs without hanging every time. The only problem I have is that TFS build fails and I have to retry it when I check in code changes, a minor annoyance, because the file is locked. The first build attempt apparently unlocks it. I surround my calls to the web service print routine with Using (service) ... End Using. Apparently between calls the "Wkhtmltox.dll" file is locked, but that doesn't seem to affect whether the system can use it using the method I am using. I pass a url to the routines to let .NET do all the rendering so I don't have to reinvent the Render subroutine. I get back a WYSIWYG response as long as I don't have any rendering that depends on javascript. |
Sorry for the delayed response. >each site will run within its own AppDomain In my last response I was using your base directory-scope solution. Now I don't seem to be able to get the other site working, not even for one generation (after the other site generation)... I'm back where I started... This is the converter, as of now: Converter = New ThreadSafeConverter(
New RemotingToolset(Of PdfToolset)(
New Win64EmbeddedDeployment(
New StaticDeployment(
Path.Combine(
Path.GetTempPath(),
AppDomain.CurrentDomain.BaseDirectory.GetHashCode().ToString()))))) I have checked the temp folder (it's the Windows one, by the way) and the converter successfully creates a directory for each site. UPDATE I tried with a simple generic handler (both with iis express and iis). The first generation always succeeds. Every other generation stalls the worker process, which requires to be killed. Am I doing something wrong? Nuget packages:
Imports TuesPechkin
Imports System.IO
Public Class Handler1
Implements System.Web.IHttpHandler
Private Shared Converter As IConverter
Sub ProcessRequest(ByVal context As HttpContext) Implements IHttpHandler.ProcessRequest
If context.Request.QueryString.Item("url") = Nothing Then Exit Sub
context.Response.ContentType = "application/pdf"
Dim Document As New HtmlToPdfDocument
Document.Objects.Add(New ObjectSettings With {
.PageUrl = context.Request.QueryString.Item("url")
})
Converter = New ThreadSafeConverter(
New RemotingToolset(Of PdfToolset)(
New Win64EmbeddedDeployment(
New StaticDeployment(
Path.Combine(
Path.GetTempPath(),
AppDomain.CurrentDomain.BaseDirectory.GetHashCode().ToString())))))
Dim Stream As New MemoryStream(Converter.Convert(Document))
Stream.WriteTo(context.Response.OutputStream)
End Sub
ReadOnly Property IsReusable() As Boolean Implements IHttpHandler.IsReusable
Get
Return False
End Get
End Property
End Class |
My apologies @wc-matteo, it does appear that there are some issues when using multiple wkhtmltox.dll files in a single process, and I think it's going to be related to how P/Invoke binds to the native modules. Looks like I need to start planning for 2.2.0 -- deprecating the WkhtmltoxBindings class and beginning to use dynamically obtained unmanaged delegates. Fun! |
Dynamically obtained unmanaged delegates do sound like fun! (whatever they are :P) But, correct me if I'm wrong, in the generic handler case you're not really using multiple wkhtmltox.dll, are you? And talking about the generic handler, version 2.1.0 does not work (didn't test with the cms):
|
Sorry, I suppose I did not look at your code sample closely enough. You are instantiating a new instance of the converter with each request (in the ProcessRequest method.) You will want to surround that with either a null check, or move that to a static constructor, or if you can in VB.NET, declare it inline with your static field. |
Well, you learn something new every day... I thought the compiler automatically did the null check for me with a static field... It still can't find the dll, though. Can you reproduce it or should I check more thoroughly on my end? P.s. Could you give me an example of an inline declaration (using C#)? UPDATE I can confirm that just updating from 2.0.1 to 2.1.0 generates the error above (tried both with StaticDeployment and the new TempFolderDeployment). |
I've just pushed 2.1.1 which address the issue you've discovered. |
Thank you for the promptly fix! :) For a resolution to my original issue I need to wait for 2.2.0 then? About the TempFolderDeployment: If it copys the dll always in the same folder (per site), when there's a software update to the package, you need to clear the dll from the temp folder, right? |
I've actually got the assembly version in the path of the embedded deployment since 2.1.1/0.12.2.1, so you shouldn't have to worry about manually deleting anything. |
I have the same issue. I just get the latest version TuesPechkin 2.1.1.0 and TuesPechkin.Wkhtmltox.Win32.dll 0.12.2.1. It works very good on converting html to pdf. The only issue is every time the aspx or aspx.vb file changed and cause recompile, we have to recycle the application pool, otherwise the whole site will freeze. My environment is a simple web site, just aspx file and aspx.vb file. For testing it only has one page, I tried all different ways, like, TempFolderDeployment, StaticDeployment, see code below
Any idea to get rid of the recycle application pool when code changes. Thank you, Gary |
I'm using the latest version of the library (2.0.0)
The following code works fine.
But, after I change the code, for example if I made the url google.com instead of fb.com, IIS/IIS_Express freezes and does not generate the pdf. The only way to resolve this is to restart the web server. Any idea, how I could get rid of this situation??
The text was updated successfully, but these errors were encountered: