OIPI PDF Collisions & Corruption (temp folder?) (OpenInsight 32-Bit)
At 15 NOV 2010 03:57:22AM Matthew Jones wrote:
OI v9.2.0, UD4.6.
We have an OI server app that acts as a request processor.
It launches OI sessions to execute tasks that include processes and reports, and these can create PDF files.
Several OI sessions can execute requests at the same time on the same server, in the same console session.
The problem we have is that multiple PDF files can be in the process of being created at precisely the same time in different OI sessions, and we repeatedly experience PDF file corruption when this happens.
The result of the corruption is either a PDF file with varying amounts of data in it, which is unreadable in Adobe Reader, or worse still, a perfectly readable PDF file supposedly created by one process but with the contents of the PDF created by another process!
Obviously this is critical as it has resulted in invoices and statements being sent to the wrong people as the content of one PDF gets overlayed with another!!
When OI creates PDF's on OIv9.2.0 it uses the Windows temp folder for the temporary files it creates.
The "pdftemp_xxxx…tx1", "OIPI_zzzz…CSV" and "OIPI_zzzz…TXT" files that are created in the temp folder are unique to each process so there are no collisions there.
However there are other files created during the PDF file creation process, such as "Pg{n}.emf" and perhaps others, and these are not unique. It seems to be these other files that are causing the corruption.
As a result, I have tried getting the temporary PDF files created in unique folders for each session by setting both the ENV_DOS_SORT_VOL$ and the ENV_OIPI_SAVE_PATH$ to unique folders for each session, but the PDF files continue to be created in the Windows temp folder.
Unfortunately the Windows temp folder is the same for each session, and I cannot manipulate that on an OI-session by OI-session basis, so I cannot escape the collisions.
Does anyone know if it's possible, and if so how, to tell OIPI where to create its temporary files when creating PDF's?
The code I have tried to set these paths is as follows:
// check before [/color]xoipiAtPath=[/color]@environ_setENV_OIPI_SAVE_PATH$] xoipiPath=Get_Env( ENV_OIPI_SAVE_PATH$ ) xdosAtPath=[/color]@environ_setENV_DOS_SORT_VOL$] xdosPath=Get_Env( ENV_DOS_SORT_VOL$) [/color]// do it here [/color]WindowsTempPath=RTI_OS_Directory( [/color]"GetWindowsTempPath" [/color]) userPath=[/color]@username [/color]:[/color]'_'[/color]: GetCurrentProcessId() sortPath=WindowsTempPath : userPath bExists=RTI_OS_Directory( [/color]"EXISTS"[/color], sortPath ) [/color]begin case case [/color]( bExists eq -[/color]1 [/color]) bExists=RTI_OS_Directory( [/color]'CREATE'[/color], sortPath ) [/color]case [/color]( bExists eq [/color]0 [/color]) [/color]case [/color]( bExists eq [/color]1 [/color]) [/color]case [/color]1 [/color]bExists=[/color]0 [/color]end case if [/color]bExists [/color]then [/color]sortPath := [/color]'\' [/color]Set_Env( ENV_DOS_SORT_VOL$, sortPath, [/color]0 [/color]) set_sort_file( sortPath ) Set_Env( ENV_OIPI_SAVE_PATH$, sortPath, [/color]0 [/color]) [/color]end [/color]// check after [/color]yoipiAtPath=[/color]@environ_setENV_OIPI_SAVE_PATH$] yoipiPath=Get_Env( ENV_OIPI_SAVE_PATH$ ) ydosAtPath=[/color]@environ_setENV_DOS_SORT_VOL$] ydosPath=Get_Env( ENV_DOS_SORT_VOL$) [/color][/color][/size]Any help on this greatly appreciated.
Thanks in advance.
Matthew Jones.
At 15 NOV 2010 08:05AM Dave Harmacek wrote:
Try adding this setting to @environ_set
EQU ENV_UNIQUE_STATION_ID$ TO 40 ;* 1=Append ProcessID to 'normal' @station
Another thought:
We have a process server running that starts Adobe Acrobat to accept a .pdf file, do a OCR of that file, then do a "burst" into single pages. For this I use locking to keep the processor from running more than one instance of Adobe Acrobat at a time.
Dave
At 15 NOV 2010 11:02AM Bob Orsini wrote:
Matthew, I do not see the temp files as being the issue. The only temp file created by the PDF process is the pdfttemp_xxx file and this file has the vsprint handle embedded in the file name so it is not duplicated. Two or more oipi sessions on the same computer should not be duplicating the temp file for PDF's.
Are you using OIPI or OIPI.NET and is the location or name of the actual PDF file different for each session.
At 15 NOV 2010 07:41PM Matthew Jones wrote:
Thanks for that Dave.
We already build @Station with networkusername.computername.sessionname.processid, so the main temp files are already unique.
I would really prefer to not have to put a lock around the PDF create process as that would turn a flexible "multi-threaded" engine back into a single, sequential process, which kind of defeats the purpose of what we're trying to do.
If I could just get the PDF create to use a unique temp folder that I can nominate, I think I would be ok! :)
Cheers,
Matthew Jones.
At 16 NOV 2010 04:07AM Matthew Jones wrote:
Hi Bob,
We are using OIPI, and we use guid's to create the actual final pdf file names, so these are unique.
When the corruption occurs, we usually have all the "pdf" output files we wanted, and they are named correctly. It's the contents of the files that's corrupted.
The only time this varies is that occasionally the corruption is such that one or more pdf files cannot be created at all.
It's difficult to work out just what temp files are being created of course, as they are deleted immediately afterwards, but we are seeing other files in addition to the "pdftemp_xxx" files:
OIPI_zzzz...CSV - the filename includes @station, which we have made unique, so this is not a problemOIPI_zzzz...TXT - these filenames also includes @station, so are not a problem~DFB841.tmp - these filenames vary but look like this, and the content looks to contain some part of the pdf file before being finally output, although I am not positive about that.Pg{n}.emf - this is an actual image file of a page of the final pdf being created.We have not experienced the problem when trying to create multiple simple columnar text report based pdf's at the same time. The problem seems to occur when we create multiple pdf documents that contain a combination of a letterhead image as well as text. I suspect this combination of image(s) and text is triggering the creation of other temp files which is leading to our problem.
Is it possible to tell OIPI what folder to create these temp pdf files in - I think that would solve everything?
This is a core and critical piece of functionality for us, and we really need to get it right.
Any help is much appreciated.
Many thanks.
Matthew Jones.
At 16 NOV 2010 10:57AM Bob Orsini wrote:
There is no way at this point to tell OIPI to create the tempfiles in different locations. I still do not believe that this is the issue. I ran tests creating graphical pages and running pdfs on the same machine at the same time without any issues. The temp file used for the pdf has the window handle in the name so should not interfere with other sessions. I am not sure where the pg{n}.emf files are coming from. I do not see these here and OIPI does not create these.
At 18 NOV 2010 04:48AM Matthew Jones wrote:
I have now confirmed without doubt that this is a problem.
Running the following code as described produces "Not able to produce PDF file" messages and / or corrupt pdf file(s) every time the test is run.
compile subroutine [/color]mrlPDF_Problem1( void ) [/color] [/color]// this stored procedure runs in the EXAMPLES application // save it and compile it // open 5 engines in the EXAMPLES application // on 4 of them, open the System Monitor and type RUN MRLPDF_PROBLEM1 // they will wait in a loop for a record "MRLPDF" to exist in table CUSTOMERS // on the 5th engine, open a record in table CUSTOMERS and do a save as to "MRLPDF" // every time I have run this it fails // I believe the problem is that OIPI creates non-unique temporary files in the Windows temp folder // [/color]declare function [/color]RTI_CreateGUID, RTI_OS_Directory, Set_Printer [/color] [/color]open [/color]'CUSTOMERS' [/color]to [/color]fhCustomers [/color]else end [/color] [/color]fldrMyDocs=RTI_OS_Directory( [/color]"GetMyDocuments" [/color]) [/color] [/color]// wait until there's a certain record, then the pdf create processes will start at the same time! [/color]bFound=[/color]0 [/color]Loop read [/color]aRec [/color]from [/color]fhCustomers, [/color]'MRLPDF' [/color]then [/color]bFound=[/color]1 [/color]until [/color]bFound [/color]Repeat [/color] [/color]// put in a tiny delay between engines by locking a virtual record // without this, it gives "Not able to write PDF file" // I think, because it's at "the same" time? [/color]bLocked=[/color]0 [/color]for [/color]i=[/color]1 [/color]to [/color]10 [/color]lock [/color]fhCustomers, [/color]'MRL'[/color]:i [/color]then [/color]bLocked=[/color]1 [/color]until [/color]bLocked [/color]next [/color]i [/color]For [/color]i=[/color]1 [/color]to [/color]5 [/color]aLine=str( i, [/color]40 [/color]) pdfFileName=fldrMyDocs :[/color]'\pdf'[/color]:i:[/color]'_'[/color]: RTI_CreateGUID() :[/color]'.pdf' [/color]spFileName=[/color]"Report "[/color]:i :[/color]@fm[/color]: [/color]@fm[/color]: [/color]6 [/color]:[/color]@fm[/color]: pdfFileName spPrintSetup=[/color]4 [/color]:[/color]@vm[/color]: [/color]@vm[/color]: [/color]1 [/color]:[/color]@vm[/color]: [/color]3 [/color]x=Set_Printer( [/color]"INIT"[/color], spFileName, [/color]"Report "[/color]:i:[/color]" Title"[/color], [/color]""[/color], [/color]0[/color], spPrintSetup ) x=Set_Printer( [/color]"BMP"[/color], [/color]"BMPS\mp3splash.bmp"[/color], [/color]1 [/color]:[/color]@fm[/color]: [/color]0[/color], [/color]1[/color], [/color]0 [/color]) x=Set_Printer( [/color]'STARTTABLE' [/color]) aTable=[/color]'' [/color]for [/color]j=[/color]1 [/color]to [/color]200 [/color]aTable := [/color]@fm[/color]: aLine [/color]next [/color]j aTable[/color]1[/color],[/color]1[/color]=[/color]'' [/color]colFormat=[/color]'strHeader=[/color]'Description '[/color]:i x=Set_Printer( [/color]'ADDTABLE'[/color], colFormat, strHeader, aTable, [/color]''[/color], [/color]''[/color], [/color]''[/color], [/color]7 [/color]) x=Set_Printer( [/color]'ENDTABLE' [/color]) x=Set_Printer( [/color]"TERM" [/color]) [/color]next [/color]i [/color] [/color]// just unlock all, we're done by now [/color]for [/color]i=[/color]1 [/color]to [/color]10 [/color]unlock [/color]fhCustomers, [/color]'MRL'[/color]:i [/color]else null next [/color]i [/color] [/color]end[/color][/color][/size]This is critical functionality for us, and we really need a solution.
To be able to specify the temporary folder for pdf creation would provide a solution, I believe, although would of course require changes to the OI code set.
Running the code above with OIPI.NET creates the pdf files without error.
However, I have found at least one separate problem with OIPI.NET which is preventing me from continuing down that path for the moment.
I shall open a separate thread about that problem.
In the meantime, I would certainly appreciate a solution to this, if one is available.
Thanks.
Matthew Jones.
At 18 NOV 2010 10:50AM Bob Orsini wrote:
By running OIPI in this manner your temp files will have exactly the same name becuase they are running in the same session with the same handle. However I ran this code and did not encompass a problem. The 10 pdf files had the correct data. I am not sure how this would be an issue because the temp and PDF files are not rendered until after the term and the temp tile is deleted before doing the next i. You might try call set_printer('VSPRINTER','CLOSE') after the term statement to force a close on the preview which will make the next init command come up with a new handle.