Forum How do I...?

problems on win2000

dorianwinterfeld
I am running prince 5.1r9 on a Windows2000 server running IIS5.0.
I am serving PDFs dynamically with Perl using code I found in the Prince docs:

open(PRINCE, "| $princecmd --no-embed-fonts -");
print PRINCE $html || die "can't write to prince; $!";
close(PRINCE);

$html is valid xhtml 1.0 strict, btw and $princecmd is the path to prince.exe.

I have a problem; the server is getting bogged down with prince.exe processes. It seems that after the PDFs are displayed prince is not exiting. I have to kill them via task manager every day or else the server slows down.

Has anyone had this problem or have a clue how to fix it?

Thanks -
Dorian Winterfeld
dorian@uaqa.com
mikeday
Hi Dorian,

There are a few potential issues that could prevent Prince from terminating in this manner:

#1: Your code is closing the PRINCE file handle, which is good: this means that the input stream will be closed and Prince will stop trying to read input and get busy producing PDF output.

#2: The generated PDF file is showing up in the output stream, which is also good: this means that Prince is not getting stuck along the way.

#3: One remaining possibility is that Prince is trying to print out an error message or something like that to the error stream and is unable to do so, and hence is waiting indefinitely.

To fix this issue you could try adding the "--silent" option to the Prince command-line. This currently undocumented option will stop Prince from trying to print out any error or warning messages.

If you need to see error or warning messages, then you could try also passing the "--log=FILE" option, which will direct Prince to append error and warning messages to the specified log file.

Best regards,

Michael
dorianwinterfeld
Thanks Michael, I've started logging the prince output and I've been running some tests. I am occasionally seeing warning messages like this:

2006-08-25 12:10:52, Reading, grade 3, 3.A.7.f
Fri Aug 25 12:10:52 2006: ---- begin
Fri Aug 25 12:10:53 2006: ---- end
Fri Aug 25 12:19:01 2006: ---- begin
Fri Aug 25 12:19:03 2006: warning: no glyphs for character U+2220
Fri Aug 25 12:19:03 2006: warning: no glyphs for character U+2220
Fri Aug 25 12:19:04 2006: warning: no glyphs for character U+0097
Fri Aug 25 12:19:04 2006: warning: no glyphs for character U+0085
Fri Aug 25 12:21:28 2006: warning: embedding font "Verdana, Regular"
Fri Aug 25 12:21:39 2006: ---- end

The first line is from the calling CGI routine. It is passed three params, does a database query, generates a string of xhtml and passes that to prince. Could the warning messages be causing the problem?

- Dorian
mikeday
The first line is from the calling CGI routine. It is passed three params, does a database query, generates a string of xhtml and passes that to prince. Could the warning messages be causing the problem?

The warning messages relate to UNICODE characters that are not supported by the currently specified font(s). Specifically, U+2220, which is the angle symbol: (It should look like a little angle if your browser supports it).
∠ABC = 30°

You may be able to find a symbol or mathematical font that supports this character, but it is not supported by Verdana or Times New Roman.

The warnings concerning U+85 and U+97 are a little bit more suspicious, as these are not commonly used characters; U+85 is the "NEXT LINE" or "NEL" line terminator, generally only used on old IBM mainframes, while U+97 is a tranmission control code and hardly a true character at all. These characters appearing in the XML document probably indicate some kind of encoding issue, perhaps where text has been entered into the database in UTF-8 encoding but then retrieved out by a program that assumes that it is in ISO-8859-1 or Windows-1252 encoding instead, breaking some characters. If you like you can email us the document and we might be able to track down whether some characters have been switched around.

The final warning states that the Verdana font is being embedded into the PDF file even though you passed --no-embed-fonts on the command-line. This is because fonts must be embedded when characters outside of the MacRoman subset of UNICODE are used. Not a big issue, really.

None of these warnings should cause any problems with zombie Prince processes or anything like that. The one possibility that I was thinking of is that if Prince was trying to write the warnings to the standard error stream and that stream was blocked, then Prince might wait indefinitely to print the warnings, leading to many Prince processes hanging around. You can eliminate this possibility by passing --silent on the command-line, which will stop Prince from attempting to print to stderr. If there are still zombie Prince processes that fail to terminate then the problem must be caused by something else, perhaps a Windows-specific Perl quirk, that we can try to workaround some other way.

Best regards,

Michael
dorianwinterfeld
Michael - We are still having the same issue. For a while we replaced the links for dynamic PDFs with static PDFs that I was generating on our development box, but this is not a long term solution. As soon as I put the dynamic version, with error logging, back on the production server we started seeing the orphaned prince.exe processes again. I noticed something in the error log that might be a clue:

2006-09-23 9:17:37, VSC, Reading, grade 4, 2.A.4.a
Sat Sep 23 09:17:37 2006: ---- begin
Sat Sep 23 09:17:38 2006: ---- end
2006-09-23 11:38:56, VSC, Reading, grade 5, 3.A.8.b
2006-09-23 12:55:14, VSC, Reading, grade 8, 3.A.4.a
Sat Sep 23 12:55:15 2006: ---- begin
Sat Sep 23 12:55:16 2006: ---- end

Notice how the record at 11:38:56 has no begin or end lines after it? seems that prince.exe is hanging at this point, before it has a chance to write to the log file. This time seems to correspond with how long the thread was running before I killed it in Task Manager. Any clue why this would happen?

One solution is to find a way to kill the orphaned processes but I would rather find out why this is happening. Any help would be appreciated.

