stonecolddevin has asked for the wisdom of the Perl Monks concerning the following question:

Hey everyone.

I'm attempting to write a system that manages user sessions for a website where users can post their school notes.

Currently, I'm trying to display the number of viewers "lurking" (aka "Guests"), and display the username for each user that is logged in (their name dissappears from the list after they log out or their session expires, not exactly a new idea.).

I'm having a heck of a time trying to figure this section out. I'm using CGI::Session, and am probably going to migrate to Apache::Session. However, this doesn't solve the problem of figuring out how to

A) Insert user's information that are logged on into a database table,

B) expire their session/set their logged_in parameter to '0',

C) Pull the above two together so that I have something similar to what perlmonks has ("Other users lurking in the monastery"), along with a count of guests with active sessions ("Guests online: $Number").

Part A's fairly easy, but I need to design part A so it's compatible with part B and C.

My main goal is to avoid redundancy. I want to expire the session stuff once, not have to expire a session file/database record, and the stuff in the table for users online.

I'm tired, and I've tried all of what I know to exhaustion. Any ideas, wise monks?

meh.
  • Comment on Session management: counting number of users currently viewing website and displaying users online
  • Download Code

Replies are listed 'Best First'.
Re: Session management: counting number of users currently viewing website and displaying users online
by fenLisesi (Priest) on Nov 03, 2006 at 12:03 UTC
    CGI::Session serializes the session object and writes the whole thing into a single column in the database (i assume that you are using a rdbms). I think the maintainers are considering changing this and allowing the user to put session attributes into their own database columns. If that were the case, you could define "currently lurking" as "has done something in the last n seconds" and do a query on the access time. Currently, you would have to retrieve all unexpired sessions and loop over them. The maintainers of the module are responsive. HTH.

      Now this is going against my previous statement of wanting to avoid redundancy...but would it be a bad idea just to roll my own that uses independent database columns per each session parameter? (save the actual ->param() method, those could be grouped together as an AoH or something in one column) Because as it stands, it seems like generating the MD5 session id, creating an expire method, deleting sessiongs, etc. on my own would be a lot simpler than scratching my head over either Apache::Session or CGI::Session.

      Am I going crazy or does this sound reasonable?

      meh.
        Well, it always seems to start this way for me, too, and then I usually find myself in mission creep and eventually end up with a lot of duplicated effort.

        There are reasonable arguments in favor of rolling-your-own instead of using bloated modules, but CGI::Session doesn't seem to be one of the worst offenders.

        You could probably get rid of some functionality there, too. For example, you may be sure that you will only ever want to work with postgres and solder that right into your module and throw away the database portability business. But time has a way of slowly rotting sureness away. Suppose the European office of your company starts using your application and they see that the [^a-zA-Z] chars are not sorting the way they were taught in school. Now you need to add COLLATE to your queries, but surprise, postgres does not support that yet, but mysql does (it is possible to use Perl to collate, though probably not as efficiently as the rdbms would do it, but please ignore that, I am just trying to put forth an unexpected situation :). Finding the unstable balance between feature-rich and lightweight can be a dark art.

        An important point to consider is maintainability. In my opinion, the real asset of a good CPAN module is its set of tests, even more so than the actual code. When you have accumulated a comprehensive set of tests, and keep adding to the set every time you find a new bug or a potential pitfall that you didn't think of before, then maintenance becomes a breeze. You just patch the code and run the tests, as often as possible. While that does not guarantee that all is well with your patch, it greatly reduces the chance that you just broke something that you coded a few weeks ago and will not even realize that for some time and when you finally do, your new fix will then break your original patch and god knows what else. You should ask yourself whether you are ready to allocate the resources to develop and maintain tests -- not a trivial undertaking -- for a task for which there already is a widely used CPAN module.

        My recommendation would be to study the source code of the module and its tests. That is likely to give you a headache for a day, until you internally make it your own. Then you will start finding a little bug here, a nice refactor there and enjoy the joys of sharing. Perhaps you will find that this module is awfully written and you would never rely on anything like it and there, you will have your answer.

Re: Session management: counting number of users currently viewing website and displaying users online
by jbert (Priest) on Nov 03, 2006 at 09:10 UTC
    I haven't built anything serious in it, but I was impressed with amount of off-the-shelf stuff available in the Catalyst framework.

    e.g. there are a bunch of different Catalyst plugin's to handle sessions, storing them in different places via different mechanisms: e.g. Catalyst::Plugin::Session::Store::DBI and friends.

    As you say, this isn't a new idea - it looks like there are nice black boxes to be plugged together, but you would have to do things the "catalyst way", which takes a little learning.

Re: Session management: counting number of users currently viewing website and displaying users online
by rhesa (Vicar) on Nov 03, 2006 at 23:35 UTC
    You might be interested in CGI::Session::PureSQL. It's not as flexible as regular CGI::Session, but it would definitely make it easier to implement your features. Since that module uses regular database columns to store session data, you wouldn't have such a hard time querying the entire sessions table.
A reply falls below the community's threshold of quality. You may see it by logging in.