You are viewing a plain text version of this content. The canonical link for it is here.
Posted to modperl@perl.apache.org by brian moseley <bc...@maz.org> on 2001/08/04 08:33:43 UTC
odd behavior with Cache::Cache
i'm observing some behavior using Cache::Cache that seems
odd, altho it may be due to my faulty understanding of how
the interface works.
i'm using Cache::MemoryCache to manage a cache of session
objects in a non-forking apache process. once i've initially
called set to store a session object using its session id as
the key, i then call get a couple of times per request to
get the session object out of the cache. problem is, each
time i call get, i'm apparently getting a different instance
of the session class! furthermore, each instance's variables
are the values that were originally set at creation time,
regardless of whether i update the variables during later
requests or not.
here's a snippet of my debug output for two subsequence
requests:
# first request. the server has just started, so there are
# no cached sessions (the requested session id refers to an
# invalid session). we create a new session (with a new id),
# set it in the cache, then get it back out for later use.
# notice the final get call seems to return a different
# instance than the set call!
get session for id [39a0a4ce81943263b25474c20b087586]:
get session for id [39a0a4ce81943263b25474c20b087586]:
get session for id [b2ac8e8d51f4512c4bcf8476126f54a5]:
set session for id [b2ac8e8d51f4512c4bcf8476126f54a5]: Wombat::Core::Session=ARRAY(0x886a838)
get session for id [b2ac8e8d51f4512c4bcf8476126f54a5]: Wombat::Core::Session=ARRAY(0x88863bc)
# second request. each get call is finding /something/ for
# the given key, but again it seems to be a different
# instance each time!
get session for id [b2ac8e8d51f4512c4bcf8476126f54a5]: Wombat::Core::Session=ARRAY(0x88bc8f4)
get session for id [b2ac8e8d51f4512c4bcf8476126f54a5]: Wombat::Core::Session=ARRAY(0x88c06dc)
i see this behavior regardless of whether i'm using
Cache::MemoryCache with a non-forking apache or
Cache::SharedMemoryCache with a forking apache. so i feel
that either i'm doing something wrong in my usage of the
Cache::Cache interface, or i'm overlooking some obvious perl
behavior.
any idea what might be going wrong?
Re: odd behavior with Cache::Cache
Posted by DeWitt Clinton <de...@unto.net>.
On Sat, Aug 04, 2001 at 03:06:37PM -0400, DeWitt Clinton wrote:
> To quote Jimi Williams, "manager's decision."
Yes, I know it is Jimy Williams. See what happens when a lifelong Red
Sox fan relocates down to NYC? We start losing our minds... :)
-DeWitt
Re: odd behavior with Cache::Cache
Posted by DeWitt Clinton <de...@unto.net>.
On Sat, Aug 04, 2001 at 09:17:21AM -0700, brian moseley wrote:
> could this be because i'm only ever doing one set, at
> session creation time? since i'm using a memory cache, i
> didn't expect to have to call set every time i modify the
> cached data.
Yup. That would be it. Please see my response to my next post (the
one in which you mention solving the problem).
> also i didn't know that Storable was used underneath. why is
> this necessary?
To quote Jimi Williams, "manager's decision." I decided to optimize
for the more common scenario in which one is pulling objects out of
the cache and modifying them. Rather than force the user to manually
clone the retrieved object, I figured that it was better to do the
clone up front and require the user to store the object again if they
modify it. This is to preserve consistent semantics and behavior
across the various cache implementations. I.e., what works for
MemoryCache should work for the SharedMemoryCache or the FileCache as
well.
That's not to say one couldn't subclass MemoryCache to have the
alternate behavior you propose...
-DeWitt
Re: odd behavior with Cache::Cache
Posted by brian moseley <bc...@maz.org>.
On Sat, 4 Aug 2001, DeWitt Clinton wrote:
> Excellent, this is the right approach. Sounds like I
> need to update the documentation to say that "objects
> retrieved from the cache are not 'live,' they are
> clones. If you want to save modifications, remember to
> store them again in the cache."
yeah, that would be helpful. thanks.
> Please see my last email on the subject, but for all
> intents and purposes, I'd like caches to behave
> consistently, but we could definitely create a special
> purpose "live" memory-based cache that does what you
> want.
fair enough. when i get around to profiling, if this is an
issue, i'll see what can be done.
> However, the good news is that there isn't really a race
> on writes. Basically, the last write wins. It is tough
> to really figure out (from the cache's perspective) what
> the appropriate behavior is in all cases. So the user
> should be responsible for locking if them want it. Of
> course, that should be done through the cache API, which
> I regretfully haven't added yet.
ok. no hurry :) thanks for the help.
Re: odd behavior with Cache::Cache
Posted by DeWitt Clinton <de...@unto.net>.
On Sat, Aug 04, 2001 at 10:34:34AM -0700, brian moseley wrote:
> ps: i've modified my code to 1) only get once per request
> and 2) set at the end of each request. the net effect is
> that stuff works as expected. i'm reasonably happy with the
> current state of affairs, but...
Excellent, this is the right approach. Sounds like I need to update
the documentation to say that "objects retrieved from the cache are
not 'live,' they are clones. If you want to save modifications,
remember to store them again in the cache."
> i don't like having to explicitly call set to force modifications to
> be written to the cache, and i'd prefer that get always return the
> same instance that i originally set. can these issues be considered
> for a future version of the interface? i see the need for the
> current behavior when using file-based caches, but perhaps there's a
> way to streamline operations for memory caches? perhaps Storable can
> be bypassed for memory caches?
Please see my last email on the subject, but for all intents and
purposes, I'd like caches to behave consistently, but we could
definitely create a special purpose "live" memory-based cache that
does what you want.
> also, has there been any thought given to locking cached
> items? when i'm using a shared cache with multiprocess
> apache, the opportunity exists for multiple requests to
> access a single session simultaneously, which can lead to
> races. which i'm happy to ignore for now but would be nice
> to eventually prevent.
A number of people have requested this, and I think it is a good idea.
For some back-end implementations, locking is conceptually easy to do,
such as the FileCache on a POSIX system. And the SharedMemoryCache
already does some locking using IPC::ShareLite. However, I wanted to
wait until I came up with the right level of granularity for the
locking API. Plus, it would require a non-trivial bit of a rewrite to
separate the front-end of the cache (which would block on locks) from
the back-end (which would be aware of the locks and manage them).
However, the good news is that there isn't really a race on writes.
Basically, the last write wins. It is tough to really figure out
(from the cache's perspective) what the appropriate behavior is in all
cases. So the user should be responsible for locking if them want it.
Of course, that should be done through the cache API, which I
regretfully haven't added yet.
Cheers,
-DeWitt
Re: odd behavior with Cache::Cache
Posted by Perrin Harkins <pe...@elem.com>.
> My impression was that the locking in Apache::Session is a one-time lock
so
> it just fixes data integrity issues. So I am not sure if it is fancier
than
> Cache::Cache unless Cache::Cache has no locking at all (or no concept of
> lock choice).
What I meant was that since there is a separate locking API used to
implement Apache::Session, it should be possible to just use, for example,
Apache::Session::Lock::Semaphore without using any other part of
Apache::Session.
- Perrin
Re: odd behavior with Cache::Cache
Posted by Gunther Birznieks <gu...@extropia.com>.
At 05:44 PM 8/5/2001 -0400, Perrin Harkins wrote:
>on 8/4/01 1:34 PM, brian moseley at bcm@maz.org wrote:
> > also, has there been any thought given to locking cached
> > items? when i'm using a shared cache with multiprocess
> > apache, the opportunity exists for multiple requests to
> > access a single session simultaneously, which can lead to
> > races. which i'm happy to ignore for now but would be nice
> > to eventually prevent.
>
>Gunther's Extropia stuff includes optional support for sessions that lock in
>the way you're describing, but I've never seen any other session
>implementation that did it this way. It seems that the session pattern is
>generally used for transient data where last-save-wins is fine as long as
>the integrity of the data is protected during the actual writes. If you
>need fancier locking, you could try ripping the lock stuff out of
>Apache::Session.
>
>- Perrin
My impression was that the locking in Apache::Session is a one-time lock so
it just fixes data integrity issues. So I am not sure if it is fancier than
Cache::Cache unless Cache::Cache has no locking at all (or no concept of
lock choice).
I was really interested in abstracting the locking API for
Extropia::Session because it was an interesting challenge and frankly at
the time I *thought* that Apache::Session did it, so I wanted to match it.
In addition, the motivation for Extropia::Session was to match the Java
Servlet Session spec so I wanted to make sure that whatever protections
were provided by Java, I would have in Perl multiprocessing environment.
The latter being fairly difficult to emulate exactly.
In the end, I don't think I have actually written any applications that
would cause two session updates to occur at the same time, so it might have
been overkill.
I am lately thinking of session as a means to store very transient stuff
but then real persistent application data such as cart data from a web
store should be stored in a real data storage with real multi-user locking
with the session id as a mere key to that database.
I guess it just depends on your scenario. I would be curious to hear about
some real world (as opposed to academic) scenarios about it being an issue.
Later,
Gunther
__________________________________________________
Gunther Birznieks (gunther.birznieks@eXtropia.com)
eXtropia - The Open Web Technology Company
http://www.eXtropia.com/
Re: odd behavior with Cache::Cache
Posted by Perrin Harkins <pe...@elem.com>.
on 8/4/01 1:34 PM, brian moseley at bcm@maz.org wrote:
> also, has there been any thought given to locking cached
> items? when i'm using a shared cache with multiprocess
> apache, the opportunity exists for multiple requests to
> access a single session simultaneously, which can lead to
> races. which i'm happy to ignore for now but would be nice
> to eventually prevent.
Gunther's Extropia stuff includes optional support for sessions that lock in
the way you're describing, but I've never seen any other session
implementation that did it this way. It seems that the session pattern is
generally used for transient data where last-save-wins is fine as long as
the integrity of the data is protected during the actual writes. If you
need fancier locking, you could try ripping the lock stuff out of
Apache::Session.
- Perrin
Re: odd behavior with Cache::Cache
Posted by brian moseley <bc...@maz.org>.
ps: i've modified my code to 1) only get once per request
and 2) set at the end of each request. the net effect is
that stuff works as expected. i'm reasonably happy with the
current state of affairs, but...
i don't like having to explicitly call set to force
modifications to be written to the cache, and i'd prefer
that get always return the same instance that i originally
set. can these issues be considered for a future version of
the interface? i see the need for the current behavior when
using file-based caches, but perhaps there's a way to
streamline operations for memory caches? perhaps Storable
can be bypassed for memory caches?
also, has there been any thought given to locking cached
items? when i'm using a shared cache with multiprocess
apache, the opportunity exists for multiple requests to
access a single session simultaneously, which can lead to
races. which i'm happy to ignore for now but would be nice
to eventually prevent.
On Sat, 4 Aug 2001, brian moseley wrote:
> On Sat, 4 Aug 2001, DeWitt Clinton wrote:
>
> > Can you check the actual data contained within the
> > object? If I understand things right, there is a chance
> > that the data itself is indeed the same. However, the
> > instance containing the data (in your case, an instance
> > of Wombat::Core::Session) will be different because it
> > is going through Storable's freeze and thaw during the
> > persistence process. Therefore a new instance is
> > created when you call get, but it is identical with
> > respect to the data to the one you stored with the set.
>
> the data is definitely different. i am using a simple
> servlet that allows me to specify a name and value to be
> bound into the session. when i reload the page, however, the
> name and value are no longer bound into the session. also,
> on each request, the session's last accessed time is updated
> after the first get, but after the second get i see the
> original time, not the updated one.
>
> could this be because i'm only ever doing one set, at
> session creation time? since i'm using a memory cache, i
> didn't expect to have to call set every time i modify the
> cached data.
>
> also i didn't know that Storable was used underneath. why is
> this necessary?
>
Re: odd behavior with Cache::Cache
Posted by brian moseley <bc...@maz.org>.
On Sat, 4 Aug 2001, DeWitt Clinton wrote:
> Can you check the actual data contained within the
> object? If I understand things right, there is a chance
> that the data itself is indeed the same. However, the
> instance containing the data (in your case, an instance
> of Wombat::Core::Session) will be different because it
> is going through Storable's freeze and thaw during the
> persistence process. Therefore a new instance is
> created when you call get, but it is identical with
> respect to the data to the one you stored with the set.
the data is definitely different. i am using a simple
servlet that allows me to specify a name and value to be
bound into the session. when i reload the page, however, the
name and value are no longer bound into the session. also,
on each request, the session's last accessed time is updated
after the first get, but after the second get i see the
original time, not the updated one.
could this be because i'm only ever doing one set, at
session creation time? since i'm using a memory cache, i
didn't expect to have to call set every time i modify the
cached data.
also i didn't know that Storable was used underneath. why is
this necessary?
Re: odd behavior with Cache::Cache
Posted by DeWitt Clinton <de...@unto.net>.
On Fri, Aug 03, 2001 at 11:33:43PM -0700, brian moseley wrote:
> i'm observing some behavior using Cache::Cache that seems
> odd, altho it may be due to my faulty understanding of how
> the interface works.
Can you check the actual data contained within the object? If I
understand things right, there is a chance that the data itself is
indeed the same. However, the instance containing the data (in your
case, an instance of Wombat::Core::Session) will be different because
it is going through Storable's freeze and thaw during the persistence
process. Therefore a new instance is created when you call get, but
it is identical with respect to the data to the one you stored with
the set.
So it may actually be working, and just doesn't appear that way. Or,
I may be completely wrong. :)
-DeWitt