- Dorian
mikeday
Notice how the record at 11:38:56 has no begin or end lines after it? seems that prince.exe is hanging at this point, before it has a chance to write to the log file. This time seems to correspond with how long the thread was running before I killed it in Task Manager. Any clue why this would happen?

Printing the "begin" message to the log is practically the first thing that Prince does, so if the Prince process is being started and does not terminate but the log message is not appearing that is quite strange.

I assume that you are using the same command-line every time you invoke Prince, and only the document being written to it differs?

We will try to reproduce the problem here and see what is going on. Perhaps there is a better way for a Perl script to invoke the Prince process safely.
dorianwinterfeld
"I assume that you are using the same command-line every time you invoke Prince, and only the document being written to it differs?"

Yes, same command line. And all the XHTML being sent to prince uses the same template w/ different content.

We are able to recreate the problem by rapidly double-clicking. I am going to prevent double-clicking via JavaScript and see if the incidence of orphaned processes decreases. But this is not my favorite solution.
mikeday
We are able to recreate the problem by rapidly double-clicking.

So when two or more Prince processes are started concurrently, one or more of them will fail to terminate? However, I understand from the timestamps in the log messages that you posted that the previous example failed to terminate even though it was the only Prince running?
dorianwinterfeld
Well, that's true. Double-clicking seems to be one cause of the problem but not the only cause. The logs indicate that sometimes prince hangs when the link is only clicked once! I can't explain this, I can only tell you what seems to be happening. I log into the server several times every day and I found orphaned processes every time. If I don't kill them they accumulate and bog down the server. Thanks for your quick responses. If you have any suggestions please let me know.

- Dorian
mikeday
One question is what happens to the Perl CGI script that spawns the zombie Prince process. Does it hang around as well, or does it terminate normally? If the code looks like this:
open(PRINCE, "| $princecmd --no-embed-fonts -");
print PRINCE $html || die "can't write to prince; $!";
close(PRINCE);

then you would expect the close(PRINCE) call to block until the Prince process terminates. If the close isn't waiting then that would be suspicious, as then the Perl CGI script could terminate before Prince has finished generating the PDF file, which could be awkward. So if you see Prince zombie processes still running, check if there are also Perl CGI scripts still running. (You would assume that if they time out and get killed automatically, then the Prince process that they have invoked should also be killed, but you never know).
dorianwinterfeld
Yes. The perl processes are hanging too. When I kill the Prince process the perl dies as well.
mikeday
A couple of quick questions: are the zombie Prince processes using any CPU time at all, or are they just sitting there using 0% of the available CPU? Also, are there any remote images in your documents, eg. any images specified using HTTP URLs that would require network access?

One thing that you might want to try is writing the generated XHTML to a file somewhere with a unique name (just make a filename including the current process id or date/timestamp) then running Prince on the file instead of writing the XHTML to Prince directly. Doing it this way might help to see whether there is some deadlock issue causing the hanging Prince process. The call to Prince would then look something like this: "$princecmd $filename -" with the trailing hyphen to tell Prince to write the PDF output to stdout. Presumably you could call Prince using system() rather than needing to open a file handle.

Sorry for all the inconvenience, but I think we're getting there! :)
mikeday
Oh, one more thing: it might be best to check the value of open(), like this:
open(PRINCE, "| $princecmd --no-embed-fonts -") || die "can't run prince";
print PRINCE $html || die "can't write to prince; $!";
close(PRINCE);

I suppose that it is possible that if open failed for some reason, then the print statement could block trying to write the XHTML to the process. Anyway, it's good practice to check the return value.
dorianwinterfeld
thanks Michael,

My actual open statement is:

if (! open(PRINCE, "| $princecmd --no-embed-fonts --log=\"$errlog\" -")){
print "Error starting Prince\n";
exit;
}

Since I started using a javascript double-click checker yesterday I have not seen any orphaned prince processes. I'm keeping my eye on the server.

- Dorian
dorianwinterfeld
We're still finding an orphaned processes on the order of one every few days. But we are getting ready to launch a new section if the website that has many more dynamic prince links and I'm afraid that we'll see more orpaned process when we do. Does anyone else have this problem? Is it unique to perl? At this point I'm looking for a tool that we can run via Task Manager that will wake up and kill any orphaned prince.exe processes that it finds. Any suggestions?
mikeday
It would be nice to solve the problem altogether rather than having to use another program to kill the zombie processes! :)

I had some questions and suggestions before:

A couple of quick questions: are the zombie Prince processes using any CPU time at all, or are they just sitting there using 0% of the available CPU? Also, are there any remote images in your documents, eg. any images specified using HTTP URLs that would require network access?

One thing that you might want to try is writing the generated XHTML to a file somewhere with a unique name (just make a filename including the current process id or date/timestamp) then running Prince on the file instead of writing the XHTML to Prince directly. Doing it this way might help to see whether there is some deadlock issue causing the hanging Prince process. The call to Prince would then look something like this: "$princecmd $filename -" with the trailing hyphen to tell Prince to write the PDF output to stdout. Presumably you could call Prince using system() rather than needing to open a file handle.

I strongly recommend trying the system() approach to see if this solves the problem.
dorianwinterfeld
Thanks Michael, I'll try using system(). I did try an experiment where I wrote xhtml to disk and then called prince, also writing the PDF to disk. No problems.

BTW, the zombie processes _are_ using quite a bit of CPU time. What we are doing for now is running "kill prince.exe" via the Task Scheduler every hour and that seems to be taking care of the problem. But I would like to solve it eventually.
mikeday
This issue may be fixed in the Prince 5.1 rev 14 maintenance release, which includes a fix for a deadlock that was affecting the Java interface on Windows in some situations.