File Coverage

blib/lib/OpenSearch/Client/Role/CxnPool/Sniff.pm
Criterion Covered Total %
statement 47 47 100.0
branch 16 18 88.8
condition 11 13 84.6
subroutine 10 10 100.0
pod 3 4 75.0
total 87 92 94.5


line stmt bran cond sub pod time code
1             # OpenSearch::Client is an unofficial client for OpenSearch.
2             # It is derived from Search::Elasticsearch version 7.714
3             # License details from the original work are contained in the
4             # NOTICE file distributed with this work.
5             #
6             #-----------------------------------------------------------------------
7             # OpenSearch::Client
8             #-----------------------------------------------------------------------
9             # Copyright 2026 Mark Dootson
10             #
11             # Licensed under the Apache License, Version 2.0 (the "License");
12             # you may not use this file except in compliance with the License.
13             # You may obtain a copy of the License at
14             #
15             # http://www.apache.org/licenses/LICENSE-2.0
16             #
17             # Unless required by applicable law or agreed to in writing, software
18             # distributed under the License is distributed on an "AS IS" BASIS,
19             # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
20             # See the License for the specific language governing permissions and
21             # limitations under the License.
22              
23             package OpenSearch::Client::Role::CxnPool::Sniff;
24             $OpenSearch::Client::Role::CxnPool::Sniff::VERSION = '3.007002';
25 11     11   5829 use Moo::Role;
  11         21  
  11         75  
26             with 'OpenSearch::Client::Role::CxnPool';
27             requires 'next_cxn', 'sniff';
28 11     11   5595 use namespace::clean;
  11         22  
  11         70  
29              
30 11     11   2704 use OpenSearch::Client::Util qw(parse_params);
  11         18  
  11         92  
31 11     11   2690 use List::Util qw(min);
  11         22  
  11         831  
32 11     11   333 use Try::Tiny;
  11         73  
  11         5764  
33              
34             has 'sniff_interval' => ( is => 'ro', default => 300 );
35             has 'next_sniff' => ( is => 'rw', default => 0 );
36             has 'sniff_max_content_length' => ( is => 'ro' );
37              
38             #===================================
39             sub BUILDARGS {
40             #===================================
41 12     12 0 51 my ( $class, $params ) = parse_params(@_);
42             $params->{sniff_max_content_length} = !$params->{max_content_length}
43 12 50       60 unless defined $params->{sniff_max_content_length};
44 12         52 return $params;
45             }
46              
47             #===================================
48             sub schedule_check {
49             #===================================
50 14     14 1 61 my $self = shift;
51 14         269 $self->logger->info("Require sniff before next request");
52 14         346 $self->next_sniff(-1);
53             }
54              
55             #===================================
56             sub parse_sniff {
57             #===================================
58 38     38 1 260 my $self = shift;
59 38 100       211 my $nodes = shift or return;
60 25         95 my @live_nodes;
61 25         103 my $max = 0;
62 25         81 my $sniff_max = $self->sniff_max_content_length;
63              
64 25         66 for my $node_id ( keys %$nodes ) {
65 47         66 my $data = $nodes->{$node_id};
66              
67 47   66     150 my $addr = $data->{http}{publish_address} || $data->{http_address};
68 47 100       97 my $host = $self->_extract_host($addr)
69             or next;
70              
71 46 50       87 $host = $self->should_accept_node( $host, $node_id, $data )
72             or next;
73              
74 46         80 push @live_nodes, $host;
75 46 100 66     141 next unless $sniff_max and $data->{http};
76              
77 43   100     121 my $node_max = $data->{http}{max_content_length_in_bytes} || 0;
78 43 100       103 $max
    100          
79             = $node_max == 0 ? $max
80             : $max == 0 ? $node_max
81             : min( $node_max, $max );
82             }
83              
84 25 100       67 return unless @live_nodes;
85              
86 24 100 100     91 $self->cxn_factory->max_content_length($max)
87             if $sniff_max and $max;
88              
89 24         80 $self->set_cxns(@live_nodes);
90 24         89 my $next = $self->next_sniff( time() + $self->sniff_interval );
91 24         1107 $self->logger->infof( "Next sniff at: %s", scalar localtime($next) );
92              
93 24         900 return 1;
94             }
95              
96             #===================================
97             sub _extract_host {
98             #===================================
99 53     53   83 my $self = shift;
100 53   100     121 my $host = shift || return;
101 51         199 $host =~ s{^inet\[(.+)\]$}{$1};
102 51         190 $host =~ s{^[^/]*/}{};
103 51         129 return $host;
104             }
105              
106             #===================================
107 46     46 1 101 sub should_accept_node { return $_[1] }
108             #===================================
109              
110             1;
111              
112             __END__