Recently I've been toying with Apache::Session a bit more as part of a new web application
that I'm building (MVCC framework implemented in PageKit). One feature of this application is
to allow its users to upload multiple images. However, I have to store those images in the database (mysql) rather than conventional
way on the hard-drive (hack, either way things end up on HD, but you know what I mean eh? :).
This is one of the key requirements of this web app. Storing images in the database
provides for greater control as images belonging to one user may not be viewed by anyone else
but the same user.
On one particular form I'm allowing a logged in user to upload up to 5 jpeg images + additional
information for each. There's also a bunch of extra fields on the form. One decision that I have
to make is where do I store the image data until all of the form is completed? How do I manage
temporary form data (large images) and also make sure that the system is not overloaded
with too much of that temporary data? Apache::Session is good in a way that sessions may expire,
and when they do all data associated with a session is eliminated thereby freeing up resources and
etc.
There are a few alternative routes which I'd looked into:
- Keep a record of the image in session. This record will only hold image description and
path to the temporary file on the server. The image and it's content won't be committed
to the database until after the entire form is completed (not just the image portion).
Displaying the (small version of) image on the (yet-to-be-completed) form will then be a
trivial matter of pointing to the temporary image url.
As soon as the form is submitted the temporary image files will be removed from the server.
However, if the user simply shuts his/her browser, there is no way to immediately remove the images.
One option is I could write a Perl script that would run from cron and clean the temporary image
directory of files that are too old.
Yet, considering my application security requirements, with this option there's a lot of
chance of making these images available to the internet public. So, this being highly undesirable
I've opted not to go ahead with this approach.
- Keep image description and it's content in session. Write a script to display the
image from session on the form. This script will basically have to spit out 'image/jpeg' content
from the session. The clear advantage is that only the current signed in user is able
to access his images. The draw back is that since I've configured my session
data to be stored in a database 'sessions' table (standard) adding new images will further
load my server (and is also slower than the disk file option in the first approach).
Once the form is submitted, image data is saved into the database and removed from session space.
On browser close, however, data will remain in session until it expires (?). As is the case with
the first approach, I'd have to provision for a way of cleaing the sessions table off expired
session keys?
- Keep image description and content in a global hash (remember this is mod_perl) under user
session key. One advantage here is that adding new images and retrieving image content
is pretty quick and doens't require database resources. Also, as with the previous approach,
only the currently signed in user is able to access his/her images.
Concering performance issues, if the global data grows large (users keep shutting their
browsers after having uploaded 5+ images :) I may have to restart the server. Restarting the
server too often doesn't smell 'the right way' either ;).
But even with this option, there's a way to clean the global hash data. For example, I could
add additional 'handler' (a method in the model class of the MVCC framework) that would allow
a web administrator to view all session data and clean it up as needed (say, clean all expired
sessions only).
So, which out of the above options you feel will work best for me? Or from your own experience,
what was the approach that you took and how did it all play out? At this stage, I'm hanging between
the second and third options. Each look appealing to me, making it all the harder to decide which
is the right one to pursue.
Please pardon me for keeping this post so long. I've tried to be as clear as possible (which I doubt
I've achieved :). I've also decided to make it a 'meditational' post due to the fact that the
questions I'm asking here require moderate discussion and pondering. Frankly, the more people
I could get input from the better ;-)
_____________________
# Under Construction