Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #!/usr/bin/perl
- package RedC;
- use strict;
- #use warnings;
- use utf8;
- binmode $_=>':utf8' for *STDOUT,*STDERR;
- use 5.16.1;
- use Redis::Fast;
- use CBOR::XS;
- use Data::Dumper;
- use Carp qw(confess);
- my %conoBy;
- my %redisCanDoThis;
- my $redTestObj;
- my $cbor=CBOR::XS->new;
- sub new {
- my ($class,$coName,$conIndex)=@_;
- my %props=('name'=>$coName,'index'=>$conIndex);
- for (map [each %props], 1..keys %props) {
- confess "$_->[1] already used as $_->[0]" if $conoBy{$_->[0]}{$_->[1]}
- }
- my $redC=new Redis::Fast (
- 'reconnect'=>3,
- 'every'=>100_000,
- 'on_connect'=>sub {
- $_[0]->select($conIndex);
- });
- my @me=($coName,$conIndex,\$redC);
- $redTestObj||=$redC;
- $conoBy{'name'}{$coName}=$redC;
- $conoBy{'index'}{$conIndex}=$redC;
- bless sub {
- state $selfMethods={
- 'me' => sub {
- return \@me
- },
- 'write' => sub {
- my $cb=pop(@_) if ref $_[$#_] eq 'CODE';
- return unless @_;
- my $method=(@_>2?'m':'').'set';
- $redC->$method(
- (map {
- my ($k,$v)=(shift,shift);
- $k=>ref($v)
- ? $CBOR::XS::MAGIC.$cbor->encode($v)
- : $v
- } 1..+(scalar(@_)>>1)),
- $cb?($cb):()
- );
- },
- 'read' => sub {
- my $flRetHashRef=ref($_[0]) eq 'HASH'?do { shift; 1 }:undef;
- my $cb=pop(@_) if ref $_[$#_] eq 'CODE';
- return unless @_;
- my $method=($#_?'m':'').'get';
- my @k=@_;
- my $retv;
- $redC->$method(@k, sub {
- if ( defined $_[1] ) {
- if ($cb) {
- $cb->(@_)
- } else {
- confess 'Redis error: '.$_[1]
- }
- }
- $retv=[ map {
- ( defined($_) and length($_)>3 and substr($_,0,3) eq $CBOR::XS::MAGIC )
- ? $cbor->decode($_)
- : $_
- } ref($_[0]) eq 'ARRAY'?@{$_[0]}:($_[0]) ];
- $retv={(map {$k[$_]=>$retv->[$_]} 0..$#k)} if $flRetHashRef;
- $cb->( $retv ) if $cb;
- });
- return 1 if $cb;
- $redC->wait_all_responses;
- return $retv;
- }
- };
- return unless my $method=shift;
- return if ref $method;
- return $selfMethods->{$_[0]} if $method eq 'hasMethod';
- if (my $hndl=$selfMethods->{$method}) {
- return $hndl->(@_)
- }
- $redC->$method(@_)
- }, (ref $class || $class);
- }
- sub AUTOLOAD {
- our $AUTOLOAD;
- my $slf=$_[0];
- return unless my ($method)=$AUTOLOAD=~/::(\w+)$/;
- unless ($slf->('hasMethod', $method) or $redisCanDoThis{$method}) {
- confess 'Redis method "select" is prohibited for '.__PACKAGE__.' objects'
- if $method eq 'select';
- eval { $redTestObj->$method() };
- confess 'Redis cant do <<'.$method.'>>' if $@ and index($@,'unknown command')>=0;
- $redisCanDoThis{$method}=1
- }
- {
- no strict 'refs';
- *{$AUTOLOAD}=sub {
- $slf->($method, @_[1..$#_]);
- }
- }
- goto &{$AUTOLOAD};
- }
- sub DESTROY {
- my $slf=shift;
- my @iam=@{$slf->('me')};
- delete $conoBy{'name'}{$iam[0]};
- delete $conoBy{'index'}{$iam[1]};
- undef ${$iam[2]};
- }
- 1;
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement