[Catalyst] Sessions stored only at end of request

Chris Czub chris.czub at gmail.com
Mon Mar 10 14:31:47 GMT 2008


I have a method triggered by clicking a submit button on my web application
that runs in the background(I enabled multi-threading on my Catalyst app)
that takes a little bit of time to perform and has multiple steps inside of
it. I would like to inform the user of the current status of this method.


Here's the code that I have that calls the method...

code:
------------------------------

    my $callback =3D sub {
        warn "logging status ".$_[0];
        $c->session->{'roll_status'} =3D $_[0];
    };

    if (eval { $somemodel->perform_action($params,
      $callback) }) {
        # action performed successfully
        $c->stash->{'json_status'} =3D SUCCESS;

    } else {
        # action failed
        $c->log->debug("error occured during perform_action");
        $c->stash->{'json_status'} =3D $@;
    }
------------------------------

$repo is a model object containing the method that does the work... then in
perform_action, it looks something like this...

code:
------------------------------

sub perform_action {
    my $self =3D shift;
    my ($params, $status_callback) =3D @_;

    # some work is done here that takes a few seconds
    $status_callback('doing step 1');

    # other stuff that takes a few seconds
    $status_callback('doing step 2');

    # more more more stuff that takes a few seconds
    $status_callback('doing step 3');

    # last bit of work done...
    $status_callback('Done!');

    return 1;
}
------------------------------

So when I watch my logs, I see...

code:
------------------------------

logging status doing step 1
logging status doing step 2
logging status doing step 3
logging status Done!
------------------------------

occur one after another every few seconds as the code runs, as I would
expect.

So then I have this method to check the status...

code:
------------------------------

sub get_roll_status : Regexp('^([^\/]+)\/get_roll_status$') {
    my $self =3D shift;
    my ($c) =3D @_;


    $c->stash->{'json_roll_status'} =3D $c->session->{'roll_status'};
    $c->stash->{'template'} =3D 'rolltool/roll_status.tt2';
}
------------------------------

and it ALWAYS returns "Done!" no matter what step is currently underway.
>From what I can tell, Catalyst waits to set the session variables until the
entire request is complete, then does them all at once. The same behavior is
exhibited if, instead of warn I use $c->log->debug(); statements... nothing
appears while the work is being done, then once it is done it prints out all
the statuses at once to my debug log.


What would you do to get around this? I could write the status to a file
locally and read from that but that seems to go against the Catalyst-way. I
tried using a cache and that did not work. I also do not wish to use a
JobQueue because requests are allowed to happen at the same time(I realize
right now the way the session variable is set up it could step on itself,
but I just want to get this working then I'll use a better data structure)
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://lists.scsys.co.uk/pipermail/catalyst/attachments/20080310/0c85d=
2f6/attachment.htm


More information about the Catalyst mailing list