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.007000';
25 11     11   5187 use Moo::Role;
  11         20  
  11         65  
26             with 'OpenSearch::Client::Role::CxnPool';
27             requires 'next_cxn', 'sniff';
28 11     11   4843 use namespace::clean;
  11         16  
  11         95  
29              
30 11     11   2375 use OpenSearch::Client::Util qw(parse_params);
  11         18  
  11         68  
31 11     11   2378 use List::Util qw(min);
  11         14  
  11         710  
32 11     11   356 use Try::Tiny;
  11         56  
  11         5367  
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 48 my ( $class, $params ) = parse_params(@_);
42             $params->{sniff_max_content_length} = !$params->{max_content_length}
43 12 50       57 unless defined $params->{sniff_max_content_length};
44 12         25 return $params;
45             }
46              
47             #===================================
48             sub schedule_check {
49             #===================================
50 14     14 1 55 my $self = shift;
51 14         266 $self->logger->info("Require sniff before next request");
52 14         359 $self->next_sniff(-1);
53             }
54              
55             #===================================
56             sub parse_sniff {
57             #===================================
58 38     38 1 304 my $self = shift;
59 38 100       147 my $nodes = shift or return;
60 25         213 my @live_nodes;
61 25         37 my $max = 0;
62 25         61 my $sniff_max = $self->sniff_max_content_length;
63              
64 25         80 for my $node_id ( keys %$nodes ) {
65 47         64 my $data = $nodes->{$node_id};
66              
67 47   66     149 my $addr = $data->{http}{publish_address} || $data->{http_address};
68 47 100       78 my $host = $self->_extract_host($addr)
69             or next;
70              
71 46 50       84 $host = $self->should_accept_node( $host, $node_id, $data )
72             or next;
73              
74 46         78 push @live_nodes, $host;
75 46 100 66     125 next unless $sniff_max and $data->{http};
76              
77 43   100     92 my $node_max = $data->{http}{max_content_length_in_bytes} || 0;
78 43 100       97 $max
    100          
79             = $node_max == 0 ? $max
80             : $max == 0 ? $node_max
81             : min( $node_max, $max );
82             }
83              
84 25 100       76 return unless @live_nodes;
85              
86 24 100 100     105 $self->cxn_factory->max_content_length($max)
87             if $sniff_max and $max;
88              
89 24         85 $self->set_cxns(@live_nodes);
90 24         87 my $next = $self->next_sniff( time() + $self->sniff_interval );
91 24         1029 $self->logger->infof( "Next sniff at: %s", scalar localtime($next) );
92              
93 24         849 return 1;
94             }
95              
96             #===================================
97             sub _extract_host {
98             #===================================
99 53     53   82 my $self = shift;
100 53   100     110 my $host = shift || return;
101 51         200 $host =~ s{^inet\[(.+)\]$}{$1};
102 51         239 $host =~ s{^[^/]*/}{};
103 51         131 return $host;
104             }
105              
106             #===================================
107 46     46 1 85 sub should_accept_node { return $_[1] }
108             #===================================
109              
110             1;
111              
112             __END__