Visual Report Writer and The Web (III)
by, 23-Apr-2013 at 12:58 AM (2614 Views)
This is the third blog about Visual Report Writer and the Web. Did you already digest the other two blogs (Solution Page and Invoices Report)? If not, I suggest you read them first. This blog is about cleanup at the server. It is not the last one in the serie.
From the blog about Invoices Report you should have learned that the integration library instructs Visual Report Writer to create a PDF file with the output of the report. By default this output file is only for the current session and can be made only available for a certain amount of time. The output is stored in a cache folder. The standard output folder is named Cache and resides inside the Reports folder. The cache folder does not have to be a sub-folder of the reports folder but it is by default and it is advisable as This folder is not web shared and files are not public accessible. The function ReportCacheFileName (member of the cVRWReport class) creates a unique file name in the cache folder. Certainly if a lot of users/sessions create reports the cache folder will soon be big and a lot of files are no longer accessible. How long should the files in there be kept? Who should be responsible for cleanup?
The files should be available as long as the URL that is generated can be used. The URL generated by the cWebResourceManager can be bound to the sessionkey and can be made to expire by setting a timeout specified in hours. By default the timeout is set to 0 which means infinitive. If you want to have the URL not available for that time span you have to set the piDownloadTimeout property of the ghoWebResourceManager object. You can do this globally or per report but keep in mind that the value is always global and if not set again will be applied for the next URL. While it is possible to not bind the URL to the current sessionkey it is not advised to do so else anyone can copy the URL and pass it to someone else and they can read the file contents.
i see three ways to cleanup the cache folder. They are:
Cleanup routine inside your application
- Program that performs the cleanup started by the Windows scheduler. This may even be a batch file.
- Part of the webserver backup plan. Of course you have your schedule to backup the data on the server and the cleanup could be done as part of that activity.
- Have a routine inside your web application that periodically cleans the cache folder. This option is discussed here in this blog as it is in use for the Visual Report Writer Live Demo website.
While it is important to cleanup the process should not make your web application slower. To avoid this happens I made the cleanup in the live demo website to operate once in each 50 times that a request is received by one of the web applications in the pool. There is not such a thing as timer at the webserver itself and this counter based activity sounds Ok to me. The only downside is that it will be accessed a number of times in a row as each of the applications in the pool uses its own counter. I could have created a shared counter but that requires a bit of I/O that I did not want to use.
I wrote the cleanup routine in a self created object named oVRWReportsManager and since this is not really a web object it is an instance of the cObject class, the most empty class in the product. The cleanup routine is invoked from OnAttachProcess in the cWebApp object.
The above code snippet is the bottom part of the cWebApp object in WebApp.src. The routine does not need to be at the bottom but it just is.Code:Procedure OnAttachProcess Forward Send OnAttachProcess Send Cleanup of oVRWReportsManager End_Procedure End_Object Send StartWebApp of oWebApp
In the cVRWReportsManager object I defined a regular DataFlex property named piAccessed and it is incremented by the message Cleanup. As soon as it becomes 50 or higher the cleanup starts and the property is set back to zero. If 50 would be too often it could be easily changed.
When the counter hits 50 the current date and time is retrieved via a CurrentDateTime() function and the cache folder is enumerated with Windows API functions to see if there are files that are older than 180 minutes. If they are the files are deleted. The following code does do this.
The ConvertDateTimeToSystemDateTime is not a built in routine but a function I wrote a long time ago (1999/2000) and published via the Data Access knowledge base. The winFindFile, winFindNextFile function are defined in the cWorkspace.pkg file.Code:Procedure Cleanup Integer iAccessed iRetval iMinutes String sCachePath sFileName Handle hFindFile tWin32_Find_Data FileData DateTime dtNow dtCreated TimeSpan tsDiff Get piAccessed to iAccessed Increment iAccessed If (iAccessed > 50) Begin Move (CurrentDateTime ()) to dtNow Get ReportsCacheFolder of oVRWReport to sCachePath Move (winFindFirstFile (sCachePath - '*.*', AddressOf (FileData))) to hFindFile If (hFindFile <> INVALID_HANDLE_VALUE) Begin Repeat If (not (IsFlagIn (FILE_ATTRIBUTE_DIRECTORY, FileData.dwFileAttributes))) Begin Get ConvertDateTimeToSystemDateTime FileData.ftCreationLowDateTime FileData.ftCreationHighDateTime to dtCreated Move (dtNow - dtCreated) to tsDiff Move (SpanTotalMinutes (tsDiff)) to iMinutes If (iMinutes > 180) Begin Move (AddressOf (FileData.cFileName)) to sFileName Move (sCachePath - sFileName) to sFileName Move (DeleteFile (AddressOf (sFileName))) to iRetval End End Move (winFindNextFile (hFindFile, AddressOf (FileData))) to iRetval Until (iRetval = 0) Move (winFindClose (hFindFile)) to iRetval End Move 0 to iAccessed End Set piAccessed to iAccessed End_Procedure
I hope this blog helps you further on your path to use the DataFlex Web Framework in combination with Visual Report Writer.