[OT] RE: Getting a Cache::SharedMemoryCache started

2001-03-28 Thread Matt

Hi all,

I eventually found the problem with getting shm to work. I had the
Openwall Linux kernel patch enabled with the "Destroy shared memory
segments not in use" option set, which most Perl IPC functions seem to not
like. Apache and PostgreSQL seem to work fine with this patch in place,
however. Removed the option, and IPC::ShareLite compiles and tests fine so
my SharedMemoryCache now works as exampled.

Thanks

Matt






RE: Getting a Cache::SharedMemoryCache started

2001-03-28 Thread Rob Bloodgood

Thanks for the pointers, unfortunately I've got a problem with the Shared
> cache in that I need IPC::ShareLite, no problem, except it won't test ok,
> I get:
>
> PERL_DL_NONLAZY=1 /usr/bin/perl -Iblib/arch -Iblib/lib
> -I/usr/lib/perl5/i386-linux -I/usr/lib/perl5 test.pl
> 1..8
> ok 1
> ok 2
> IPC::ShareLite store() error: Identifier removed at test.pl line 33

It took me forever, but I finally figured out HOW to deal w/ share memory!
As in, what is the status, what can I change, how can I make garbage go
away?

On Linux (and Solaris, probably others) there is a program called ipcs(8).
This will give you a listing of all shared memory segments, message queues,
and semaphore arrays.

An example (Linux):
-- Shared Memory Segments 
keyshmid owner perms bytes nattchstatus
0x00280267 1 root  644   1048576   0

-- Semaphore Arrays 
key   semid owner perms nsems status
0x00280269 0 root  666   14

-- Message Queues 
key   msqid owner perms used-bytes  messages


NOW, if I wanted to make these go away (AFTER checking that nothing critical
is actually USING these segments!), I would use the companion program
ipcrm(8).

ipcrm shm 1
ipcrm sem 0

the shm 1 line corresponds to the lines above that show shmid 1 under shared
memory.  Likewise, the sem 0 is for the semaphore w/ semid 0.  See the
manpages!

Anyway, whenever I've seen that message, it means that something is barfing
in shared memory.  Usually, something got left behind instead of being
cleaned up.  A quick removal usually takes care of it.   BUT!!!  Don't do
something silly (and dangerous) like deleting ORACLE's shared memory
segments, while it's running.  Fortunately, ipcs(8) shows the owners of
shared memory segments, so this should be reasonable simple to identify.

Hope this helps!

(is this OT? :-)

L8r,
Rob




Re: Getting a Cache::SharedMemoryCache started

2001-03-27 Thread Perrin Harkins

On Tue, 27 Mar 2001, DeWitt Clinton wrote:
> Now, this implies that a module, such as the Cache::MemoryCache, which
> currently shares data for a particular process by creating a global
> hash, would only share data for one instance of the Perl interpreter
> associated with that thread.  If I wanted to extend the cache to share
> data between multiple threads, I would create what Doug calls a
> "solar" variable to hold that hash, correct?

I don't think so.  A solar variable is used for sharing data between
threads with the same parent interpreter, and only for that, but your
Cache::* modules will work with any combination of threads and processes
since the data is really stored outside of the interpreter in shared
memory or files.  Even if you use globals, they are only global to the
current thread.

- Perrin





Re: Getting a Cache::SharedMemoryCache started

2001-03-27 Thread DeWitt Clinton

On Tue, Mar 27, 2001 at 11:57:26PM +0100, Matt wrote:

> Thanks for the pointers, unfortunately I've got a problem with the
> Shared cache in that I need IPC::ShareLite, no problem, except it
> won't test ok,

I'm not sure what the IPC::ShareLite problem is, maybe Maurice Aubrey
does...

In any case, consider switching to Cache::FileCache instead.

Preliminary benchmarks show that FileCache is just as fast as the
SharedMemoryCache, at least on my Linux 2.4 system.  And it is
significantly faster on large caches (either a large number of keys or
large values).

-DeWitt






Re: Getting a Cache::SharedMemoryCache started

2001-03-27 Thread Matt

Thanks for the pointers, unfortunately I've got a problem with the Shared
cache in that I need IPC::ShareLite, no problem, except it won't test ok,
I get:

PERL_DL_NONLAZY=1 /usr/bin/perl -Iblib/arch -Iblib/lib -I/usr/lib/perl5/i386-linux 
-I/usr/lib/perl5 test.pl
1..8
ok 1
ok 2
IPC::ShareLite store() error: Identifier removed at test.pl line 33

I know this isn't strictly "mod_"perl, but seems as people are using the
Cache::Cache package, maybe someone knows the problem.

I'm running Linux 2.2.17 smp, Perl 5.6.0 from Slackware 7.1 btw

Thanks

Matt




Re: Getting a Cache::SharedMemoryCache started

2001-03-27 Thread DeWitt Clinton

On Tue, Mar 27, 2001 at 02:38:34PM -0800, Perrin Harkins wrote:

> On Tue, 27 Mar 2001, DeWitt Clinton wrote:
>
> > I imagine that nearly most Perl libraries are not thread safe, of
> > course.  But code that will be used in mod_perl environments needs
> > to be, right?
> 
> You can read all about it here:
> http://www.apache.org/~dougm/modperl_2.0.html
> 
> The gist is that you probably don't need to change any Perl code, but some
> XS modules on CPAN may have to change.

