[Catalyst] Catalyst::Component/Model Instances and Attributes per Request

Tomas Doran bobtfish at bobtfish.net
Mon Jul 12 19:08:07 GMT 2010


On 12 Jul 2010, at 15:34, Derek Wueppelmann wrote:

> On Sat, 2010-07-10 at 13:37 -0400, Alejandro Imass wrote:
>> If in a Catalyst::Component, say an extension of Catalyst::Model, the
>> attributes of my instance are also per-request. In other words if I  
>> do
>> $self->yuca($c->stash->{yuca}) in ACCEPT_CONTEXT and return $self,
>> will $self->yuca in the Model _instance_ in a separate memory space
>> for this request?

No.

Each process is in a separate memory space if you're using FCGI or  
mod_perl or something, but it's not entirely certain (if you use  
Catalyst::Engine::PSGI and Corona (for example) then multiple requests  
can be in-flight and sharing the same logicial memory space  
application (they just have different instances of the request context).

However doing what you suggest above will work for FCGI/mod_perl (or  
generally anything forked), although it's a bit icky - the instance of  
your Model lasts forever, and so bashing some of the instance data in  
each request works..

I would however you return an entirely new instance constructed in  
ACCEPT_CONTEXT, or use Catalyst::Component::InstancePerContext if  
you'd like the instance you build to be scoped to the request.

>> I would suspect that a Catalyst::Controller instance
>> is paired with a single Model instance for a specific request....

No.

Nothing implies that controllers own models - they're entirely  
independent (and there can be many controllers and many models  
involved in processing a request).

>> but
>> I'm afraid that being an _instance_ instead of a class, the  
>> attributes
>> may get overriden by a second request that could be running in a
>> parallel process or thread, say in mod_perl running on Apache prefork
>> or worker (threads). Then again, I guess I'm answering myself as one
>> request will run in one process or thread and the data segment is
>> protected by the underlying OS, so I see no way a second request can
>> override the attributes of a model instance.

But you're correct here.

>> From my understanding when you make a request to the system all the
> variable and objects are localized to the scope of that request.

Incorrect. If you write into a global variable in request 1, then  
request 2 (which happens in _that process_) will be able to see the  
data.

> So
> making multiple requests open multiple scopes and the data does not  
> mix
> between them. If you require data to survive past a single request  
> this
> is where the session object comes in. You can then store data and
> objects that are required to survive past a single request here,  
> however
> this are specific for the session so don't mix with other requests  
> that
> are not related to the session.

But this is kinda right - you can't be certain that you'll get the  
same application server process twice in a row, so you need to persist  
data in some way that ensures whatever app server process answers it  
can find the data..

Cheers
t0m




More information about the Catalyst mailing list