CHI-Driver-HandlerSocket
view release on metacpan or search on metacpan
lib/CHI/Driver/HandlerSocket.pm view on Meta::CPAN
This program is free software; you can redistribute it and/or modify it under
the same terms as Perl itself.
=cut
has 'dbh' => ( is => 'rw', ); # isa => 'DBI::db',
sub get_dbh {
my $self = shift;
my $dbh = $self->dbh or die "no dbh!";
return $dbh->dbh if eval { $dbh->ISA('DBIx::Connector'); };
return $dbh->() if eval { ref $dbh eq 'CODE' }; # tell me again what's wrong with UNIVERSAL::ISA.
# warn "dbh isn't a DBI::db; it's a " . ref $dbh unless eval { $dbh->ISA('DBI::db'); }; # "dbh isn't a DBI::db; it's a DBI::db"
return $dbh;
}
has 'table_prefix' => ( is => 'rw', isa => 'Str', default => 'chi_', );
has 'host' => ( is => 'ro', default => 'localhost', );
has 'read_port' => ( is => 'ro', default => 9998, );
has 'write_port' => ( is => 'ro', default => 9999, );
has 'read_index' => ( is => 'ro', default => 1, );
has 'write_index' => ( is => 'ro', default => 1, );
has 'read_hs' => ( is => 'rw', isa => 'Net::HandlerSocket', );
has 'write_hs' => ( is => 'rw', isa => 'Net::HandlerSocket', );
has 'mysql_thread_stack' => ( is => 'rw', isa => 'Num', ); # HandlerSocket uses the stack to buffer writes; remember how large the stack is
__PACKAGE__->meta->make_immutable;
sub BUILD {
my ( $self, $args ) = @_;
my $dbh = $self->get_dbh;
my $table = $self->_table; # don't quote it
my $database_name = do {
my $sth = $dbh->prepare( qq{ SELECT database() AS dbname } ) or die $dbh->errstr;
$sth->execute or die $sth->errstr;
my @row = $sth->fetchrow_array or die "couldn't figure out the name of the database";
$sth->finish;
$row[0];
};
# HandlerSocket uses the stack to buffer writes; remember how large the stack is
$self->mysql_thread_stack(do {
my $sth = $dbh->prepare( qq{ SHOW global variables WHERE Variable_name = 'thread_stack' } ) or die $dbh->errstr;
$sth->execute or die $sth->errstr;
my @row = $sth->fetchrow_array || do {
# every time you use a magic number in code, a devil gets his horns; seriously though, this is this
# particular MySQL releases default thread stack size
warn "couldn't figure out the thread_stack size; oh well, guessing";
(131072);
};
$sth->finish;
# 5824 is the amount of data my MySQL version/install said had already been used of the stack before the
# unaccomodatable request came in; 2 is a fudge factor
# if this is less than 0 for some reason, then all writes will go to DBI, which is probably necessary in that case
$row[0] - 5824 * 2;
});
# warn "host: @{[ $self->host ]} port: @{[ $self->read_port ]} database_name: $database_name table: $table read_index: @{[ $self->read_index ]} write_index: @{[ $self->write_index ]} thread_stack: @{[ $self->mysql_thread_stack ]}";
# CREATE TABLE IF NOT EXISTS $table ( `key` VARCHAR( 600 ), `value` BLOB, PRIMARY KEY ( `key` ) ) CHARSET=ASCII # fails 30 tests right now
# CREATE TABLE IF NOT EXISTS $table ( `key` VARCHAR( 300 ), `value` TEXT, PRIMARY KEY ( `key` ) ) CHARSET=utf8 # fails 220 tests
$dbh->do( qq{
CREATE TABLE IF NOT EXISTS $table ( `key` VARCHAR( 600 ), `value` BLOB, PRIMARY KEY ( `key` ) ) CHARSET=ASCII
} ) or croak $dbh->errstr;
# from https://github.com/ahiguti/HandlerSocket-Plugin-for-MySQL/blob/master/docs-en/perl-client.en.txt:
# The first argument for open_index is an integer value which is
# used to identify an open table, which is only valid within the
# same Net::HandlerSocket object. The 4th argument is the name of
# index to open. If 'PRIMARY' is specified, the primary index is
# open. The 5th argument is a comma-separated list of column names.
my $read_hs = Net::HandlerSocket->new({ host => $self->host, port => $self->read_port, }) or die;
$read_hs->open_index($self->read_index, $database_name, $table, 'PRIMARY', 'value') and die $read_hs->get_error;
$self->read_hs($read_hs);
my $write_hs = Net::HandlerSocket->new({ host => $self->host, port => $self->write_port, });
$write_hs->open_index($self->write_index, $database_name, $table, 'PRIMARY', 'key,value') and die $write_hs->get_error;
$self->write_hs($write_hs);
return;
}
sub _table {
my $self = shift;
return $self->table_prefix() . $self->namespace();
}
sub fetch {
my ( $self, $key, ) = @_;
my $index = $self->read_index;
my $hs = $self->read_hs;
# from https://github.com/ahiguti/HandlerSocket-Plugin-for-MySQL/blob/master/docs-en/perl-client.en.txt:
# The first argument must be an integer which has specified as the
# first argument for open_index on the same Net::HandlerSocket
# object. The second argument specifies the search operation. The
# current version of handlersocket supports '=', '>=', '<=', '>',
# and '<'. The 3rd argument specifies the key to find, which must
# an arrayref whose length is equal to or smaller than the number
# of key columns of the index. The 4th and the 5th arguments
# specify the maximum number of records to be retrieved, and the
# number of records skipped before retrieving records. The columns
# to be retrieved are specified by the 5th argument for the
( run in 0.641 second using v1.01-cache-2.11-cpan-39bf76dae61 )