Profile of /data/SimpleDB-Class/author.t/../lib/SimpleDB/Class/Cache.pm

← Index
NYTProf Performance Profile «block view•line view•sub view»
For 05.Domain_and_Item.t
Run on Tue May 4 17:21:41 2010
Reported on Tue May 4 17:22:30 2010

File | /data/SimpleDB-Class/author.t/../lib/SimpleDB/Class/Cache.pm
Statements Executed | 511
Statement Execution Time | 17.6ms

Subroutines — ordered by exclusive time
Calls | P | F | Exclusive Time | Inclusive Time | Subroutine
--- | --- | --- | --- | --- | ---
24 | 2 | 2 | 1.16ms | 25.3ms | SimpleDB::Class::Cache::::getSimpleDB::Class::Cache::get
17 | 3 | 3 | 809µs | 8.44ms | SimpleDB::Class::Cache::::setSimpleDB::Class::Cache::set
1 | 1 | 1 | 538µs | 9.28ms | SimpleDB::Class::Cache::::BEGIN@32SimpleDB::Class::Cache::BEGIN@32
1 | 1 | 1 | 440µs | 2.45ms | SimpleDB::Class::Cache::::BEGIN@31SimpleDB::Class::Cache::BEGIN@31
41 | 2 | 1 | 371µs | 832µs | SimpleDB::Class::Cache::::fix_keySimpleDB::Class::Cache::fix_key
1 | 1 | 1 | 283µs | 1.35ms | SimpleDB::Class::Cache::::BEGIN@33SimpleDB::Class::Cache::BEGIN@33
1 | 1 | 1 | 187µs | 7.65ms | SimpleDB::Class::Cache::::BEGIN@30SimpleDB::Class::Cache::BEGIN@30
3 | 3 | 1 | 123µs | 1.93ms | SimpleDB::Class::Cache::::flushSimpleDB::Class::Cache::flush
41 | 1 | 2 | 110µs | 461µs | SimpleDB::Class::Cache::::CORE:substSimpleDB::Class::Cache::CORE:subst (opcode)
1 | 1 | 1 | 38µs | 2.22ms | SimpleDB::Class::Cache::::BEGIN@29SimpleDB::Class::Cache::BEGIN@29
1 | 1 | 1 | 26µs | 112µs | SimpleDB::Class::Cache::::__ANON__[../lib/SimpleDB/Class/Cache.pm:106]SimpleDB::Class::Cache::__ANON__[../lib/SimpleDB/Class/Cache.pm:106]
1 | 1 | 1 | 11µs | 134µs | SimpleDB::Class::Cache::::BEGIN@448SimpleDB::Class::Cache::BEGIN@448
0 | 0 | 0 | 0s | 0s | SimpleDB::Class::Cache::::__ANON__[../lib/SimpleDB/Class/Cache.pm:38]SimpleDB::Class::Cache::__ANON__[../lib/SimpleDB/Class/Cache.pm:38]
0 | 0 | 0 | 0s | 0s | SimpleDB::Class::Cache::::deleteSimpleDB::Class::Cache::delete
0 | 0 | 0 | 0s | 0s | SimpleDB::Class::Cache::::mgetSimpleDB::Class::Cache::mget

Call graph for these subroutines as a Graphviz dot language file.

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 use Moose; # 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 use SimpleDB::Class::Exception; # 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 use Memcached::libmemcached; # 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 use Storable (); # 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 use Params::Validate qw(:all); # 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 default => sub {
95 | 4 | 74µ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 | 2 | 32µs |  |  | 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 |  |  |  |  | # spent 832µs (371+461) within SimpleDB::Class::Cache::fix_key which was called 41 times, avg 20µs/call: # 24 times (224µs+433µs) by SimpleDB::Class::Cache::get at line 255, avg 27µs/call # 17 times (147µs+28µs) by SimpleDB::Class::Cache::set at line 380, avg 10µs/call 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 sub flush {
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 sub get {
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 sub set {
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 no Moose; # 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 sub SimpleDB::Class::Cache::CORE:subst; # xsub