[Jifty-commit] jifty branch, cas-memcached, created. 75d11b59bfb3cbb381ec76d6b6de606aac9a3933

Jifty commits jifty-commit at lists.jifty.org
Tue Jan 26 20:56:25 EST 2010


The branch, cas-memcached has been created
        at  75d11b59bfb3cbb381ec76d6b6de606aac9a3933 (commit)

- Log -----------------------------------------------------------------
commit d572a6d5e94bf7f2389ef035d460a174e8395978
Author: Thomas Sibley <trs at bestpractical.com>
Date:   Tue Jan 26 17:23:54 2010 -0500

    Only deflate CAS content upon first request for it

diff --git a/lib/Jifty/CAS/Blob.pm b/lib/Jifty/CAS/Blob.pm
index 1915633..2f7ffaf 100644
--- a/lib/Jifty/CAS/Blob.pm
+++ b/lib/Jifty/CAS/Blob.pm
@@ -60,7 +60,7 @@ Retuens the key calculated for this content.
 
 =cut
 
-__PACKAGE__->mk_accessors(qw(content content_deflated metadata key));
+__PACKAGE__->mk_accessors(qw(content metadata key));
 
 sub new {
     my $class = shift;
@@ -71,9 +71,17 @@ sub new {
         %$args,
     } );
     $self->key( md5_hex( $self->metadata->{hash_with} || $self->content ) );
-    $self->content_deflated( Compress::Zlib::memGzip( $self->content ) )
-        if $self->metadata->{deflate};
     return $self;
 }
 
+sub content_deflated {
+    my $self = shift;
+    return unless $self->metadata->{deflate};
+
+    $self->{content_deflated} = Compress::Zlib::memGzip( $self->content )
+        unless exists $self->{content_deflated};
+
+    return $self->{content_deflated};
+}
+
 1;

commit 75d11b59bfb3cbb381ec76d6b6de606aac9a3933
Author: Thomas Sibley <trs at bestpractical.com>
Date:   Tue Jan 26 20:54:35 2010 -0500

    Jifty::CAS now has a memcached backend

