← Index
NYTProf Performance Profile   « block view • line view • sub view »
For mongo_pain.pl
  Run on Fri Mar 25 17:00:29 2011
Reported on Fri Mar 25 17:07:07 2011

Filename/usr/local/lib/perl/5.10.1/MongoDB/Connection.pm
StatementsExecuted 66 statements in 3.70ms
Subroutines
Calls P F Exclusive
Time
Inclusive
Time
Subroutine
10000001112.6s12.6sMongoDB::Connection::::sendMongoDB::Connection::send (xsub)
1111.67ms42.5msMongoDB::Connection::::BEGIN@23MongoDB::Connection::BEGIN@23
111991µs1.33msMongoDB::Connection::::BEGIN@27MongoDB::Connection::BEGIN@27
111489µs493µsMongoDB::Connection::::connectMongoDB::Connection::connect (xsub)
111261µs166msMongoDB::Connection::::BUILDMongoDB::Connection::BUILD
11149µs53µsMongoDB::Connection::::_init_connMongoDB::Connection::_init_conn (xsub)
11129µs29µsMongoDB::Connection::::DESTROYMongoDB::Connection::DESTROY (xsub)
11117µs4.23msMongoDB::Connection::::AUTOLOADMongoDB::Connection::AUTOLOAD
11116µs16µsMongoDB::Connection::::BEGIN@22MongoDB::Connection::BEGIN@22
11110µs125µsMongoDB::Connection::::BEGIN@737MongoDB::Connection::BEGIN@737
11110µs53µsMongoDB::Connection::::BEGIN@29MongoDB::Connection::BEGIN@29
11110µs351µsMongoDB::Connection::::BEGIN@25MongoDB::Connection::BEGIN@25
1119µs235µsMongoDB::Connection::::BEGIN@26MongoDB::Connection::BEGIN@26
1119µs4.21msMongoDB::Connection::::get_databaseMongoDB::Connection::get_database
1117µs7µsMongoDB::Connection::::BEGIN@28MongoDB::Connection::BEGIN@28
1115µs5µsMongoDB::Connection::::CORE:substMongoDB::Connection::CORE:subst (opcode)
2114µs4µsMongoDB::Connection::::hostMongoDB::Connection::host (xsub)
1113µs3µsMongoDB::Connection::::usernameMongoDB::Connection::username (xsub)
1112µs2µsMongoDB::Connection::::find_masterMongoDB::Connection::find_master (xsub)
1112µs2µsMongoDB::Connection::::timeoutMongoDB::Connection::timeout (xsub)
1112µs2µsMongoDB::Connection::::__ANON__[:309]MongoDB::Connection::__ANON__[:309]
1112µs2µsMongoDB::Connection::::auto_reconnectMongoDB::Connection::auto_reconnect (xsub)
1112µs2µsMongoDB::Connection::::auto_connectMongoDB::Connection::auto_connect (xsub)
1111µs1µsMongoDB::Connection::::__ANON__[:357]MongoDB::Connection::__ANON__[:357]
1111µs1µsMongoDB::Connection::::portMongoDB::Connection::port (xsub)
1111µs1µsMongoDB::Connection::::passwordMongoDB::Connection::password (xsub)
111700ns700nsMongoDB::Connection::::CORE:matchMongoDB::Connection::CORE:match (opcode)
0000s0sMongoDB::Connection::::_get_a_specific_connectionMongoDB::Connection::_get_a_specific_connection
0000s0sMongoDB::Connection::::_get_any_connectionMongoDB::Connection::_get_any_connection
0000s0sMongoDB::Connection::::_old_stupid_paired_connMongoDB::Connection::_old_stupid_paired_conn
0000s0sMongoDB::Connection::::authenticateMongoDB::Connection::authenticate
0000s0sMongoDB::Connection::::database_namesMongoDB::Connection::database_names
0000s0sMongoDB::Connection::::get_masterMongoDB::Connection::get_master
Call graph for these subroutines as a Graphviz dot language file.
Line State
ments
Time
on line
Calls Time
in subs
Code
1#
2# Copyright 2009 10gen, Inc.
3#
4# Licensed under the Apache License, Version 2.0 (the "License");
5# you may not use this file except in compliance with the License.
6# You may obtain a copy of the License at
7#
8# http://www.apache.org/licenses/LICENSE-2.0
9#
10# Unless required by applicable law or agreed to in writing, software
11# distributed under the License is distributed on an "AS IS" BASIS,
12# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13# See the License for the specific language governing permissions and
14# limitations under the License.
15#
16
17package MongoDB::Connection;
181900nsour $VERSION = '0.42';
19
20# ABSTRACT: A connection to a Mongo server
21
22338µs116µs
# spent 16µs within MongoDB::Connection::BEGIN@22 which was called: # once (16µs+0s) by MongoDB::BEGIN@26 at line 22
use MongoDB;
# spent 16µs making 1 call to MongoDB::Connection::BEGIN@22
233175µs142.5ms
# spent 42.5ms (1.67+40.8) within MongoDB::Connection::BEGIN@23 which was called: # once (1.67ms+40.8ms) by MongoDB::BEGIN@26 at line 23
use MongoDB::Cursor;
# spent 42.5ms making 1 call to MongoDB::Connection::BEGIN@23
24
25339µs2693µs
# spent 351µs (10+342) within MongoDB::Connection::BEGIN@25 which was called: # once (10µs+342µs) by MongoDB::BEGIN@26 at line 25
use Any::Moose;
# spent 351µs making 1 call to MongoDB::Connection::BEGIN@25 # spent 342µs making 1 call to Any::Moose::import
26341µs2460µs
# spent 235µs (9+225) within MongoDB::Connection::BEGIN@26 which was called: # once (9µs+225µs) by MongoDB::BEGIN@26 at line 26
use Any::Moose 'Util::TypeConstraints';
# spent 235µs making 1 call to MongoDB::Connection::BEGIN@26 # spent 225µs making 1 call to Any::Moose::import
273151µs21.36ms
# spent 1.33ms (991µs+343µs) within MongoDB::Connection::BEGIN@27 which was called: # once (991µs+343µs) by MongoDB::BEGIN@26 at line 27
use Digest::MD5;
# spent 1.33ms making 1 call to MongoDB::Connection::BEGIN@27 # spent 26µs making 1 call to Exporter::import
28332µs17µs
# spent 7µs within MongoDB::Connection::BEGIN@28 which was called: # once (7µs+0s) by MongoDB::BEGIN@26 at line 28
use Tie::IxHash;
# spent 7µs making 1 call to MongoDB::Connection::BEGIN@28
2932.18ms296µs
# spent 53µs (10+43) within MongoDB::Connection::BEGIN@29 which was called: # once (10µs+43µs) by MongoDB::BEGIN@26 at line 29
use boolean;
# spent 53µs making 1 call to MongoDB::Connection::BEGIN@29 # spent 43µs making 1 call to Exporter::import
30
31=head1 NAME
32
- -
9512µs1215µshas host => (
# spent 215µs making 1 call to Mouse::has
96 is => 'ro',
97 isa => 'Str',
98 required => 1,
99 default => 'mongodb://localhost:27017',
100);
101
102=head2 w
103
- -
14112µs1195µshas w => (
# spent 195µs making 1 call to Mouse::has
142 is => 'rw',
143 isa => 'Int',
144 default => 1,
145);
146
147=head2 wtimeout
148
- -
15812µs1194µshas wtimeout => (
# spent 194µs making 1 call to Mouse::has
159 is => 'rw',
160 isa => 'Int',
161 default => 1000,
162);
163
16412µs1194µshas port => (
# spent 194µs making 1 call to Mouse::has
165 is => 'ro',
166 isa => 'Int',
167 required => 1,
168 default => 27017,
169);
170
17112µs1192µshas left_host => (
# spent 192µs making 1 call to Mouse::has
172 is => 'ro',
173 isa => 'Str',
174);
175
17612µs1192µshas left_port => (
# spent 192µs making 1 call to Mouse::has
177 is => 'ro',
178 isa => 'Int',
179 default => 27017,
180);
181
18212µs1191µshas right_host => (
# spent 191µs making 1 call to Mouse::has
183 is => 'ro',
184 isa => 'Str',
185);
186
18712µs1200µshas right_port => (
# spent 200µs making 1 call to Mouse::has
188 is => 'ro',
189 isa => 'Int',
190 default => 27017,
191);
192
193=head2 auto_reconnect
194
- -
20012µs1205µshas auto_reconnect => (
# spent 205µs making 1 call to Mouse::has
201 is => 'ro',
202 isa => 'Bool',
203 required => 1,
204 default => 1,
205);
206
207=head2 auto_connect
208
- -
21412µs1193µshas auto_connect => (
# spent 193µs making 1 call to Mouse::has
215 is => 'ro',
216 isa => 'Bool',
217 required => 1,
218 default => 1,
219);
220
221=head2 timeout
222
- -
22712µs1194µshas timeout => (
# spent 194µs making 1 call to Mouse::has
228 is => 'ro',
229 isa => 'Int',
230 required => 1,
231 default => 20000,
232);
233
234=head2 username
235
- -
24112µs1193µshas username => (
# spent 193µs making 1 call to Mouse::has
242 is => 'rw',
243 isa => 'Str',
244 required => 0,
245);
246
247=head2 password
248
- -
25412µs1195µshas password => (
# spent 195µs making 1 call to Mouse::has
255 is => 'rw',
256 isa => 'Str',
257 required => 0,
258);
259
260=head2 db_name
261
- -
26912µs1200µshas db_name => (
# spent 200µs making 1 call to Mouse::has
270 is => 'rw',
271 isa => 'Str',
272 required => 1,
273 default => 'admin',
274);
275
276=head2 query_timeout
277
- -
305has query_timeout => (
306 is => 'rw',
307 isa => 'Int',
308 required => 1,
30915µs
# spent 2µs within MongoDB::Connection::__ANON__[/usr/local/lib/perl/5.10.1/MongoDB/Connection.pm:309] which was called: # once (2µs+0s) by Mouse::Object::new at line 13 of mongo_pain.pl
default => sub { return $MongoDB::Cursor::timeout; },
31015µs1195µs);
# spent 195µs making 1 call to Mouse::has
311
312=head2 find_master
313
- -
34512µs1204µshas find_master => (
# spent 204µs making 1 call to Mouse::has
346 is => 'ro',
347 isa => 'Bool',
348 required => 1,
349 default => 0,
350);
351
352# hash of servers in a set
353# call connected() to determine if a connection is enabled
354has _servers => (
355 is => 'rw',
356 isa => 'HashRef',
35714µs
# spent 1µs within MongoDB::Connection::__ANON__[/usr/local/lib/perl/5.10.1/MongoDB/Connection.pm:357] which was called: # once (1µs+0s) by Mouse::Object::new at line 13 of mongo_pain.pl
default => sub { {} },
35814µs1199µs);
# spent 199µs making 1 call to Mouse::has
359
360# actual connection to a server in the set
36112µs1161µshas _master => (
# spent 161µs making 1 call to Mouse::has
362 is => 'rw',
363# isa => 'MongoDB::Connection',
364 required => 0,
365);
366
36712µs1190µshas ts => (
# spent 190µs making 1 call to Mouse::has
368 is => 'rw',
369 isa => 'Int',
370 default => 0
371);
372
373=head2 port [deprecated]
374
- -
406
# spent 4.23ms (17µs+4.21) within MongoDB::Connection::AUTOLOAD which was called: # once (17µs+4.21ms) by main::RUNTIME at line 15 of mongo_pain.pl
sub AUTOLOAD {
407521µs my $self = shift @_;
408 our $AUTOLOAD;
409
410 my $db = $AUTOLOAD;
41115µs $db =~ s/.*:://;
# spent 5µs making 1 call to MongoDB::Connection::CORE:subst
412
41314.21ms return $self->get_database($db);
# spent 4.21ms making 1 call to MongoDB::Connection::get_database
414}
415
416
# spent 166ms (261µs+166) within MongoDB::Connection::BUILD which was called: # once (261µs+166ms) by Mouse::Object::new at line 13 of mongo_pain.pl
sub BUILD {
4176213µs my ($self, $opts) = @_;
418 eval "use ${_}" # no Any::Moose::load_class becase the namespaces already have symbols from the xs bootstrap
419 for qw/MongoDB::Database MongoDB::Cursor MongoDB::OID MongoDB::Timestamp/;
# spent 136µs executing statements in string eval
# includes 944µs spent executing 1 call to 1 sub defined therein. # spent 129µs executing statements in string eval
# includes 538µs spent executing 1 call to 1 sub defined therein. # spent 126µs executing statements in string eval
# includes 195µs spent executing 1 call to 1 sub defined therein. # spent 18µs executing statements in string eval
# includes 13µs spent executing 1 call to 1 sub defined therein.
420
421 my @pairs;
422
423 # deprecated syntax
42446µs if (!($self->host =~ /^mongodb:\/\//)) {
# spent 4µs making 2 calls to MongoDB::Connection::host, avg 2µs/call # spent 1µs making 1 call to MongoDB::Connection::port # spent 700ns making 1 call to MongoDB::Connection::CORE:match
425 push @pairs, $self->host.":".$self->port;
426 }
427 # even more deprecated syntax
428 elsif ($self->left_host && $self->right_host) {
429 push @pairs, $self->left_host.":".$self->left_port;
430 push @pairs, $self->right_host.":".$self->right_port;
431 }
432 # supported syntax
433 else {
434 my $str = substr $self->host, 10;
435 @pairs = split ",", $str;
436 }
437
438 # a simple single server is special-cased (so we don't recurse forever)
4395579µs12µs if (@pairs == 1 && !$self->find_master) {
# spent 2µs making 1 call to MongoDB::Connection::find_master
440 my @hp = split ":", $pairs[0];
441
442 if (!exists $hp[1]) {
443 $hp[1] = 27017;
444 }
445
446356µs $self->_init_conn($hp[0], $hp[1]);
# spent 53µs making 1 call to MongoDB::Connection::_init_conn # spent 2µs making 1 call to MongoDB::Connection::timeout # spent 2µs making 1 call to MongoDB::Connection::auto_reconnect
4474499µs if ($self->auto_connect) {
# spent 493µs making 1 call to MongoDB::Connection::connect # spent 3µs making 1 call to MongoDB::Connection::username # spent 2µs making 1 call to MongoDB::Connection::auto_connect # spent 1µs making 1 call to MongoDB::Connection::password
448 $self->connect;
449 }
450 return;
451 }
452
453 # multiple servers
454 my $connected = 0;
455 $opts->{find_master} = 0;
456 $opts->{auto_connect} = 0;
457 foreach (@pairs) {
458 $opts->{host} = "mongodb://$_";
459
460 $self->_servers->{$_} = MongoDB::Connection->new($opts);
461
462 next unless $self->auto_connect;
463
464 # it's okay if we can't connect, so long as someone can
465 eval {
466 $self->_servers->{$_}->connect;
467 };
468
469 # at least one connection worked
470 if (!$@) {
471 $connected = 1;
472 }
473 }
474
475 my $master;
476
477 if ($self->auto_connect) {
478
479 # if we still aren't connected to anyone, give up
480 if (!$connected) {
481 die "couldn't connect to any servers listed: ".join(",", @pairs);
482 }
483
484 $master = $self->get_master;
485 if ($master == -1) {
486 die "couldn't find master";
487 }
488 }
489 else {
490 # no auto-connect so just pick one. if auto-reconnect is set then it will connect as needed
491 ($master) = values %{$self->_servers};
492 }
493
494 # create a struct that just points to the master's connection
495 $self->_init_conn_holder($master);
496}
497
498=head1 METHODS
499
- -
515sub database_names {
516 my ($self) = @_;
517 my $ret = $self->get_database('admin')->run_command({ listDatabases => 1 });
518 return map { $_->{name} } @{ $ret->{databases} };
519}
520
521=head2 get_database($name)
522
- -
529
# spent 4.21ms (9µs+4.20) within MongoDB::Connection::get_database which was called: # once (9µs+4.20ms) by MongoDB::Connection::AUTOLOAD at line 413
sub get_database {
530211µs my ($self, $database_name) = @_;
531166µs88.33ms return MongoDB::Database->new(
# spent 4.20ms making 1 call to Mouse::Object::new # spent 4.07ms making 1 call to MongoDB::Database::BUILD # spent 61µs making 1 call to Mouse::Meta::Class::_calculate_all_attributes # spent 3µs making 2 calls to Mouse::Meta::TypeConstraint::_compiled_type_constraint, avg 1µs/call # spent 2µs making 1 call to Mouse::Meta::Class::strict_constructor # spent 1µs making 1 call to Mouse::Meta::Class::is_immutable # spent 1µs making 1 call to Mouse::Meta::Class::is_anon_class
532 _connection => $self,
533 name => $database_name,
534 );
535}
536
537sub _get_a_specific_connection {
538 my ($self, $host) = @_;
539
540 if ($self->_servers->{$host}->connected) {
541 return $self->_servers->{$host};
542 }
543
544 eval {
545 $self->_servers->{$host}->connect;
546 };
547
548 if (!$@) {
549 return $self->_servers->{$host};
550 }
551 return 0;
552}
553
554sub _get_any_connection {
555 my ($self) = @_;
556
557 while ((my $key, my $value) = each(%{$self->_servers})) {
558 my $conn = $self->_get_a_specific_connection($key);
559 if ($conn) {
560 return $conn;
561 }
562 }
563
564 return 0;
565}
566
- -
569=head2 get_master
570
- -
580sub get_master {
581 my ($self) = @_;
582
583 # return if the connection is paired the stupid old way
584 if (defined $self->left_host && defined $self->right_host) {
585 return $self->_old_stupid_paired_conn;
586 }
587
588 my $conn = $self->_get_any_connection();
589 # if we couldn't connect to anything, just return
590 if (!$conn) {
591 return -1;
592 }
593
594 # a single server or list of servers
595 if (!$self->find_master) {
596 $self->_master($conn);
597 return $self->_master;
598 }
599 # auto-detect master
600 else {
601 my $master = $conn->get_database('admin')->run_command({"ismaster" => 1});
602
603 # check for errors
604 if (ref($master) eq 'SCALAR') {
605 return -1;
606 }
607
608 # if this is a replica set & we haven't renewed the host list in 1 sec
609 if ($master->{'hosts'} && time() > $self->ts) {
610 # update (or set) rs list
611 for (@{$master->{'hosts'}}) {
612 if (!$self->_servers->{$_}) {
613 $self->_servers->{$_} = MongoDB::Connection->new("host" => "mongodb://$_", auto_connect => 0);
614 }
615 }
616 $self->ts(time());
617 }
618
619 # if this is the master, whether or not it's a replica set, return it
620 if ($master->{'ismaster'}) {
621 $self->_master($conn);
622 return $self->_master;
623 }
624 elsif ($self->find_master && exists $master->{'primary'}) {
625 my $primary = $self->_get_a_specific_connection($master->{'primary'});
626 if (!$primary) {
627 return -1;
628 }
629
630 # double-check that this is master
631 my $result = $primary->get_database("admin")->run_command({"ismaster" => 1});
632 if ($result->{'ismaster'}) {
633 $self->_master($primary);
634 return $self->_master;
635 }
636 }
637 }
638
639 return -1;
640}
641
642sub _old_stupid_paired_conn {
643 my $self = shift;
644
645 my ($left, $right, $master);
646
647 # check the left host
648 eval {
649 $left = MongoDB::Connection->new("host" => $self->left_host, "port" => $self->left_port, timeout => $self->timeout);
650 };
651 if (!($@ =~ m/couldn't connect to server/)) {
652 $master = $left->find_one('admin.$cmd', {ismaster => 1});
653 if ($master->{'ismaster'}) {
654 return 0;
655 }
656 }
657
658 # check the right_host
659 eval {
660 $right = MongoDB::Connection->new("host" => $self->right_host, "port" => $self->right_port, timeout => $self->timeout);
661 };
662 if (!($@ =~ m/couldn't connect to server/)) {
663 $master = $right->find_one('admin.$cmd', {ismaster => 1});
664 if ($master->{'ismaster'}) {
665 return 1;
666 }
667 }
668
669 # something went wrong
670 return -1;
671}
672
673=head2 authenticate ($dbname, $username, $password, $is_digest?)
674
- -
687sub authenticate {
688 my ($self, $dbname, $username, $password, $is_digest) = @_;
689 my $hash = $password;
690
691 # create a hash if the password isn't yet encrypted
692 if (!$is_digest) {
693 $hash = Digest::MD5::md5_hex("${username}:mongo:${password}");
694 }
695
696 # get the nonce
697 my $db = $self->get_database($dbname);
698 my $result = $db->run_command({getnonce => 1});
699 if (!$result->{'ok'}) {
700 return $result;
701 }
702
703 my $nonce = $result->{'nonce'};
704 my $digest = Digest::MD5::md5_hex($nonce.$username.$hash);
705
706 # run the login command
707 my $login = tie(my %hash, 'Tie::IxHash');
708 %hash = (authenticate => 1,
709 user => $username,
710 nonce => $nonce,
711 key => $digest);
712 $result = $db->run_command($login);
713
714 return $result;
715}
716
717=head2 send($str)
718
- -
737362µs2239µs
# spent 125µs (10+114) within MongoDB::Connection::BEGIN@737 which was called: # once (10µs+114µs) by MongoDB::BEGIN@26 at line 737
no Any::Moose;
# spent 125µs making 1 call to MongoDB::Connection::BEGIN@737 # spent 114µs making 1 call to Any::Moose::unimport
73816µs264µs__PACKAGE__->meta->make_immutable (inline_destructor => 0);
# spent 55µs making 1 call to Mouse::Meta::Class::make_immutable # spent 9µs making 1 call to MongoDB::Connection::meta
739
740136µs1;
741
742=head1 AUTHOR
 
# spent 700ns within MongoDB::Connection::CORE:match which was called: # once (700ns+0s) by MongoDB::Connection::BUILD at line 424
sub MongoDB::Connection::CORE:match; # opcode
# spent 5µs within MongoDB::Connection::CORE:subst which was called: # once (5µs+0s) by MongoDB::Connection::AUTOLOAD at line 411
sub MongoDB::Connection::CORE:subst; # opcode
# spent 29µs within MongoDB::Connection::DESTROY which was called: # once (29µs+0s) by main::NULL at line 0 of mongo_pain.pl
sub MongoDB::Connection::DESTROY; # xsub
# spent 53µs (49+3) within MongoDB::Connection::_init_conn which was called: # once (49µs+3µs) by MongoDB::Connection::BUILD at line 446
sub MongoDB::Connection::_init_conn; # xsub
# spent 2µs within MongoDB::Connection::auto_connect which was called: # once (2µs+0s) by MongoDB::Connection::BUILD at line 447
sub MongoDB::Connection::auto_connect; # xsub
# spent 2µs within MongoDB::Connection::auto_reconnect which was called: # once (2µs+0s) by MongoDB::Connection::_init_conn at line 446
sub MongoDB::Connection::auto_reconnect; # xsub
# spent 493µs (489+4) within MongoDB::Connection::connect which was called: # once (489µs+4µs) by MongoDB::Connection::BUILD at line 447
sub MongoDB::Connection::connect; # xsub
# spent 2µs within MongoDB::Connection::find_master which was called: # once (2µs+0s) by MongoDB::Connection::BUILD at line 439
sub MongoDB::Connection::find_master; # xsub
# spent 4µs within MongoDB::Connection::host which was called 2 times, avg 2µs/call: # 2 times (4µs+0s) by MongoDB::Connection::BUILD at line 424, avg 2µs/call
sub MongoDB::Connection::host; # xsub
# spent 1µs within MongoDB::Connection::password which was called: # once (1µs+0s) by MongoDB::Connection::connect at line 447
sub MongoDB::Connection::password; # xsub
# spent 1µs within MongoDB::Connection::port which was called: # once (1µs+0s) by MongoDB::Connection::BUILD at line 424
sub MongoDB::Connection::port; # xsub
# spent 12.6s within MongoDB::Connection::send which was called 1000000 times, avg 13µs/call: # 1000000 times (12.6s+0s) by MongoDB::Collection::batch_insert at line 313 of MongoDB/Collection.pm, avg 13µs/call
sub MongoDB::Connection::send; # xsub
# spent 2µs within MongoDB::Connection::timeout which was called: # once (2µs+0s) by MongoDB::Connection::_init_conn at line 446
sub MongoDB::Connection::timeout; # xsub
# spent 3µs within MongoDB::Connection::username which was called: # once (3µs+0s) by MongoDB::Connection::connect at line 447
sub MongoDB::Connection::username; # xsub