Filename | /opt/flows/lib/lib/perl5/Search/Elasticsearch/Role/Cxn.pm |
Statements | Executed 65 statements in 1.63ms |
Calls | P | F | Exclusive Time |
Inclusive Time |
Subroutine |
---|---|---|---|---|---|
1 | 1 | 1 | 45µs | 2.02ms | pings_ok | Search::Elasticsearch::Role::Cxn::
2 | 1 | 1 | 17µs | 17µs | process_response | Search::Elasticsearch::Role::Cxn::
2 | 2 | 2 | 17µs | 20µs | mark_live | Search::Elasticsearch::Role::Cxn::
1 | 1 | 1 | 16µs | 330µs | BEGIN@3 | Search::Elasticsearch::Role::Cxn::
1 | 1 | 1 | 14µs | 64µs | BEGIN@5 | Search::Elasticsearch::Role::Cxn::
1 | 1 | 1 | 10µs | 147µs | BEGIN@4 | Search::Elasticsearch::Role::Cxn::
1 | 1 | 1 | 9µs | 272µs | BEGIN@9 | Search::Elasticsearch::Role::Cxn::
1 | 1 | 1 | 9µs | 43µs | BEGIN@6 | Search::Elasticsearch::Role::Cxn::
1 | 1 | 1 | 8µs | 154µs | BEGIN@8 | Search::Elasticsearch::Role::Cxn::
1 | 1 | 1 | 8µs | 10µs | force_ping | Search::Elasticsearch::Role::Cxn::
1 | 1 | 1 | 8µs | 44µs | __ANON__[:3] | Search::Elasticsearch::Role::Cxn::
1 | 1 | 1 | 6µs | 6µs | is_dead | Search::Elasticsearch::Role::Cxn::
1 | 1 | 1 | 5µs | 6µs | is_live | Search::Elasticsearch::Role::Cxn::
1 | 1 | 1 | 4µs | 4µs | BEGIN@7 | Search::Elasticsearch::Role::Cxn::
5 | 5 | 2 | 4µs | 4µs | next_ping (xsub) | Search::Elasticsearch::Role::Cxn::
2 | 2 | 1 | 4µs | 4µs | logger (xsub) | Search::Elasticsearch::Role::Cxn::
2 | 2 | 1 | 3µs | 3µs | ping_failures (xsub) | Search::Elasticsearch::Role::Cxn::
1 | 1 | 1 | 2µs | 2µs | __ANON__[:27] | Search::Elasticsearch::Role::Cxn::
1 | 1 | 1 | 2µs | 2µs | request_timeout (xsub) | Search::Elasticsearch::Role::Cxn::
2 | 2 | 1 | 1µs | 1µs | uri (xsub) | Search::Elasticsearch::Role::Cxn::
1 | 1 | 1 | 1µs | 1µs | __ANON__[:26] | Search::Elasticsearch::Role::Cxn::
1 | 1 | 1 | 900ns | 900ns | default_qs_params (xsub) | Search::Elasticsearch::Role::Cxn::
1 | 1 | 1 | 800ns | 800ns | handle_args (xsub) | Search::Elasticsearch::Role::Cxn::
1 | 1 | 1 | 800ns | 800ns | ping_timeout (xsub) | Search::Elasticsearch::Role::Cxn::
0 | 0 | 0 | 0s | 0s | __ANON__[:113] | Search::Elasticsearch::Role::Cxn::
0 | 0 | 0 | 0s | 0s | __ANON__[:117] | Search::Elasticsearch::Role::Cxn::
0 | 0 | 0 | 0s | 0s | __ANON__[:91] | Search::Elasticsearch::Role::Cxn::
0 | 0 | 0 | 0s | 0s | __ANON__[:96] | Search::Elasticsearch::Role::Cxn::
0 | 0 | 0 | 0s | 0s | _munge_elasticsearch_exception | Search::Elasticsearch::Role::Cxn::
0 | 0 | 0 | 0s | 0s | mark_dead | Search::Elasticsearch::Role::Cxn::
0 | 0 | 0 | 0s | 0s | sniff | Search::Elasticsearch::Role::Cxn::
Line | State ments |
Time on line |
Calls | Time in subs |
Code |
---|---|---|---|---|---|
1 | package Search::Elasticsearch::Role::Cxn; | ||||
2 | 1 | 500ns | $Search::Elasticsearch::Role::Cxn::VERSION = '2.02'; | ||
3 | 4 | 48µs | 3 | 680µs | # spent 330µs (16+314) within Search::Elasticsearch::Role::Cxn::BEGIN@3 which was called:
# once (16µs+314µs) by Module::Runtime::require_module at line 3
# spent 44µs (8+36) within Search::Elasticsearch::Role::Cxn::__ANON__[/opt/flows/lib/lib/perl5/Search/Elasticsearch/Role/Cxn.pm:3] which was called:
# once (8µs+36µs) by import::into at line 34 of Import/Into.pm # spent 330µs making 1 call to Search::Elasticsearch::Role::Cxn::BEGIN@3
# spent 314µs making 1 call to Moo::Role::import
# spent 36µs making 1 call to strictures::import |
4 | 2 | 38µs | 2 | 285µs | # spent 147µs (10+138) within Search::Elasticsearch::Role::Cxn::BEGIN@4 which was called:
# once (10µs+138µs) by Module::Runtime::require_module at line 4 # spent 147µs making 1 call to Search::Elasticsearch::Role::Cxn::BEGIN@4
# spent 138µs making 1 call to Sub::Exporter::__ANON__[/opt/flows/lib/lib/perl5/Sub/Exporter.pm:337] |
5 | 2 | 36µs | 2 | 115µs | # spent 64µs (14+50) within Search::Elasticsearch::Role::Cxn::BEGIN@5 which was called:
# once (14µs+50µs) by Module::Runtime::require_module at line 5 # spent 64µs making 1 call to Search::Elasticsearch::Role::Cxn::BEGIN@5
# spent 50µs making 1 call to Exporter::import |
6 | 2 | 28µs | 2 | 77µs | # spent 43µs (9+34) within Search::Elasticsearch::Role::Cxn::BEGIN@6 which was called:
# once (9µs+34µs) by Module::Runtime::require_module at line 6 # spent 43µs making 1 call to Search::Elasticsearch::Role::Cxn::BEGIN@6
# spent 34µs making 1 call to Exporter::import |
7 | 2 | 28µs | 1 | 4µs | # spent 4µs within Search::Elasticsearch::Role::Cxn::BEGIN@7 which was called:
# once (4µs+0s) by Module::Runtime::require_module at line 7 # spent 4µs making 1 call to Search::Elasticsearch::Role::Cxn::BEGIN@7 |
8 | 2 | 35µs | 2 | 300µs | # spent 154µs (8+146) within Search::Elasticsearch::Role::Cxn::BEGIN@8 which was called:
# once (8µs+146µs) by Module::Runtime::require_module at line 8 # spent 154µs making 1 call to Search::Elasticsearch::Role::Cxn::BEGIN@8
# spent 146µs making 1 call to Sub::Exporter::__ANON__[/opt/flows/lib/lib/perl5/Sub/Exporter.pm:337] |
9 | 2 | 1.17ms | 2 | 536µs | # spent 272µs (9+264) within Search::Elasticsearch::Role::Cxn::BEGIN@9 which was called:
# once (9µs+264µs) by Module::Runtime::require_module at line 9 # spent 272µs making 1 call to Search::Elasticsearch::Role::Cxn::BEGIN@9
# spent 264µs making 1 call to namespace::clean::import |
10 | |||||
11 | 1 | 2µs | 1 | 9µs | requires qw(protocol perform_request error_from_text); # spent 9µs making 1 call to Moo::Role::requires |
12 | |||||
13 | 1 | 1µs | 1 | 136µs | has 'host' => ( is => 'ro', required => 1 ); # spent 136µs making 1 call to Moo::Role::has |
14 | 1 | 1µs | 1 | 114µs | has 'port' => ( is => 'ro', required => 1 ); # spent 114µs making 1 call to Moo::Role::has |
15 | 1 | 1µs | 1 | 110µs | has 'uri' => ( is => 'ro', required => 1 ); # spent 110µs making 1 call to Moo::Role::has |
16 | 1 | 1µs | 1 | 110µs | has 'request_timeout' => ( is => 'ro', default => 30 ); # spent 110µs making 1 call to Moo::Role::has |
17 | 1 | 1µs | 1 | 109µs | has 'ping_timeout' => ( is => 'ro', default => 2 ); # spent 109µs making 1 call to Moo::Role::has |
18 | 1 | 1µs | 1 | 110µs | has 'sniff_timeout' => ( is => 'ro', default => 1 ); # spent 110µs making 1 call to Moo::Role::has |
19 | 1 | 1µs | 1 | 110µs | has 'sniff_request_timeout' => ( is => 'ro', default => 2 ); # spent 110µs making 1 call to Moo::Role::has |
20 | 1 | 1µs | 1 | 119µs | has 'next_ping' => ( is => 'rw', default => 0 ); # spent 119µs making 1 call to Moo::Role::has |
21 | 1 | 1µs | 1 | 118µs | has 'ping_failures' => ( is => 'rw', default => 0 ); # spent 118µs making 1 call to Moo::Role::has |
22 | 1 | 1µs | 1 | 111µs | has 'dead_timeout' => ( is => 'ro', default => 60 ); # spent 111µs making 1 call to Moo::Role::has |
23 | 1 | 1µs | 1 | 110µs | has 'max_dead_timeout' => ( is => 'ro', default => 3600 ); # spent 110µs making 1 call to Moo::Role::has |
24 | 1 | 1µs | 1 | 124µs | has 'serializer' => ( is => 'ro', required => 1 ); # spent 124µs making 1 call to Moo::Role::has |
25 | 1 | 1µs | 1 | 128µs | has 'logger' => ( is => 'ro', required => 1 ); # spent 128µs making 1 call to Moo::Role::has |
26 | 2 | 11µs | 1 | 127µs | # spent 1µs within Search::Elasticsearch::Role::Cxn::__ANON__[/opt/flows/lib/lib/perl5/Search/Elasticsearch/Role/Cxn.pm:26] which was called:
# once (1µs+0s) by Search::Elasticsearch::Cxn::HTTPTiny::new at line 51 of (eval 87)[Sub/Quote.pm:5] # spent 127µs making 1 call to Moo::Role::has |
27 | 2 | 7µs | 1 | 125µs | # spent 2µs within Search::Elasticsearch::Role::Cxn::__ANON__[/opt/flows/lib/lib/perl5/Search/Elasticsearch/Role/Cxn.pm:27] which was called:
# once (2µs+0s) by Search::Elasticsearch::Cxn::HTTPTiny::new at line 43 of (eval 87)[Sub/Quote.pm:5] # spent 125µs making 1 call to Moo::Role::has |
28 | |||||
29 | 1 | 4µs | my %Code_To_Error = ( | ||
30 | 400 => 'Request', | ||||
31 | 401 => 'Unauthorized', | ||||
32 | 403 => 'Forbidden', | ||||
33 | 404 => 'Missing', | ||||
34 | 408 => 'RequestTimeout', | ||||
35 | 409 => 'Conflict', | ||||
36 | 503 => 'Unavailable' | ||||
37 | ); | ||||
38 | |||||
39 | #=================================== | ||||
40 | 1 | 8µs | 1 | 700ns | # spent 6µs (5+700ns) within Search::Elasticsearch::Role::Cxn::is_live which was called:
# once (5µs+700ns) by Search::Elasticsearch::CxnPool::Static::next_cxn at line 22 of /opt/flows/lib/lib/perl5/Search/Elasticsearch/CxnPool/Static.pm # spent 700ns making 1 call to Search::Elasticsearch::Role::Cxn::next_ping |
41 | 1 | 14µs | 1 | 600ns | # spent 6µs (6+600ns) within Search::Elasticsearch::Role::Cxn::is_dead which was called:
# once (6µs+600ns) by Search::Elasticsearch::Role::CxnPool::Static::schedule_check at line 23 of /opt/flows/lib/lib/perl5/Search/Elasticsearch/Role/CxnPool/Static.pm # spent 600ns making 1 call to Search::Elasticsearch::Role::Cxn::next_ping |
42 | #=================================== | ||||
43 | |||||
44 | #=================================== | ||||
45 | # spent 20µs (17+3) within Search::Elasticsearch::Role::Cxn::mark_live which was called 2 times, avg 10µs/call:
# once (12µs+3µs) by Search::Elasticsearch::Role::Cxn::try {...} at line 89
# once (4µs+0s) by Search::Elasticsearch::Role::CxnPool::request_ok at line 66 of /opt/flows/lib/lib/perl5/Search/Elasticsearch/Role/CxnPool.pm | ||||
46 | #=================================== | ||||
47 | 2 | 1µs | my $self = shift; | ||
48 | 2 | 9µs | 1 | 2µs | $self->ping_failures(0); # spent 2µs making 1 call to Search::Elasticsearch::Role::Cxn::ping_failures |
49 | 2 | 14µs | 1 | 2µs | $self->next_ping(0); # spent 2µs making 1 call to Search::Elasticsearch::Role::Cxn::next_ping |
50 | } | ||||
51 | |||||
52 | #=================================== | ||||
53 | sub mark_dead { | ||||
54 | #=================================== | ||||
55 | my $self = shift; | ||||
56 | my $fails = $self->ping_failures; | ||||
57 | $self->ping_failures( $fails + 1 ); | ||||
58 | |||||
59 | my $timeout | ||||
60 | = min( $self->dead_timeout * 2**$fails, $self->max_dead_timeout ); | ||||
61 | my $next = $self->next_ping( time() + $timeout ); | ||||
62 | |||||
63 | $self->logger->infof( 'Marking [%s] as dead. Next ping at: %s', | ||||
64 | $self->stringify, scalar localtime($next) ); | ||||
65 | |||||
66 | } | ||||
67 | |||||
68 | #=================================== | ||||
69 | # spent 10µs (8+2) within Search::Elasticsearch::Role::Cxn::force_ping which was called:
# once (8µs+2µs) by Search::Elasticsearch::Role::CxnPool::Static::schedule_check at line 26 of /opt/flows/lib/lib/perl5/Search/Elasticsearch/Role/CxnPool/Static.pm | ||||
70 | #=================================== | ||||
71 | 1 | 200ns | my $self = shift; | ||
72 | 1 | 5µs | 1 | 900ns | $self->ping_failures(0); # spent 900ns making 1 call to Search::Elasticsearch::Role::Cxn::ping_failures |
73 | 1 | 6µs | 1 | 700ns | $self->next_ping(-1); # spent 700ns making 1 call to Search::Elasticsearch::Role::Cxn::next_ping |
74 | } | ||||
75 | |||||
76 | #=================================== | ||||
77 | # spent 2.02ms (45µs+1.98) within Search::Elasticsearch::Role::Cxn::pings_ok which was called:
# once (45µs+1.98ms) by Search::Elasticsearch::CxnPool::Static::next_cxn at line 24 of /opt/flows/lib/lib/perl5/Search/Elasticsearch/CxnPool/Static.pm | ||||
78 | #=================================== | ||||
79 | 1 | 300ns | my $self = shift; | ||
80 | 1 | 11µs | 3 | 10µs | $self->logger->infof( 'Pinging [%s]', $self->stringify ); # spent 8µs making 1 call to Search::Elasticsearch::Role::Cxn::HTTP::stringify
# spent 2µs making 1 call to Search::Elasticsearch::Role::Logger::infof
# spent 600ns making 1 call to Search::Elasticsearch::Role::Cxn::logger |
81 | return try { | ||||
82 | 1 | 14µs | 2 | 1.79ms | $self->perform_request( # spent 1.79ms making 1 call to Search::Elasticsearch::Cxn::HTTPTiny::perform_request
# spent 800ns making 1 call to Search::Elasticsearch::Role::Cxn::ping_timeout |
83 | { method => 'HEAD', | ||||
84 | path => '/', | ||||
85 | timeout => $self->ping_timeout, | ||||
86 | } | ||||
87 | ); | ||||
88 | 1 | 17µs | 3 | 23µs | $self->logger->infof( 'Marking [%s] as live', $self->stringify ); # spent 15µs making 1 call to Search::Elasticsearch::Role::Cxn::HTTP::stringify
# spent 5µs making 1 call to Search::Elasticsearch::Role::Logger::infof
# spent 3µs making 1 call to Search::Elasticsearch::Role::Cxn::logger |
89 | 1 | 4µs | 1 | 16µs | $self->mark_live; # spent 16µs making 1 call to Search::Elasticsearch::Role::Cxn::mark_live |
90 | 1 | 5µs | 1; | ||
91 | } | ||||
92 | catch { | ||||
93 | $self->logger->debug("$_"); | ||||
94 | $self->mark_dead; | ||||
95 | 0; | ||||
96 | 1 | 26µs | 2 | 3µs | }; # spent 3µs making 1 call to Try::Tiny::catch
# spent 1.95ms making 1 call to Try::Tiny::try, recursion: max depth 1, sum of overlapping time 1.95ms |
97 | } | ||||
98 | |||||
99 | #=================================== | ||||
100 | sub sniff { | ||||
101 | #=================================== | ||||
102 | my $self = shift; | ||||
103 | my $protocol = $self->protocol; | ||||
104 | $self->logger->infof( 'Sniffing [%s]', $self->stringify ); | ||||
105 | return try { | ||||
106 | $self->perform_request( | ||||
107 | { method => 'GET', | ||||
108 | path => '/_nodes/' . $protocol, | ||||
109 | qs => { timeout => $self->sniff_timeout . 's' }, | ||||
110 | timeout => $self->sniff_request_timeout, | ||||
111 | } | ||||
112 | )->{nodes}; | ||||
113 | } | ||||
114 | catch { | ||||
115 | $self->logger->debug($_); | ||||
116 | return; | ||||
117 | }; | ||||
118 | } | ||||
119 | |||||
120 | #=================================== | ||||
121 | # spent 17µs within Search::Elasticsearch::Role::Cxn::process_response which was called 2 times, avg 8µs/call:
# 2 times (17µs+0s) by Search::Elasticsearch::Role::Cxn::HTTP::__ANON__[/opt/flows/lib/lib/perl5/Search/Elasticsearch/Role/Cxn/HTTP.pm:136] at line 135 of /opt/flows/lib/lib/perl5/Search/Elasticsearch/Role/Cxn/HTTP.pm, avg 8µs/call | ||||
122 | #=================================== | ||||
123 | 2 | 2µs | my ( $self, $params, $code, $msg, $body, $mime_type ) = @_; | ||
124 | |||||
125 | 2 | 3µs | my $is_encoded = $mime_type && $mime_type ne 'text/plain'; | ||
126 | |||||
127 | # Request is successful | ||||
128 | |||||
129 | 2 | 3µs | if ( $code >= 200 and $code <= 209 ) { | ||
130 | 2 | 1µs | if ( defined $body and length $body ) { | ||
131 | $body = $self->serializer->decode($body) | ||||
132 | if $is_encoded; | ||||
133 | return $code, $body; | ||||
134 | } | ||||
135 | 2 | 14µs | return ( $code, 1 ) if $params->{method} eq 'HEAD'; | ||
136 | return ( $code, '' ); | ||||
137 | } | ||||
138 | |||||
139 | # Check if the error should be ignored | ||||
140 | my @ignore = to_list( $params->{ignore} ); | ||||
141 | push @ignore, 404 if $params->{method} eq 'HEAD'; | ||||
142 | return ($code) if grep { $_ eq $code } @ignore; | ||||
143 | |||||
144 | # Determine error type | ||||
145 | my $error_type = $Code_To_Error{$code}; | ||||
146 | unless ($error_type) { | ||||
147 | if ( defined $body and length $body ) { | ||||
148 | $msg = $body; | ||||
149 | $body = undef; | ||||
150 | } | ||||
151 | $error_type = $self->error_from_text( $code, $msg ); | ||||
152 | } | ||||
153 | |||||
154 | delete $params->{data} if $params->{body}; | ||||
155 | my %error_args = ( status_code => $code, request => $params ); | ||||
156 | |||||
157 | # Extract error message from the body, if present | ||||
158 | |||||
159 | if ( $body = $self->serializer->decode($body) ) { | ||||
160 | $error_args{body} = $body; | ||||
161 | $msg = $self->_munge_elasticsearch_exception($body) || $msg; | ||||
162 | |||||
163 | $error_args{current_version} = $1 | ||||
164 | if $error_type eq 'Conflict' | ||||
165 | and $msg =~ /: version conflict, current \[(\d+)\]/; | ||||
166 | } | ||||
167 | $msg ||= $error_type; | ||||
168 | |||||
169 | chomp $msg; | ||||
170 | throw( $error_type, "[" . $self->stringify . "]-[$code] $msg", | ||||
171 | \%error_args ); | ||||
172 | } | ||||
173 | |||||
174 | #=================================== | ||||
175 | sub _munge_elasticsearch_exception { | ||||
176 | #=================================== | ||||
177 | my ( $self, $body ) = @_; | ||||
178 | return $body unless ref $body eq 'HASH'; | ||||
179 | my $error = $body->{error} || return; | ||||
180 | return $error unless ref $error eq 'HASH'; | ||||
181 | |||||
182 | my $root_causes = $error->{root_cause} || []; | ||||
183 | unless (@$root_causes) { | ||||
184 | my $msg = "[" . $error->{type} . "] " if $error->{type}; | ||||
185 | $msg .= $error->{reason} if $error->{reason}; | ||||
186 | return $msg; | ||||
187 | } | ||||
188 | |||||
189 | my $json = $self->serializer; | ||||
190 | my @msgs; | ||||
191 | for (@$root_causes) { | ||||
192 | my %cause = (%$_); | ||||
193 | my $msg | ||||
194 | = "[" . ( delete $cause{type} ) . "] " . ( delete $cause{reason} ); | ||||
195 | if ( keys %cause ) { | ||||
196 | $msg .= ", with: " . $json->encode( \%cause ); | ||||
197 | } | ||||
198 | push @msgs, $msg; | ||||
199 | } | ||||
200 | return ( join ", ", @msgs ); | ||||
201 | } | ||||
202 | |||||
203 | 1 | 19µs | 1; | ||
204 | |||||
205 | # ABSTRACT: Provides common functionality to Cxn implementations | ||||
206 | |||||
207 | 1 | 25µs | 1 | 497µs | __END__ # spent 497µs making 1 call to B::Hooks::EndOfScope::XS::__ANON__[/opt/flows/lib/lib/perl5/B/Hooks/EndOfScope/XS.pm:17] |
# spent 900ns within Search::Elasticsearch::Role::Cxn::default_qs_params which was called:
# once (900ns+0s) by Search::Elasticsearch::Role::Cxn::HTTP::build_uri at line 93 of /opt/flows/lib/lib/perl5/Search/Elasticsearch/Role/Cxn/HTTP.pm | |||||
# spent 800ns within Search::Elasticsearch::Role::Cxn::handle_args which was called:
# once (800ns+0s) by Search::Elasticsearch::Cxn::HTTPTiny::_build_handle at line 69 of /opt/flows/lib/lib/perl5/Search/Elasticsearch/Cxn/HTTPTiny.pm | |||||
sub Search::Elasticsearch::Role::Cxn::logger; # xsub | |||||
# spent 4µs within Search::Elasticsearch::Role::Cxn::next_ping which was called 5 times, avg 800ns/call:
# once (2µs+0s) by Search::Elasticsearch::Role::Cxn::mark_live at line 49
# once (700ns+0s) by Search::Elasticsearch::Role::Cxn::force_ping at line 73
# once (700ns+0s) by Search::Elasticsearch::Role::Cxn::is_live at line 40
# once (600ns+0s) by Search::Elasticsearch::Role::Cxn::is_dead at line 41
# once (500ns+0s) by Search::Elasticsearch::CxnPool::Static::next_cxn at line 24 of /opt/flows/lib/lib/perl5/Search/Elasticsearch/CxnPool/Static.pm | |||||
sub Search::Elasticsearch::Role::Cxn::ping_failures; # xsub | |||||
# spent 800ns within Search::Elasticsearch::Role::Cxn::ping_timeout which was called:
# once (800ns+0s) by Search::Elasticsearch::Role::Cxn::try {...} at line 82 | |||||
# spent 2µs within Search::Elasticsearch::Role::Cxn::request_timeout which was called:
# once (2µs+0s) by Search::Elasticsearch::Cxn::HTTPTiny::perform_request at line 32 of /opt/flows/lib/lib/perl5/Search/Elasticsearch/Cxn/HTTPTiny.pm | |||||
# spent 1µs within Search::Elasticsearch::Role::Cxn::uri which was called 2 times, avg 650ns/call:
# once (700ns+0s) by Search::Elasticsearch::Role::Cxn::HTTP::build_uri at line 91 of /opt/flows/lib/lib/perl5/Search/Elasticsearch/Role/Cxn/HTTP.pm
# once (600ns+0s) by Search::Elasticsearch::Role::Cxn::HTTP::stringify at line 21 of /opt/flows/lib/lib/perl5/Search/Elasticsearch/Role/Cxn/HTTP.pm |