Great pointer, Perrin.  So, according to Doug:

  The Perl ``ithreads'' implementation ensures that Perl code is
  thread safe, at least with respect to the Apache threads in which it
  is running. However, it does not ensure that extensions which call
  into third-party C/C++ libraries are thread safe. In the case of
  non-threadsafe extensions, if it is not possible to fix those
  routines, care will need to be taken to serialize calls into such
  functions (either at the xs or Perl level).

  Another issue is that ``global'' variables are only global to the
  interpreter in which they are created. Some research has been done
  on the concept of solar variables which are global across all
  interpreter instances. It has not been decided if this feature would
  best fit built into the Perl core or as an extension, but fear not,
  the feature will be provided in one form or another.

Now, this implies that a module, such as the Cache::MemoryCache, which
currently shares data for a particular process by creating a global
hash, would only share data for one instance of the Perl interpreter
associated with that thread.  If I wanted to extend the cache to share
data between multiple threads, I would create what Doug calls a
"solar" variable to hold that hash, correct?  Neat!

Cheers,

-DeWitt



Re: Getting a Cache::SharedMemoryCache started

2001-03-27 Thread Perrin Harkins

On Tue, 27 Mar 2001, DeWitt Clinton wrote:
> Which reminds me of something.  These cache objects are not currently
> thread safe.  When should I start expecting multi-threaded
> apache/mod_perl to become mainstream enough to warrant an overhaul of
> the code?  I imagine that nearly most Perl libraries are not thread
> safe, of course.  But code that will be used in mod_perl environments
> needs to be, right?

You can read all about it here:
http://www.apache.org/~dougm/modperl_2.0.html

The gist is that you probably don't need to change any Perl code, but some
XS modules on CPAN may have to change.

- Perrin




Re: Getting a Cache::SharedMemoryCache started

2001-03-27 Thread DeWitt Clinton

On Tue, Mar 27, 2001 at 05:19:15PM -0500, Pierre Phaneuf wrote:

> DeWitt Clinton wrote:
> 
> > The other question is whether or not to share the cache instance
> > itself globally.  Technically, this is up to you.  Personally I
> > wouldn't bother, considering the overhead of instantiating the
> > cache is so low that I would rather keep it local to the handler
> > (as I did above).  I tend to only share data globally in mod_perl
> > handlers very judiciously, and even then I wrap the data in an
> > object that provides accessor methods.  For an example of an
> > object that wraps shared data, check out Cache::MemoryCache, which
> > simply caches data inside the process.
> 
> Wouldn't this cause the cache to be torn down and rebuilt for every
> request???

The cache instance itself would be, but the data behind it (a global
hash in the case of the MemoryCache, and a IPC::ShareLite store for
the SharedMemoryCache ) would stay around.  Since the instance isn't
that heavy, I feel better instantiating them fresh every request.  If
you need optimal performance, however, you may want to keep the
instance itself global.  

Which reminds me of something.  These cache objects are not currently
thread safe.  When should I start expecting multi-threaded
apache/mod_perl to become mainstream enough to warrant an overhaul of
the code?  I imagine that nearly most Perl libraries are not thread
safe, of course.  But code that will be used in mod_perl environments
needs to be, right?

-DeWitt




Re: Getting a Cache::SharedMemoryCache started

2001-03-27 Thread Pierre Phaneuf

DeWitt Clinton wrote:

> The other question is whether or not to share the cache instance
> itself globally.  Technically, this is up to you.  Personally I
> wouldn't bother, considering the overhead of instantiating the cache
> is so low that I would rather keep it local to the handler (as I did
> above).  I tend to only share data globally in mod_perl handlers very
> judiciously, and even then I wrap the data in an object that provides
> accessor methods.  For an example of an object that wraps shared data,
> check out Cache::MemoryCache, which simply caches data inside the
> process.

Wouldn't this cause the cache to be torn down and rebuilt for every
request???

-- 
"The camel has not evolved to smell good. Neither has Perl."
 -- Larry Wall



Re: Getting a Cache::SharedMemoryCache started

2001-03-27 Thread DeWitt Clinton

On Tue, Mar 27, 2001 at 09:50:33PM +0100, Matt wrote:

> I want to cache some values in my handlers so they don't keep having
> to look stuff up, and so I figured a Cache::SharedMemoryCache would
> be the way to go.

It all depends on what you want to cache and why.  If you wanted to
save a trip to the database on each request, a really simple mod_perl
handler could look something like this:

  package MyApplication;

  use strict;
  use Apache::Request;
  use Cache::SharedMemoryCache;

  sub handler
  {
my ( $request );

my $cache = new Cache::SharedMemoryCache( );

my $data = $cache->get( 'data' );

if ( not defined $data )
{
  $data = expensive_database_request( );

  $cache->set( 'data', $data );
}

$request->content_type( 'text/plain' );
$request->send_http_header( );
$request->print( "data: $data" );
  }
  

The first time this handler is run, the data will not be found in the
cache.  The second time, however, the data will be returned from the
cache, saving a trip to the database.

The other question is whether or not to share the cache instance
itself globally.  Technically, this is up to you.  Personally I
wouldn't bother, considering the overhead of instantiating the cache
is so low that I would rather keep it local to the handler (as I did
above).  I tend to only share data globally in mod_perl handlers very
judiciously, and even then I wrap the data in an object that provides
accessor methods.  For an example of an object that wraps shared data,
check out Cache::MemoryCache, which simply caches data inside the
process.

Hope this helps a bit.  Cheers,

-DeWitt