EV-Kafka
view release on metacpan or search on metacpan
lib/EV/Kafka.pm view on Meta::CPAN
warn "EV::Kafka: SASL $mech configured without TLS â "
. "credentials will be sent over plaintext\n";
}
}
return $self;
}
package EV::Kafka::Client;
use EV;
use Scalar::Util 'weaken';
sub _any_conn {
my ($self) = @_;
my $cfg = $self->{cfg};
my $conn = $cfg->{bootstrap_conn};
for my $c (values %{$cfg->{conns}}) {
if ($c->connected) { $conn = $c; last }
}
return ($conn && $conn->connected) ? $conn : undef;
}
lib/EV/Kafka.pm view on Meta::CPAN
my $cfg = $self->{cfg};
return $cfg->{conns}{$node_id} if $cfg->{conns}{$node_id};
my $info = $cfg->{broker_map}{$node_id};
return undef unless $info;
my $conn = EV::Kafka::Conn::_new('EV::Kafka::Conn', $self->{loop});
$self->_configure_conn($conn);
$cfg->{conns}{$node_id} = $conn;
weaken(my $weak = $self);
$conn->on_connect(sub {
$weak->_drain_pending_for($node_id) if $weak;
});
$conn->connect($info->{host}, $info->{port}, 10.0);
return $conn;
}
sub _configure_conn {
my ($self, $conn) = @_;
my $cfg = $self->{cfg};
$conn->client_id($cfg->{client_id});
if ($cfg->{tls}) {
$conn->tls(1, $cfg->{tls_ca_file}, $cfg->{tls_skip_verify});
}
if ($cfg->{sasl}) {
$conn->sasl($cfg->{sasl}{mechanism}, $cfg->{sasl}{username}, $cfg->{sasl}{password});
}
weaken(my $weak_cfg = $cfg);
$conn->on_error(sub {
$weak_cfg->{on_error}->($_[0]) if $weak_cfg && $weak_cfg->{on_error};
});
}
sub _bootstrap_connect {
my ($self, $cb) = @_;
my $cfg = $self->{cfg};
my @bs = @{$cfg->{bootstrap}};
my $idx = 0;
lib/EV/Kafka.pm view on Meta::CPAN
$self->_arm_metadata_timer;
});
}
sub _arm_metadata_timer {
my ($self) = @_;
my $cfg = $self->{cfg};
return if $cfg->{_meta_timer};
my $interval = $cfg->{metadata_refresh} || 0;
return if $interval <= 0;
weaken(my $weak = $self);
$cfg->{_meta_timer} = EV::timer $interval, $interval, sub {
return unless $weak;
$weak->_refresh_metadata unless $weak->{cfg}{meta_pending};
};
}
sub _disarm_metadata_timer {
my ($self) = @_;
undef $self->{cfg}{_meta_timer};
}
lib/EV/Kafka.pm view on Meta::CPAN
my $batch_bytes = 0;
for my $b (@$batch) {
$batch_bytes += length($b->{rec}{value} // '') + length($b->{rec}{key} // '') + 20;
}
if ($batch_bytes >= $cfg->{batch_size}) {
$self->_flush_batch($topic, $partition, $conn);
} elsif (!$cfg->{_linger_active}) {
# start linger timer
$cfg->{_linger_active} = 1;
weaken(my $weak = $self);
$cfg->{_linger_timer} = EV::timer $cfg->{linger_ms} / 1000.0, 0, sub {
$cfg->{_linger_active} = 0;
$weak->_flush_all_batches if $weak;
};
}
}
sub _flush_batch {
my ($self, $topic, $partition, $conn) = @_;
my $cfg = $self->{cfg};
lib/EV/Kafka.pm view on Meta::CPAN
$popts{base_sequence} = $saved_seq;
$cfg->{next_sequence}{$bkey} = $saved_seq + scalar @records;
$cfg->{_inflight}{$bkey} = 1;
}
$self->_add_txn_partition($topic, $partition) if $cfg->{_txn_active};
# retry count persists on the batch across re-queues
$cfg->{_batch_retries}{$bkey} //= 3;
weaken(my $weak_self = $self);
$conn->produce_batch($topic, $partition, \@records, \%popts, sub {
my ($result, $err) = @_;
delete $cfg->{_inflight}{$bkey} if $idempotent;
my $retriable = 0;
my $fatal_seq = 0;
if (!$err && $result && ref $result->{topics} eq 'ARRAY') {
for my $t (@{$result->{topics}}) {
for my $p (@{$t->{partitions} // []}) {
my $ec = $p->{error_code} // 0;
lib/EV/Kafka.pm view on Meta::CPAN
my ($topic, $partition) = split /:/, $bkey, 2;
my $leader_id = $self->_get_leader($topic, $partition);
unless (defined $leader_id) { $skipped++; next }
my $conn = $self->_get_or_create_conn($leader_id);
unless ($conn && $conn->connected) { $skipped++; next }
$self->_flush_batch($topic, $partition, $conn);
}
# re-arm timer if batches were skipped (connection not yet ready)
if ($skipped && keys %{$cfg->{batches}}) {
$cfg->{_linger_active} = 1;
weaken(my $weak = $self);
$cfg->{_linger_timer} = EV::timer 0.1, 0, sub {
$cfg->{_linger_active} = 0;
$weak->_flush_all_batches if $weak;
};
}
}
sub produce_many {
my ($self, $messages, $cb) = @_;
my $remaining = scalar @$messages;
lib/EV/Kafka.pm view on Meta::CPAN
undef $g->{heartbeat_timer};
}
sub _start_fetch_loop {
my ($self) = @_;
my $cfg = $self->{cfg};
return if $cfg->{fetch_active};
$cfg->{fetch_active} = 1;
$cfg->{_fetch_in_flight} = 0;
weaken(my $weak = $self);
$cfg->{fetch_timer} = EV::timer 0, 0.1, sub {
return unless $weak && $cfg->{fetch_active};
# Skip ticks while a prior poll round is still in flight to avoid
# duplicate per-(topic,partition) requests landing on the broker.
return if $cfg->{_fetch_in_flight};
$cfg->{_fetch_in_flight} = 1;
$weak->poll(sub { $cfg->{_fetch_in_flight} = 0 });
};
}
src/ppport.h view on Meta::CPAN
sv_resetpvn|5.017005||Viu
SvRMAGICAL|5.003007||Viu
SvRMAGICAL_off|5.003007||Viu
SvRMAGICAL_on|5.003007||Viu
SvROK|5.003007|5.003007|
SvROK_off|5.003007|5.003007|
SvROK_on|5.003007|5.003007|
SvRV|5.003007|5.003007|
SvRV_const|5.010001||Viu
SvRV_set|5.009003|5.003007|p
sv_rvunweaken|5.027004|5.027004|
sv_rvweaken|5.006000|5.006000|
SvRVx|5.003007||Viu
SvRX|5.009005|5.003007|p
SvRXOK|5.009005|5.003007|p
SV_SAVED_COPY|5.009005||Viu
SvSCREAM|5.003007||Viu
SvSCREAM_off|5.003007||Viu
SvSCREAM_on|5.003007||Viu
sv_setbool|5.035004|5.035004|
sv_setbool_mg|5.035004|5.035004|
sv_setgid|5.019001||Viu
( run in 1.519 second using v1.01-cache-2.11-cpan-995e09ba956 )