| File | /data/SimpleDB-Class/author.t/../lib/SimpleDB/Class/Cache.pm |
| Statements Executed | 511 |
| Statement Execution Time | 17.6ms |
| Calls | P | F | Exclusive Time |
Inclusive Time |
Subroutine |
|---|---|---|---|---|---|
| 24 | 2 | 2 | 1.16ms | 25.3ms | SimpleDB::Class::Cache::get |
| 17 | 3 | 3 | 809µs | 8.44ms | SimpleDB::Class::Cache::set |
| 1 | 1 | 1 | 538µs | 9.28ms | SimpleDB::Class::Cache::BEGIN@32 |
| 1 | 1 | 1 | 440µs | 2.45ms | SimpleDB::Class::Cache::BEGIN@31 |
| 41 | 2 | 1 | 371µs | 832µs | SimpleDB::Class::Cache::fix_key |
| 1 | 1 | 1 | 283µs | 1.35ms | SimpleDB::Class::Cache::BEGIN@33 |
| 1 | 1 | 1 | 187µs | 7.65ms | SimpleDB::Class::Cache::BEGIN@30 |
| 3 | 3 | 1 | 123µs | 1.93ms | SimpleDB::Class::Cache::flush |
| 41 | 1 | 2 | 110µs | 461µs | SimpleDB::Class::Cache::CORE:subst (opcode) |
| 1 | 1 | 1 | 38µs | 2.22ms | SimpleDB::Class::Cache::BEGIN@29 |
| 1 | 1 | 1 | 26µs | 112µs | SimpleDB::Class::Cache::__ANON__[../lib/SimpleDB/Class/Cache.pm:106] |
| 1 | 1 | 1 | 11µs | 134µs | SimpleDB::Class::Cache::BEGIN@448 |
| 0 | 0 | 0 | 0s | 0s | SimpleDB::Class::Cache::__ANON__[../lib/SimpleDB/Class/Cache.pm:38] |
| 0 | 0 | 0 | 0s | 0s | SimpleDB::Class::Cache::delete |
| 0 | 0 | 0 | 0s | 0s | SimpleDB::Class::Cache::mget |
| Line | State ments |
Time on line |
Calls | Time in subs |
Code |
|---|---|---|---|---|---|
| 1 | package SimpleDB::Class::Cache; | ||||
| 2 | |||||
| 3 | |||||
| 4 | =head1 NAME | ||||
| 5 | |||||
| 6 | SimpleDB::Class::Cache - Memcached interface for SimpleDB. | ||||
| 7 | |||||
| 8 | =head1 DESCRIPTION | ||||
| 9 | |||||
| 10 | An API that allows you to cache item data to a memcached server. Technically I should be storing the item itself, but since the item has a reference to the domain, and the domain has a reference to the simpledb object, it could cause all sorts of problems, so it's just safer to store just the item's data. | ||||
| 11 | |||||
| 12 | =head1 SYNOPSIS | ||||
| 13 | |||||
| 14 | use SimpleDB::Class::Cache; | ||||
| 15 | |||||
| 16 | my $cache = SimpleDB::Class::Cache->new(servers=>[{host=>'127.0.0.1', port=>11211}]); | ||||
| 17 | |||||
| 18 | $cache->set($domain->name, $id, $value); | ||||
| 19 | |||||
| 20 | my $value = $cache->get($domain->name, $id); | ||||
| 21 | my ($val1, $val2) = @{$cache->mget([[$domain->name, $id1], [$domain->name, $id2]])}; | ||||
| 22 | |||||
| 23 | $cache->delete($domain->name, $id); | ||||
| 24 | |||||
| 25 | $cache->flush; | ||||
| 26 | |||||
| 27 | =cut | ||||
| 28 | |||||
| 29 | 3 | 36µs | 2 | 4.40ms | # spent 2.22ms (38µs+2.18) within SimpleDB::Class::Cache::BEGIN@29 which was called
# once (38µs+2.18ms) by SimpleDB::Class::BEGIN@139 at line 29 # spent 2.22ms making 1 call to SimpleDB::Class::Cache::BEGIN@29
# spent 2.18ms making 1 call to Moose::Exporter::__ANON__[Moose/Exporter.pm:389] |
| 30 | 3 | 127µs | 1 | 7.65ms | # spent 7.65ms (187µs+7.46) within SimpleDB::Class::Cache::BEGIN@30 which was called
# once (187µs+7.46ms) by SimpleDB::Class::BEGIN@139 at line 30 # spent 7.65ms making 1 call to SimpleDB::Class::Cache::BEGIN@30 |
| 31 | 3 | 125µs | 2 | 2.47ms | # spent 2.45ms (440µs+2.01) within SimpleDB::Class::Cache::BEGIN@31 which was called
# once (440µs+2.01ms) by SimpleDB::Class::BEGIN@139 at line 31 # spent 2.45ms making 1 call to SimpleDB::Class::Cache::BEGIN@31
# spent 21µs making 1 call to Exporter::import |
| 32 | 3 | 151µs | 1 | 9.28ms | # spent 9.28ms (538µs+8.74) within SimpleDB::Class::Cache::BEGIN@32 which was called
# once (538µs+8.74ms) by SimpleDB::Class::BEGIN@139 at line 32 # spent 9.28ms making 1 call to SimpleDB::Class::Cache::BEGIN@32 |
| 33 | 3 | 1.21ms | 2 | 1.55ms | # spent 1.35ms (283µs+1.07) within SimpleDB::Class::Cache::BEGIN@33 which was called
# once (283µs+1.07ms) by SimpleDB::Class::BEGIN@139 at line 33 # spent 1.35ms making 1 call to SimpleDB::Class::Cache::BEGIN@33
# spent 197µs making 1 call to Exporter::import |
| 34 | Params::Validate::validation_options( on_fail => sub { | ||||
| 35 | my $error = shift; | ||||
| 36 | warn "Error in Cache params: ".$error; | ||||
| 37 | SimpleDB::Class::Exception::InvalidParam->throw( error => $error ); | ||||
| 38 | 1 | 4µs | 1 | 12µs | } ); # spent 12µs making 1 call to Params::Validate::validation_options |
| 39 | |||||
| 40 | |||||
| 41 | |||||
| 42 | =head1 METHODS | ||||
| 43 | |||||
| 44 | These methods are available from this class: | ||||
| 45 | |||||
| 46 | =cut | ||||
| 47 | |||||
| 48 | #------------------------------------------------------------------- | ||||
| 49 | |||||
| 50 | =head2 new ( params ) | ||||
| 51 | |||||
| 52 | Constructor. | ||||
| 53 | |||||
| 54 | =head3 params | ||||
| 55 | |||||
| 56 | A hash containing configuration params to connect to memcached. | ||||
| 57 | |||||
| 58 | =head4 servers | ||||
| 59 | |||||
| 60 | An array reference of servers (sockets and/or hosts). It should look similar to: | ||||
| 61 | |||||
| 62 | [ | ||||
| 63 | { host => '127.0.0.1', port=> '11211' }, | ||||
| 64 | { socket => '/path/to/unix/socket' }, | ||||
| 65 | ] | ||||
| 66 | |||||
| 67 | =cut | ||||
| 68 | |||||
| 69 | #------------------------------------------------------------------- | ||||
| 70 | |||||
| 71 | =head2 servers ( ) | ||||
| 72 | |||||
| 73 | Returns the array reference of servers passed into the constructor. | ||||
| 74 | |||||
| 75 | =cut | ||||
| 76 | |||||
| 77 | 1 | 2µs | 1 | 1.77ms | has 'servers' => ( # spent 1.77ms making 1 call to Moose::has |
| 78 | is => 'ro', | ||||
| 79 | required => 1, | ||||
| 80 | ); | ||||
| 81 | |||||
| 82 | #------------------------------------------------------------------- | ||||
| 83 | |||||
| 84 | =head2 memcached ( ) | ||||
| 85 | |||||
| 86 | Returns a L<Memcached::libmemcached> object, which is constructed using the information passed into the constructor. | ||||
| 87 | |||||
| 88 | =cut | ||||
| 89 | |||||
| 90 | has 'memcached' => ( | ||||
| 91 | is => 'ro', | ||||
| 92 | lazy => 1, | ||||
| 93 | clearer => 'clear_memcached', | ||||
| 94 | # spent 112µs (26+85) within SimpleDB::Class::Cache::__ANON__[../lib/SimpleDB/Class/Cache.pm:106] which was called
# once (26µs+85µs) by Class::MOP::Mixin::AttributeCore::default at line 53 of Class/MOP/Mixin/AttributeCore.pm | ||||
| 95 | 6 | 106µs | my $self = shift; | ||
| 96 | my $memcached = Memcached::libmemcached::memcached_create(); # spent 57µs making 1 call to Memcached::libmemcached::memcached_create | ||||
| 97 | foreach my $server (@{$self->servers}) { # spent 4µs making 1 call to SimpleDB::Class::Cache::servers | ||||
| 98 | if (exists $server->{socket}) { | ||||
| 99 | Memcached::libmemcached::memcached_server_add_unix_socket($memcached, $server->{socket}); | ||||
| 100 | } | ||||
| 101 | else { | ||||
| 102 | Memcached::libmemcached::memcached_server_add($memcached, $server->{host}, $server->{port}); # spent 24µs making 1 call to Memcached::libmemcached::memcached_server_add | ||||
| 103 | } | ||||
| 104 | } | ||||
| 105 | return $memcached; | ||||
| 106 | }, | ||||
| 107 | 1 | 4µs | 1 | 1.42ms | ); # spent 1.42ms making 1 call to Moose::has |
| 108 | |||||
| 109 | |||||
| 110 | #------------------------------------------------------------------- | ||||
| 111 | |||||
| 112 | =head2 fix_key ( domain, id ) | ||||
| 113 | |||||
| 114 | Returns a key after it's been processed for completeness. Merges a domain name and a key name with a colon. Keys cannot have any spaces in them, and this fixes that. However, it means that "foo bar" and "foo_bar" are the same thing. | ||||
| 115 | |||||
| 116 | =head3 domain | ||||
| 117 | |||||
| 118 | They domain name to process. | ||||
| 119 | |||||
| 120 | =head3 id | ||||
| 121 | |||||
| 122 | They id name to process. | ||||
| 123 | |||||
| 124 | =cut | ||||
| 125 | |||||
| 126 | sub fix_key { | ||||
| 127 | 164 | 469µs | my ($self, $domain, $id) = @_; | ||
| 128 | my $key = $domain.":".$id; | ||||
| 129 | 1 | 10µs | 42 | 813µs | $key =~ s/\s+/_/g; # spent 461µs making 41 calls to SimpleDB::Class::Cache::CORE:subst, avg 11µs/call
# spent 352µs making 1 call to utf8::SWASHNEW |
| 130 | return $key; | ||||
| 131 | } | ||||
| 132 | |||||
| 133 | #------------------------------------------------------------------- | ||||
| 134 | |||||
| 135 | =head2 delete ( domain, id ) | ||||
| 136 | |||||
| 137 | Delete a key from the cache. | ||||
| 138 | |||||
| 139 | Throws SimpleDB::Class::Exception::InvalidParam, SimpleDB::Class::Exception::Connection and SimpleDB::Class::Exception. | ||||
| 140 | |||||
| 141 | =head3 domain | ||||
| 142 | |||||
| 143 | The domain name to delete from. | ||||
| 144 | |||||
| 145 | =head3 id | ||||
| 146 | |||||
| 147 | The key to delete. | ||||
| 148 | |||||
| 149 | =cut | ||||
| 150 | |||||
| 151 | sub delete { | ||||
| 152 | my $self = shift; | ||||
| 153 | my ($domain, $id, $retry) = validate_pos(@_, { type => SCALAR }, { type => SCALAR }, { optional => 1 } ); | ||||
| 154 | my $key = $self->fix_key($domain, $id); | ||||
| 155 | my $memcached = $self->memcached; | ||||
| 156 | Memcached::libmemcached::memcached_delete($memcached, $key); | ||||
| 157 | if ($memcached->errstr eq 'SYSTEM ERROR Unknown error: 0') { | ||||
| 158 | SimpleDB::Class::Exception::Connection->throw( | ||||
| 159 | error => "Cannot connect to memcached server." | ||||
| 160 | ); | ||||
| 161 | } | ||||
| 162 | elsif ($memcached->errstr eq 'UNKNOWN READ FAILURE' ) { | ||||
| 163 | if ($retry) { | ||||
| 164 | SimpleDB::Class::Exception::Connection->throw( | ||||
| 165 | error => "Cannot connect to memcached server." | ||||
| 166 | ); | ||||
| 167 | } | ||||
| 168 | else { | ||||
| 169 | warn "Memcached went away, reconnecting."; | ||||
| 170 | $self->clear_memcached; | ||||
| 171 | $self->delete($domain, $id, 1); | ||||
| 172 | } | ||||
| 173 | } | ||||
| 174 | elsif ($memcached->errstr eq 'NOT FOUND' ) { | ||||
| 175 | SimpleDB::Class::Exception::ObjectNotFound->throw( | ||||
| 176 | error => "The cache key $key has no value.", | ||||
| 177 | id => $key, | ||||
| 178 | ); | ||||
| 179 | } | ||||
| 180 | elsif ($memcached->errstr eq 'NO SERVERS DEFINED') { | ||||
| 181 | SimpleDB::Class::Exception->throw( | ||||
| 182 | error => "No memcached servers specified." | ||||
| 183 | ); | ||||
| 184 | } | ||||
| 185 | elsif ($memcached->errstr ne 'SUCCESS' # deleted | ||||
| 186 | && $memcached->errstr ne 'PROTOCOL ERROR' # doesn't exist to delete | ||||
| 187 | ) { | ||||
| 188 | SimpleDB::Class::Exception->throw( | ||||
| 189 | error => "Couldn't delete $key from cache because ".$memcached->errstr | ||||
| 190 | ); | ||||
| 191 | } | ||||
| 192 | } | ||||
| 193 | |||||
| 194 | #------------------------------------------------------------------- | ||||
| 195 | |||||
| 196 | =head2 flush ( ) | ||||
| 197 | |||||
| 198 | Empties the caching system. | ||||
| 199 | |||||
| 200 | Throws SimpleDB::Class::Exception::Connection and SimpleDB::Class::Exception. | ||||
| 201 | |||||
| 202 | =cut | ||||
| 203 | |||||
| 204 | # spent 1.93ms (123µs+1.80) within SimpleDB::Class::Cache::flush which was called 3 times, avg 642µs/call:
# once (41µs+1.06ms) by main::RUNTIME at line 19 of 05.Domain_and_Item.t
# once (44µs+414µs) by main::RUNTIME at line 105 of 05.Domain_and_Item.t
# once (38µs+326µs) by main::RUNTIME at line 128 of 05.Domain_and_Item.t | ||||
| 205 | 12 | 1.79ms | my ($self, $retry) = @_; | ||
| 206 | my $memcached = $self->memcached; # spent 143µs making 3 calls to SimpleDB::Class::Cache::memcached, avg 48µs/call | ||||
| 207 | Memcached::libmemcached::memcached_flush($memcached); # spent 1.63ms making 3 calls to Memcached::libmemcached::memcached_flush, avg 542µs/call | ||||
| 208 | if ($memcached->errstr eq 'SYSTEM ERROR Unknown error: 0') { # spent 34µs making 12 calls to Memcached::libmemcached::errstr, avg 3µs/call | ||||
| 209 | SimpleDB::Class::Exception::Connection->throw( | ||||
| 210 | error => "Cannot connect to memcached server." | ||||
| 211 | ); | ||||
| 212 | } | ||||
| 213 | elsif ($memcached->errstr eq 'UNKNOWN READ FAILURE' ) { | ||||
| 214 | SimpleDB::Class::Exception::Connection->throw( | ||||
| 215 | error => "Cannot connect to memcached server." | ||||
| 216 | ) if $retry; | ||||
| 217 | |||||
| 218 | warn "Memcached went away, reconnecting."; | ||||
| 219 | $self->clear_memcached; | ||||
| 220 | return $self->flush(1); | ||||
| 221 | } | ||||
| 222 | elsif ($memcached->errstr eq 'NO SERVERS DEFINED') { | ||||
| 223 | SimpleDB::Class::Exception->throw( | ||||
| 224 | error => "No memcached servers specified." | ||||
| 225 | ); | ||||
| 226 | } | ||||
| 227 | elsif ($memcached->errstr ne 'SUCCESS') { | ||||
| 228 | SimpleDB::Class::Exception->throw( | ||||
| 229 | error => "Couldn't flush cache because ".$memcached->errstr | ||||
| 230 | ); | ||||
| 231 | } | ||||
| 232 | } | ||||
| 233 | |||||
| 234 | #------------------------------------------------------------------- | ||||
| 235 | |||||
| 236 | =head2 get ( domain, id ) | ||||
| 237 | |||||
| 238 | Retrieves a key value from the cache. | ||||
| 239 | |||||
| 240 | Throws SimpleDB::Class::Exception::InvalidObject, SimpleDB::Class::Exception::InvalidParam, SimpleDB::Class::Exception::ObjectNotFound, SimpleDB::Class::Exception::Connection and SimpleDB::Class::Exception. | ||||
| 241 | |||||
| 242 | =head3 domain | ||||
| 243 | |||||
| 244 | The domain name to retrieve from. | ||||
| 245 | |||||
| 246 | =head3 id | ||||
| 247 | |||||
| 248 | The key to retrieve. | ||||
| 249 | |||||
| 250 | =cut | ||||
| 251 | |||||
| 252 | # spent 25.3ms (1.16+24.1) within SimpleDB::Class::Cache::get which was called 24 times, avg 1.05ms/call:
# 18 times (791µs+17.6ms) by SimpleDB::Class::ResultSet::next at line 464 of ../lib/SimpleDB/Class/ResultSet.pm, avg 1.02ms/call
# 6 times (371µs+6.53ms) by SimpleDB::Class::Domain::find at line 155 of ../lib/SimpleDB/Class/Domain.pm, avg 1.15ms/call | ||||
| 253 | 168 | 7.11ms | my $self = shift; | ||
| 254 | 1 | 660µs | 24 | 1.36ms | my ($domain, $id, $retry) = validate_pos(@_, { type => SCALAR }, { type => SCALAR }, { optional => 1 }); # spent 1.36ms making 24 calls to Params::Validate::_validate_pos, avg 57µs/call |
| 255 | my $key = $self->fix_key($domain, $id); # spent 657µs making 24 calls to SimpleDB::Class::Cache::fix_key, avg 27µs/call | ||||
| 256 | my $memcached = $self->memcached; # spent 117µs making 24 calls to SimpleDB::Class::Cache::memcached, avg 5µs/call | ||||
| 257 | my $content = Memcached::libmemcached::memcached_get($memcached, $key); # spent 5.18ms making 24 calls to Memcached::libmemcached::memcached_get, avg 216µs/call | ||||
| 258 | $content = Storable::thaw($content); # spent 12.8ms making 23 calls to Storable::thaw, avg 556µs/call
# spent 467µs making 1 call to AutoLoader::AUTOLOAD | ||||
| 259 | if ($memcached->errstr eq 'SUCCESS') { # spent 2.26ms making 5 calls to Exception::Class::Base::throw, avg 451µs/call
# spent 97µs making 29 calls to Memcached::libmemcached::errstr, avg 3µs/call | ||||
| 260 | if (ref $content) { | ||||
| 261 | return $content; | ||||
| 262 | } | ||||
| 263 | else { | ||||
| 264 | SimpleDB::Class::Exception::InvalidObject->throw( | ||||
| 265 | error => "Couldn't thaw value for $key." | ||||
| 266 | ); | ||||
| 267 | } | ||||
| 268 | } | ||||
| 269 | elsif ($memcached->errstr eq 'NOT FOUND' ) { | ||||
| 270 | SimpleDB::Class::Exception::ObjectNotFound->throw( | ||||
| 271 | error => "The cache key $key has no value.", | ||||
| 272 | id => $key, | ||||
| 273 | ); | ||||
| 274 | } | ||||
| 275 | elsif ($memcached->errstr eq 'NO SERVERS DEFINED') { | ||||
| 276 | SimpleDB::Class::Exception->throw( | ||||
| 277 | error => "No memcached servers specified." | ||||
| 278 | ); | ||||
| 279 | } | ||||
| 280 | elsif ($memcached->errstr eq 'SYSTEM ERROR Unknown error: 0' || $retry) { | ||||
| 281 | SimpleDB::Class::Exception::Connection->throw( | ||||
| 282 | error => "Cannot connect to memcached server." | ||||
| 283 | ); | ||||
| 284 | } | ||||
| 285 | elsif ($memcached->errstr eq 'UNKNOWN READ FAILURE' ) { | ||||
| 286 | warn "Memcached went away, reconnecting."; | ||||
| 287 | $self->clear_memcached; | ||||
| 288 | return $self->get($domain, $id, 1); | ||||
| 289 | } | ||||
| 290 | SimpleDB::Class::Exception->throw( | ||||
| 291 | error => "Couldn't get $key from cache because ".$memcached->errstr | ||||
| 292 | ); | ||||
| 293 | } | ||||
| 294 | |||||
| 295 | #------------------------------------------------------------------- | ||||
| 296 | |||||
| 297 | =head2 mget ( keys ) | ||||
| 298 | |||||
| 299 | Retrieves multiple values from cache at once, which is much faster than retrieving one at a time. Returns an array reference containing the values in the order they were requested. | ||||
| 300 | |||||
| 301 | Throws SimpleDB::Class::Exception::InvalidParam, SimpleDB::Class::Exception::Connection and SimpleDB::Class::Exception. | ||||
| 302 | |||||
| 303 | =head3 keys | ||||
| 304 | |||||
| 305 | An array reference of domain names and ids to retrieve. | ||||
| 306 | |||||
| 307 | =cut | ||||
| 308 | |||||
| 309 | sub mget { | ||||
| 310 | my $self = shift; | ||||
| 311 | my ($names) = validate_pos(@_, { type => ARRAYREF }); | ||||
| 312 | my $retry = shift; | ||||
| 313 | my @keys = map { $self->fix_key(@{$_}) } @{ $names }; | ||||
| 314 | my %result; | ||||
| 315 | my $memcached = $self->memcached; | ||||
| 316 | $memcached->mget_into_hashref(\@keys, \%result); | ||||
| 317 | if ($memcached->errstr eq 'SYSTEM ERROR Unknown error: 0') { | ||||
| 318 | SimpleDB::Class::Exception::Connection->throw( | ||||
| 319 | error => "Cannot connect to memcached server." | ||||
| 320 | ); | ||||
| 321 | } | ||||
| 322 | elsif ($memcached->errstr eq 'UNKNOWN READ FAILURE' ) { | ||||
| 323 | SimpleDB::Class::Exception::Connection->throw( | ||||
| 324 | error => "Cannot connect to memcached server." | ||||
| 325 | ) if $retry; | ||||
| 326 | warn "Memcached went away, reconnecting."; | ||||
| 327 | $self->clear_memcached; | ||||
| 328 | return $self->get($names, 1); | ||||
| 329 | } | ||||
| 330 | elsif ($memcached->errstr eq 'NO SERVERS DEFINED') { | ||||
| 331 | SimpleDB::Class::Exception->throw( | ||||
| 332 | error => "No memcached servers specified." | ||||
| 333 | ); | ||||
| 334 | } | ||||
| 335 | # no other useful status messages are returned | ||||
| 336 | my @values; | ||||
| 337 | foreach my $key (@keys) { | ||||
| 338 | my $content = Storable::thaw($result{$key}); | ||||
| 339 | unless (ref $content) { | ||||
| 340 | SimpleDB::Class::Exception::InvalidObject->throw( | ||||
| 341 | id => $key, | ||||
| 342 | error => "Can't thaw object returned from memcache for $key.", | ||||
| 343 | ); | ||||
| 344 | next; | ||||
| 345 | } | ||||
| 346 | push @values, $content; | ||||
| 347 | } | ||||
| 348 | return \@values; | ||||
| 349 | } | ||||
| 350 | |||||
| 351 | #------------------------------------------------------------------- | ||||
| 352 | |||||
| 353 | =head2 set ( domain, id, value [, ttl] ) | ||||
| 354 | |||||
| 355 | Sets a key value to the cache. | ||||
| 356 | |||||
| 357 | Throws SimpleDB::Class::Exception::InvalidParam, SimpleDB::Class::Exception::Connection, and SimpleDB::Class::Exception. | ||||
| 358 | |||||
| 359 | =head3 domain | ||||
| 360 | |||||
| 361 | The name of the domain to set the info into. | ||||
| 362 | |||||
| 363 | =head3 id | ||||
| 364 | |||||
| 365 | The name of the key to set. | ||||
| 366 | |||||
| 367 | =head3 value | ||||
| 368 | |||||
| 369 | A hash reference to store. | ||||
| 370 | |||||
| 371 | =head3 ttl | ||||
| 372 | |||||
| 373 | A time in seconds for the cache to exist. Default is 3600 seconds (1 hour). | ||||
| 374 | |||||
| 375 | =cut | ||||
| 376 | |||||
| 377 | # spent 8.44ms (809µs+7.63) within SimpleDB::Class::Cache::set which was called 17 times, avg 496µs/call:
# 12 times (608µs+6.05ms) by SimpleDB::Class::Item::put at line 497 of ../lib/SimpleDB/Class/Item.pm, avg 555µs/call
# 3 times (119µs+891µs) by SimpleDB::Class::ResultSet::next at line 470 of ../lib/SimpleDB/Class/ResultSet.pm, avg 336µs/call
# 2 times (83µs+687µs) by SimpleDB::Class::Domain::find at line 168 of ../lib/SimpleDB/Class/Domain.pm, avg 385µs/call | ||||
| 378 | 136 | 5.34ms | my $self = shift; | ||
| 379 | 1 | 418µs | 17 | 714µs | my ($domain, $id, $value, $ttl, $retry) = validate_pos(@_, { type => SCALAR }, { type => SCALAR }, { type => HASHREF }, { type => SCALAR | UNDEF, optional => 1 }, { optional => 1 }); # spent 714µs making 17 calls to Params::Validate::_validate_pos, avg 42µs/call |
| 380 | my $key = $self->fix_key($domain, $id); # spent 175µs making 17 calls to SimpleDB::Class::Cache::fix_key, avg 10µs/call | ||||
| 381 | $ttl ||= 60; | ||||
| 382 | my $frozenValue = Storable::nfreeze($value); # spent 1.72ms making 16 calls to Storable::nfreeze, avg 108µs/call
# spent 337µs making 1 call to AutoLoader::AUTOLOAD | ||||
| 383 | my $memcached = $self->memcached; # spent 90µs making 17 calls to SimpleDB::Class::Cache::memcached, avg 5µs/call | ||||
| 384 | Memcached::libmemcached::memcached_set($memcached, $key, $frozenValue, $ttl); # spent 4.16ms making 17 calls to Memcached::libmemcached::memcached_set, avg 245µs/call | ||||
| 385 | if ($memcached->errstr eq 'SUCCESS') { # spent 76µs making 17 calls to Memcached::libmemcached::errstr, avg 4µs/call | ||||
| 386 | return $value; | ||||
| 387 | } | ||||
| 388 | elsif ($memcached->errstr eq 'SYSTEM ERROR Unknown error: 0' || $retry) { | ||||
| 389 | SimpleDB::Class::Exception::Connection->throw( | ||||
| 390 | error => "Cannot connect to memcached server." | ||||
| 391 | ); | ||||
| 392 | } | ||||
| 393 | elsif ($memcached->errstr eq 'UNKNOWN READ FAILURE' ) { | ||||
| 394 | warn "Memcached went away, reconnecting."; | ||||
| 395 | $self->clear_memcached; | ||||
| 396 | return $self->set($domain, $id, $value, $ttl, 1); | ||||
| 397 | } | ||||
| 398 | elsif ($memcached->errstr eq 'NO SERVERS DEFINED') { | ||||
| 399 | SimpleDB::Class::Exception->throw( | ||||
| 400 | error => "No memcached servers specified." | ||||
| 401 | ); | ||||
| 402 | } | ||||
| 403 | SimpleDB::Class::Exception->throw( | ||||
| 404 | error => "Couldn't set $key to cache because ".$memcached->errstr | ||||
| 405 | ); | ||||
| 406 | return $value; | ||||
| 407 | } | ||||
| 408 | |||||
| 409 | |||||
| 410 | =head1 EXCEPTIONS | ||||
| 411 | |||||
| 412 | This class throws a lot of inconvenient, but useful exceptions. If you just want to avoid them you could: | ||||
| 413 | |||||
| 414 | my $value = eval { $cache->get($key) }; | ||||
| 415 | if (SimpleDB::Class::Exception::ObjectNotFound->caught) { | ||||
| 416 | $value = $db->fetchValueFromTheDatabase; | ||||
| 417 | } | ||||
| 418 | |||||
| 419 | The exceptions that can be thrown are: | ||||
| 420 | |||||
| 421 | =head2 SimpleDB::Class::Exception | ||||
| 422 | |||||
| 423 | When an uknown exception happens, or there are no configured memcahed servers in the cacheServers directive in your config file. | ||||
| 424 | |||||
| 425 | =head2 SimpleDB::Class::Exception::Connection | ||||
| 426 | |||||
| 427 | When it can't connect to the memcached servers that are configured. | ||||
| 428 | |||||
| 429 | =head2 SimpleDB::Class::Exception::InvalidParam | ||||
| 430 | |||||
| 431 | When you pass in the wrong arguments. | ||||
| 432 | |||||
| 433 | =head2 SimpleDB::Class::Exception::ObjectNotFound | ||||
| 434 | |||||
| 435 | When you request a cache key that doesn't exist on any configured memcached server. | ||||
| 436 | |||||
| 437 | =head2 SimpleDB::Class::Exception::InvalidObject | ||||
| 438 | |||||
| 439 | When an object can't be thawed from cache due to corruption of some sort. | ||||
| 440 | |||||
| 441 | =head1 LEGAL | ||||
| 442 | |||||
| 443 | SimpleDB::Class is Copyright 2009-2010 Plain Black Corporation (L<http://www.plainblack.com/>) and is licensed under the same terms as Perl itself. | ||||
| 444 | |||||
| 445 | =cut | ||||
| 446 | |||||
| 447 | |||||
| 448 | 3 | 45µs | 2 | 257µs | # spent 134µs (11+123) within SimpleDB::Class::Cache::BEGIN@448 which was called
# once (11µs+123µs) by SimpleDB::Class::BEGIN@139 at line 448 # spent 134µs making 1 call to SimpleDB::Class::Cache::BEGIN@448
# spent 123µs making 1 call to Moose::Exporter::__ANON__[Moose/Exporter.pm:478] |
| 449 | 1 | 48µs | 2 | 15.3ms | __PACKAGE__->meta->make_immutable; # spent 15.3ms making 1 call to Class::MOP::Class::make_immutable
# spent 14µs making 1 call to SimpleDB::Class::Cache::meta |
| 450 | |||||
# spent 461µs (110+352) within SimpleDB::Class::Cache::CORE:subst which was called 41 times, avg 11µs/call:
# 41 times (110µs+352µs) by SimpleDB::Class::Cache::fix_key at line 129 of ../lib/SimpleDB/Class/Cache.pm, avg 11µs/call |