Thanks for your input, however I can replicate the problem using a client based on Mojo::IOLoop, like this for example:
use warnings;
use strict;
use IO::Socket::SSL 'SSL_VERIFY_NONE';
use Mojo::IOLoop;
use Time::HiRes qw'time';
use constant {
BUFSIZE => 16384,
INTERVAL => 1,
};
my $PEER_ADDR='192.168.1.10';
my $PEER_PORT=1234;
my $transferred=0;
my ($currentTime,$intvlStart,$intvlEnd);
Mojo::IOLoop->client(
{ address => $PEER_ADDR,
port => $PEER_PORT,
tls => 1,
tls_options => {SSL_verify_mode => SSL_VERIFY_NONE},
tls_verify => SSL_VERIFY_NONE },
sub {
my ($loop, $err, $stream) = @_;
if(defined $err) {
print "Failed to connect to SSL server: $err\n";
return;
}
print "Connected, downloading data from server...\n";
$currentTime=time();
($intvlStart,$intvlEnd)=($currentTime,$currentTime+INTERVAL);
$stream->on(close => sub {die "Connection closed by peer"});
$stream->on(error => sub {
die "Failed to read from SSL socket: $_[1]"
});
$stream->on(read => sub {
my ($stream,$readData)=@_;
my $readLength=length($readData);
die "Unexpected read length: $readLength"
unless($readLength == BUFSIZE);
$transferred+=BUFSIZE;
$currentTime=time();
if($currentTime >= $intvlEnd) {
printReport();
initNewInterval();
}
});
});
sub printReport {
my $speed=formatSize($transferred/($currentTime-$intvlStart));
print "Transfer speed: $speed/s\n";
}
sub formatSize {
my $size=shift;
my @UNITS=('',qw'K M G T');
my $unitIdx=0;
while($size >= 1000 && $unitIdx < $#UNITS) {
$size/=1000;
$unitIdx++;
}
$size=sprintf('%.2f',$size) if(index($size,'.') != -1);
return $size.' '.$UNITS[$unitIdx].'B';
}
sub initNewInterval {
$transferred=0;
$intvlStart=$currentTime;
$intvlEnd+=INTERVAL while($intvlEnd < $intvlStart+INTERVAL/2);
}
print "Connecting to SSL server ($PEER_ADDR:$PEER_PORT)\n";
Mojo::IOLoop->start();
When I perform the test using this Mojo-based non-blocking SSL client, I have a CPU core which is used at 100% (~40% us, ~10% sy, ~50% si), exactly like with my "low-level" non-blocking SSL client implementation. The problem is that when I use this Mojo-based client, I don't have access to the number of sysread calls which failed due to SSL_WANT_READ, so I have less information to provide for debugging.
For the record, if I use a blocking SSL client (still in Perl) instead, the highest CPU core usage for a 1Gbps transfer is at 55% on this system... |