diff --git a/lib/Jifty.pm b/lib/Jifty.pm
index 10c1907..b0dd454 100644
--- a/lib/Jifty.pm
+++ b/lib/Jifty.pm
@@ -166,6 +166,12 @@ sub new {
     Jifty::Util->require( $record_base_class );
     push @Jifty::Record::ISA, $record_base_class unless $record_base_class eq 'Jifty::Record';
 
+    # Configure the base class for Jifty::CAS
+    @Jifty::CAS::ISA = grep { $_ ne 'Jifty::CAS::Store' } @Jifty::CAS::ISA;
+    my $cas_base = Jifty->config->framework('CAS')->{'BaseClass'};
+    Jifty::Util->require( $cas_base );
+    push @Jifty::CAS::ISA, $cas_base unless $cas_base eq 'Jifty::CAS';
+
     # Logger turn on
     Jifty->logger( Jifty::Logger->new( $args{'logger_component'} ) );
 
diff --git a/lib/Jifty/CAS.pm b/lib/Jifty/CAS.pm
index 1e4829e..63eaaeb 100644
--- a/lib/Jifty/CAS.pm
+++ b/lib/Jifty/CAS.pm
@@ -1,9 +1,12 @@
-package Jifty::CAS;
 use strict;
+use warnings;
+
+package Jifty::CAS;
+use base 'Jifty::CAS::Store';
 
 =head1 NAME
 
-Jifty::CAS - Jifty's Content-addressable storage facility
+Jifty::CAS - Jifty's Content-Addressable Storage facility
 
 =head1 SYNOPSIS
 
@@ -28,11 +31,13 @@ stored under a "domain", and can be addressed using wither the "key",
 which is an C<md5> sum, or the "name", which simply stores the most
 recent key provided with that name.
 
-=cut
+=head1 BACKENDS
 
-my %CONTAINER;
-
-use Jifty::CAS::Blob;
+The default data store is an per-process, in-memory store.  A
+L<memcached|Jifty::CAS::Store::Memcached> backed store is also available and
+has the benefits of sharing the cache across all instances of a Jifty app using
+Jifty::CAS.  The memcached store is limited to objects less than 1MB in size,
+however.
 
 =head1 METHODS
 
@@ -42,37 +47,11 @@ Publishes the given C<CONTENT> at the address C<DOMAIN> and C<NAME>.
 C<METADATA> is an arbitrary hash; see L<Jifty::CAS::Blob> for more.
 Returns the key.
 
-=cut
-
-sub publish {
-    my ($class, $domain, $name, $content, $opt) = @_;
-    my $db = $CONTAINER{$domain} ||= {};
-    $opt ||= {};
-
-    my $blob = Jifty::CAS::Blob->new(
-        {   content  => $content,
-            metadata => $opt,
-        }
-    );
-    my $key = $blob->key;
-    $db->{DB}{$key} = $blob;
-    $db->{KEYS}{$name} = $key;
-
-    return $key;
-}
-
 =head2 key DOMAIN NAME
 
 Returns the most recent key for the given pair of C<DOMAIN> and
 C<NAME>, or undef if none such exists.
 
-=cut
-
-sub key {
-    my ($class, $domain, $name) = @_;
-    return $CONTAINER{$domain}{KEYS}{$name};
-}
-
 =head2 retrieve DOMAIN KEY
 
 Returns a L<Jifty::CAS::Blob> for the given pair of C<DOMAIN> and
@@ -80,9 +59,4 @@ C<KEY>, or undef if none such exists.
 
 =cut
 
-sub retrieve {
-    my ($class, $domain, $key) = @_;
-    return $CONTAINER{$domain}{DB}{$key};
-}
-
 1;
diff --git a/lib/Jifty/CAS.pm b/lib/Jifty/CAS/Store.pm
similarity index 53%
copy from lib/Jifty/CAS.pm
copy to lib/Jifty/CAS/Store.pm
index 1e4829e..390955d 100644
--- a/lib/Jifty/CAS.pm
+++ b/lib/Jifty/CAS/Store.pm
@@ -1,40 +1,23 @@
-package Jifty::CAS;
 use strict;
+use warnings;
 
-=head1 NAME
-
-Jifty::CAS - Jifty's Content-addressable storage facility
-
-=head1 SYNOPSIS
-
-  my $key = Jifty::CAS->publish('js' => 'all', $content,
-                      { hash_with => $content, # default behaviour
-                        content_type => 'application/x-javascript',
-                        deflate => 1
-                      });
+package Jifty::CAS::Store;
 
-  $ie_key = Jifty::CAS->publish('js' => 'ie-only', $ie_content,
-                      { hash_with => $ie_content,
-                        content_type => 'application/x-javascript',
-                      });
+=head1 NAME
 
-  $key = Jifty::CAS->key('js', 'ie-only');
-  my $blob = Jifty::CAS->retrieve('js', $key);
+Jifty::CAS::Store - The default, per-process, in-memory store for Jifty's
+Content-Addressable Storage facility
 
 =head1 DESCRIPTION
 
-Provides an in-memory C<md5>-addressed content store.  Content is
-stored under a "domain", and can be addressed using wither the "key",
-which is an C<md5> sum, or the "name", which simply stores the most
-recent key provided with that name.
+This is the default backend store for L<Jifty::CAS>.  For more information, see
+L<Jifty::CAS/DESCRIPTION>.
 
 =cut
 
-my %CONTAINER;
-
 use Jifty::CAS::Blob;
 
-=head1 METHODS
+my %CONTAINER;
 
 =head2 publish DOMAIN NAME CONTENT METADATA
 
@@ -46,7 +29,6 @@ Returns the key.
 
 sub publish {
     my ($class, $domain, $name, $content, $opt) = @_;
-    my $db = $CONTAINER{$domain} ||= {};
     $opt ||= {};
 
     my $blob = Jifty::CAS::Blob->new(
@@ -54,10 +36,21 @@ sub publish {
             metadata => $opt,
         }
     );
+    return $class->_store( $domain, $name, $blob );
+}
+
+=head2 _store DOMAIN NAME BLOB
+
+Stores the BLOB (a L<Jifty::CAS::Blob>) in the backend.  Returns the key.  Don't use this directly, use C<publish> instead.
+
+=cut
+
+sub _store {
+    my ($class, $domain, $name, $blob) = @_;
+    my $db  = $CONTAINER{$domain} ||= {};
     my $key = $blob->key;
     $db->{DB}{$key} = $blob;
     $db->{KEYS}{$name} = $key;
-
     return $key;
 }
 
diff --git a/lib/Jifty/CAS/Store/Memcached.pm b/lib/Jifty/CAS/Store/Memcached.pm
new file mode 100644
index 0000000..cb5ba8b
--- /dev/null
+++ b/lib/Jifty/CAS/Store/Memcached.pm
@@ -0,0 +1,120 @@
+use strict;
+use warnings;
+
+package Jifty::CAS::Store::Memcached;
+
+use base 'Jifty::CAS::Store';
+
+=head1 NAME
+
+Jifty::CAS::Store::Memcached - A memcached backend for Jifty's
+Content-Addressable Storage facility
+
+=head1 SYNOPSIS
+
+Add the following to your Jifty config.yml:
+
+    framework:
+      CAS:
+        BaseClass: Jifty::CAS::Store::Memcached
+
+=head1 DESCRIPTION
+
+This is a memcached backend for L<Jifty::CAS>.  For more information, see
+L<Jifty::CAS/DESCRIPTION>.
+
+=cut
+
+use Cache::Memcached;
+
+our $MEMCACHED;
+
+
+=head1 METHODS
+
+=head2 memcached
+
+Returns the L<Cache::Memcached> object for this class.
+
+=cut
+
+sub memcached {
+    $MEMCACHED ||= Cache::Memcached->new( $_[0]->memcached_config );
+}
+
+=head2 _store DOMAIN NAME BLOB
+
+Stores the BLOB (a L<Jifty::CAS::Blob>) in memcached.  Returns the key.
+
+=cut
+
+sub _store {
+    my ($class, $domain, $name, $blob) = @_;
+
+    # my $db  = $CONTAINER{$domain} ||= {};
+    # $db->{DB}{$key} = $blob;
+    # $db->{KEYS}{$name} = $key;
+
+    my $key = $blob->key;
+    $class->memcached->set("$domain:db:$key", $blob);
+    $class->memcached->set("$domain:keys:$name", $key);
+
+    return $key;
+}
+
+=head2 key DOMAIN NAME
+
+Returns the most recent key for the given pair of C<DOMAIN> and
+C<NAME>, or undef if none such exists.
+
+=cut
+
+sub key {
+    my ($class, $domain, $name) = @_;
+    return $class->memcached->get("$domain:keys:$name");
+}
+
+=head2 retrieve DOMAIN KEY
+
+Returns a L<Jifty::CAS::Blob> for the given pair of C<DOMAIN> and
+C<KEY>, or undef if none such exists.
+
+=cut
+
+sub retrieve {
+    my ($class, $domain, $key) = @_;
+    return $class->memcached->get("$domain:db:$key");
+}
+
+=head2 memcached_config
+
+Returns a hashref containing arguments to pass to L<Cache::Memcached> during
+construction. The defaults are like:
+
+  {
+      servers     => [ '127.0.0.1:11211' ],
+      debug       => 0,
+      namespace   => Jifty->config->framework('ApplicationName'),
+      compress_threshold => 10240,
+  }
+
+To change these options, set them in your Jifty application config file under
+C</framework/CAS/Memcached> like so:
+
+    framework:
+      CAS:
+        BaseClass: Jifty::CAS::Store::Memcached
+        Memcached:
+            servers:
+                - 10.0.0.2:11211
+                - 10.0.0.3:11211
+            compress_threshold: 5120
+
+=cut
+
+sub memcached_config {
+    Jifty->config->framework('CAS')->{'Memcached'}
+        || Jifty->config->defaults->{'framework'}{'CAS'}{'Memcached'}
+}
+
+1;
diff --git a/lib/Jifty/Config.pm b/lib/Jifty/Config.pm
index 1e33a11..f2c4433 100644
--- a/lib/Jifty/Config.pm
+++ b/lib/Jifty/Config.pm
@@ -614,6 +614,15 @@ sub defaults {
                 DefaultTemplateRoot => Jifty::Util->share_root . '/web/templates',
                 SessionCookieName => 'JIFTY_SID_$PORT',
             },
+            CAS => {
+                BaseClass => 'Jifty::CAS::Store',
+                Memcached => {
+                    servers     => [ '127.0.0.1:11211' ],
+                    debug       => 0,
+                    namespace   => $self->framework('ApplicationName'),
+                    compress_threshold => 10240,
+                },
+            },
         }
     };
 

-----------------------------------------------------------------------


More information about the Jifty-commit mailing list