Today I've been working with wkhtmltopdf.exe in a web app and I was wondering whether I should use a lock (or the singleton pattern) in order to call Process.Start in a thread-safe manner.
My concern is that multiple users will do GETs simultaneously on the page that calls the exe file mentioned above. It's my understanding that each Request is created on its own thread, does this mean that calling an exe file (with Process.Start) is thread-safe in a web application?
Process.Start has nothing to do with thread safety. It is a thread safe call - you can call it as many times you want from as many threads you want. The problem that comes with this is that you are depending on an external process to do the job. Spawning multiple processes in an intensively used web application is not a good idea as you will be consuming more and more resources. So while this could be fine if your site doesn't have a big load, it is not recommended if you expect to start scaling.
Yeah, I know that converting HTML to PDF in a reliable and performant way which doesn't involve spawning processes and be happy with the final result costs money. But scalability of a web application usually comes at a cost.
Related
TLDR; is it possible to send/receive objects between an app and a 3rd party launch agent?
I'm writing an extension for an existing app (A). It's packaged and I do not have access to the source - but I can write simple plug-ins that can do some basic Cocoa and host a UI. Read: very limited options.
Ideally, what I'd like to do is have the plugin in app (A) message an external service (B) [sending objects], have (B) do some heavy lifting, then respond back to (A) so the UI can update.
I've been reading up on Launch Agents and they look promising, but I noted the examples all use basic types - no objects. I found one post discussing how to use Distributed Objects, but that's about it. It looks great, but what worries me is I'm not seeing a whole lot of current information on DO and I can't tell if it's something Apple will continue to support going forward.
Does anyone have any suggestions on options for a scenario like this? Maybe I'm just approaching this the wrong way?
Another option is I just completely split this out - write a separate full app and have (A) open it up with AppleScript. The UX wouldn't be as nice, but it would also work.
Thank you,
Eric
NOTE: I can't use NSTask. Or at least I've failed utterly to get it to work in this specific situation. Due to issues with app (A) it breaks when some of the methods run within the process. If I could somehow spawn NSTask so it was executing completely outside of (A) that might be an option. Which is actually what prompted me to look at Launch Agents...
I do understand that the first wcf call is usually very slow. And that is the case in my app. I have tried to apply various solutions I have found through out internet with very little progress.
But the thing that puzzles me is the fact that all subsequent wcf calls even after having exited and reentered the app after few minutes are very fast. Am I correct in thinking that android somehow keeps some dll or whatever resource related to wcf infrastructure in some memory cache so that even after reentering the app calls are fast ? If that is the case, can I use this same technique to keep "wcf resources" ready to fire for my app? (I hope my question is clear :-) Thank you in advance
I am working with the QuickTime API and need to perform a few lengthy (as in hours) operations in the background. Unfortunately, it is not multi-thread friendly, so I am falling back to perform the tasks in a separate process, so all QuickTime related calls can happen in its main thread.
After launching it, I need a way of getting feedback on its progress, since the operations can take very long.
I am unsure of how to do this, specifically:
Should the separate process be compiled as another cocoa app or a command line tool?
How to launch it from the main cocoa app?
How to periodically get an object from it to get status information?
How to determine when it finished?
How to avoid showing a window/console when called?
How to have it part of the .app bundle so that it does not appear as a separate executable to the user?
These are really 6+ questions, but they are very related and very specific, and I think anyone needing to launch external processes (instead of spawning worker threads) can benefit from their answers. Generic code examples would be very helpful.
If it is possible, then implement the functionality in a command line tool, or another form of GUI-less application. For Cocoa applications it is possible to prevent them appearing on the Dock or in the Force Quit dialog, however a command line tool is a single binary file which does that anyway, so that would probably be a better way.
In terms of launching the tool, NSTask & NSPipe are your friends in this endeavour. The tool can definitely be kept inside your main Application's bundle, inside the Resources directory or some such, and then launched when needed. You can use the pipe to communicate back and forth.
I don't have any example code to hand, and its been a long while since I've had occasion to use either of these classes so the information I can give is limited, but it should be enough to point you in the right direction.
I work on a Classic ASP web application that uses several old COM components written in VB6. All of the VB6 components are registered in a COM+ application that run in their own dllhost process. A large majority of the application has been converted to .Net, but there are still a lot of legacy pages and components. COM Interop is used in both directions, calling some .Net assemblies from classic ASP and VB6 as well as calling VB6 components from ASP.Net. The application is running on Windows Server 2008 R2 (IIS 7.5) in the classic pipeline mode.
For the most part the application works fine. The transition to .Net effort was ultimately abandoned, with a new product being developed instead. In the meantime, the old product must be maintained in it's heterogeneous state.
I am having trouble tracking down an intermittent problem where the web application hangs. Users just see a blank screen while their browser waits and the server never responds. The hang persists until I manually kill the dllhost process that's hosting the VB6 components, so I believe the problem is buried there. Probably a memory leak or runaway circular loop.
There are thousands of users on the system daily, but the problem only happens once or twice a week. Fortunately we have a web farm that automatically pulls a server out when it stops responding, so the customer impact is zero. Still, I would like to figure out what's going on.
I have recompiled all of the VB6 components to include debugging symbols and redeployed to production. When the problem happens, I use the 32-bit task manager (c:\windows\syswow64\taskmgr.exe) to take a crash dump of the dllhost process. I end up with a dllhost.dmp file, which I bring down to my development workstation and open in VS2010. I have the .pdb symbol files that VB6 created in my symbols path. When I start the debugging session in VS2010, I can go to the Modules screen and see that indeed all of the symbols for my components are loaded.
Where to go from here? The call stack doesn't show any of my own components. It looks like this:
The disassembly at the top of the call stack looks like this:
Not sure what else I can do. I examined all of the locals at every frame of the call stack and it's gibberish to me. I don't see any references to any of my own components.
Perhaps WinDbg would yield more information? Not sure where to start with it.
I'm pretty sure that if I could just find what VB6 class/method was being called when the hang occurred that I could get to the bottom of it. I've tried adding some logging, and the results are inconsistent.
Perhaps there's nothing wrong with my VB6 components at all, but I'm hitting on some bug within Windows or IIS?
Any advice would be appreciated, but throwing away VB6 is not an option at this point. Thanks.
Not a complete answer, but CoRegisterSurrogateEx is documented to block as long as the surrogate process is running:
The CoRegisterSurrogateEx function is a blocking function. It does not
return until COM+ has determined that the process will be shut down.
Before calling this function, initialize COM on this thread as a
multi-threaded apartment (MTA).
So I don't think the error is on this call-stack. (You can see it was still blocking on a WaitForSingleObject call, most likely the mechanism it uses to block until the process is to be shut down).
Note: I couldn't decide whether this was more appropriate for Stack Overflow or Serverfault, so if you have some insight into that, let me know.
Background: Recently, my server (Windows 2000, MS SQL 2005, IIS 5.0, ASP Classic) experienced a spike in traffic to a specific set of ASP pages. This spike caused a massive drain on the processor, spiking it at 100% and causing all kinds of timeout problems for the visitors.
We've actually handled larger volumes in traffic than this without error. The problem seemed to be that the specific ASP scripts being called were using a huge amount of processor time. Using the Process Explorer from Sysinternals, I found that dllhost.exe was taking up all of the processor time. Looking at its threads, the culprit was calls to COMSVCS.DLL, which seems to be COM+ objects.
So, it seems like my ASP pages are calling COM+ objects and it's killing my processor.
Here's the question: How do I determine which parts of my ASP scripts are calling the COM+ objects, and how would I begin to improve performance from these parts? I have basically no background in Windows programming, so I am at a loss of how to begin.
Thanks for your help.
Neither COM+ or DLLHOST are likely your problem, they are just the containers that the web site and COM objects are running in. The actual objects they are being "fed" are your issue and/or the ways/frequency they are being called by the web app.
A more productive way to isolate the problem would be to look at the IIS logs for the pages with the longest processing time and have a programmer analyze what is going on in that page and what objects are being called.
Specifically, check the "time-taken" column in the IIS log.
For determining what objects are being called, look for
<OBJECT ID=MyObject RUNAT=SERVER PROGID=MyDll.MyObject></OBJECT>
or
set myObject = server.createobject("MyDll.MyObject")
inside your ASP pages.
Beware that this could be calling standard DLL (not COM+ objects). The method for instantiation is the same for both types.
If you want to know what COM+ processes are you running, check out the Component Services app.
alt text http://img38.imageshack.us/img38/5062/capturerm.png