Code Monkey home page Code Monkey logo

Comments (25)

tuespetre avatar tuespetre commented on September 3, 2024

What were you passing in before?

from tuespechkin.

appstractmeyn avatar appstractmeyn commented on September 3, 2024

new StaticDeployment(HttpRuntime.AppDomainAppPath + "/wkhtml"))

from tuespechkin.

appstractmeyn avatar appstractmeyn commented on September 3, 2024

Any better solution? Not sure why I need a brand new copy each time.

from tuespechkin.

tuespetre avatar tuespetre commented on September 3, 2024

Wait a minute -- you are using the RemotingToolset, right?

from tuespechkin.

appstractmeyn avatar appstractmeyn commented on September 3, 2024
static string tpath = Path.Combine(Path.GetTempPath(), Guid.NewGuid().ToString(), "wkhtml");
private static IConverter pdfConverter = new ThreadSafeConverter(new RemotingToolset<PdfToolset>(new Win32EmbeddedDeployment(new StaticDeployment(tpath))));

from tuespechkin.

tuespetre avatar tuespetre commented on September 3, 2024

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 RemotingConverter was not invoking wkhtmltopdf_deinit which must have left some unmanaged web loading object hanging before trying to unload the AppDomain. The temporary workaround is a bit hacky but it stays underneath the surface of the public API. There will now be a unit test for this scenario as well -- converting from URL after AppDomain unloading.

from tuespechkin.

appstractmeyn avatar appstractmeyn commented on September 3, 2024

Thanks a lot.

from tuespechkin.

timdooling avatar timdooling commented on September 3, 2024

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.

from tuespechkin.

tuespetre avatar tuespetre commented on September 3, 2024

If you had an existing one running with the unpatched version, that would probably happen.

  • Derek Gray

On Jan 6, 2015, at 12:04 PM, timdooling [email protected] wrote:

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.


Reply to this email directly or view it on GitHub.

from tuespechkin.

wc-matteo avatar wc-matteo commented on September 3, 2024

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
• Two web sites running from different folders but having the same code and AppPool (it is a custom CMS)
• TuesPechkin wrapped in a class (acting as a thin wrapper) and included as a reference in the web application projects (using TuesPechkin.Wkhtmltox.Win64 too)

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(
New RemotingToolset(Of PdfToolset)(
New Win64EmbeddedDeployment(
New StaticDeployment(
Path.Combine(Path.GetTempPath(), "mycustomcms")
)
)
)
)

ANOTHER THING...
...is that the wkhtmltox dll is not copied in the temp folder (and mycustomcms is not created either).

--Matteo

from tuespechkin.

tuespetre avatar tuespetre commented on September 3, 2024

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.

  • Derek Gray

On Jan 16, 2015, at 9:18 AM, wc-matteo [email protected] wrote:

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
• Two web sites running from different folders but having the same code and AppPool (it is a custom CMS)
• TuesPechkin wrapped in a class (acting as a thin wrapper) and included as a reference in the web application projects (using TuesPechkin.Wkhtmltox.Win64 too)

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(
New RemotingToolset(Of PdfToolset)(
New Win64EmbeddedDeployment(
New StaticDeployment(
Path.Combine(Path.GetTempPath(), "mycustomcms")
)
)
)
)

Matteo

Reply to this email directly or view it on GitHub.

from tuespechkin.

wc-matteo avatar wc-matteo commented on September 3, 2024

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)

from tuespechkin.

tuespetre avatar tuespetre commented on September 3, 2024

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 C:\Windows\Temp or C:\Users\<some_user_name>\AppData\Local\Temp depending on how you have things set up.

With 2.1.0 there will be an included TempFolderDeployment class that somewhat imitates the deployment behavior of 1.0.3. I would recommend switching to use that as soon as 2.1.0 is released. You can use the same method right now if you want, it pretty much does this:

            Path = System.IO.Path.Combine(
                System.IO.Path.GetTempPath(),
                AppDomain.CurrentDomain.BaseDirectory.GetHashCode().ToString());

Assuming each of your sites have different base directories, that should work for you.

from tuespechkin.

wc-matteo avatar wc-matteo commented on September 3, 2024

>The temp folder will vary by the user your app pool runs under
Duh... so obvious! -_-

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)?

from tuespechkin.

tuespetre avatar tuespetre commented on September 3, 2024

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.

from tuespechkin.

timdooling avatar timdooling commented on September 3, 2024

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:

    Shared Property converter As IConverter = Nothing

         ...
        Dim physicalApplicationPath As String = MyClass.Context.Request.PhysicalApplicationPath

           If IsNothing(converter) Then
                converter = New ThreadSafeConverter(
     New RemotingToolset(Of PdfToolset)(
     New StaticDeployment(physicalApplicationPath)))
            End If

    ...

            converter = Nothing ' releases the memory to garbage collection

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.

from tuespechkin.

wc-matteo avatar wc-matteo commented on September 3, 2024

Sorry for the delayed response.

>each site will run within its own AppDomain
Ah! I was conflating AppPools and AppDomains; now I see...

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:

  • TuesPechkin 2.0.1
  • TuesPechkin.Wkhtmltox.Win64 0.12.1
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

from tuespechkin.

tuespetre avatar tuespetre commented on September 3, 2024

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!

from tuespechkin.

wc-matteo avatar wc-matteo commented on September 3, 2024

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):

[DllNotFoundException: Unable to load DLL 'wkhtmltox.dll': The specified module could not be found. (Exception from HRESULT: 0x8007007E).]
   TuesPechkin.ThreadSafeConverter.Invoke(FuncShim`1 delegate) +246

from tuespechkin.

tuespetre avatar tuespetre commented on September 3, 2024

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.

from tuespechkin.

wc-matteo avatar wc-matteo commented on September 3, 2024

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).

from tuespechkin.

tuespetre avatar tuespetre commented on September 3, 2024

I've just pushed 2.1.1 which address the issue you've discovered.

from tuespechkin.

wc-matteo avatar wc-matteo commented on September 3, 2024

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?

from tuespechkin.

tuespetre avatar tuespetre commented on September 3, 2024

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.

from tuespechkin.

GaryWang1 avatar GaryWang1 commented on September 3, 2024

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

Public Shared ReadOnly Property convertidor() As IConverter
    Get
        If _converter Is Nothing Then
            SyncLock _PadLock
                If _converter Is Nothing Then
                    'Dim wkhtmltoxPath As String = "C:\Windows\Temp\80570420\4\0.12.2.1"
                    'Dim physicalApplicationPath As String = "C:\inetpub\wwwroot\MySiteRoot"
                    _converter = New ThreadSafeConverter(New RemotingToolset(Of PdfToolset)(New Win32EmbeddedDeployment(New TempFolderDeployment())))
                    '_converter = New ThreadSafeConverter(New RemotingToolset(Of PdfToolset)(New Win32EmbeddedDeployment(New StaticDeployment(physicalApplicationPath))))
                End If
            End SyncLock
        End If
        Return _converter
    End Get
End Property

Any idea to get rid of the recycle application pool when code changes.

Thank you,

Gary

from tuespechkin.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.