AC-Yenta
    
    
  
  
  
view release on metacpan or search on metacpan
eg/yenta.conf view on Meta::CPAN
# example yenta config
#
# file will be reloaded automagically if it changes. no need to hup or restart.
port            3503
environment	prod
# save peer status in a file?
savestatus      /var/tmp/yenta.status           yenta
allow		127.0.0.1
lib/AC/Yenta.pm view on Meta::CPAN
=head1 USAGE
    Copy + Paste from the example code into your own code.
    Copy + Paste from the example config into your own config.
    Send in bug report.
=head1 YIDDISH-ENGLISH GLOSSARY
	Kibitz - Gossip. Casual information exchange with ones peers.
	Yenta - 1. An old woman who kibitzes with other yentas.
		2. Software which kibitzes with other yentas.
=head1 DESCRIPTION
=head2 Peers
All of the running yentas are peers. There is no master server.
New nodes can be added or removed on the fly with no configuration.
=head2 Kibitzing
Each yenta kibitzes (gossips) with the other yentas in the network
to exchange status information, distribute key-value data, and
detect and correct inconsistent data.
=head2 Eventual Consistency
Key-value data is versioned with timestamps. By default, newest wins.
Maps can be configured to keep and return multiple versions and client
code can use other conflict resolution mechanisms.
Lost, missing or otherwise inconsistent data is detected
by kibitzing merkle tree hash values.
lib/AC/Yenta/Kibitz/Status.pm view on Meta::CPAN
# -*- perl -*-
# Copyright (c) 2009 AdCopy
# Author: Jeff Weisberg
# Created: 2009-Mar-30 10:20 (EDT)
# Function: exchange status info via gossip protocol
#
# $Id$
package AC::Yenta::Kibitz::Status;
use AC::Yenta::Kibitz::Status::Server;
use AC::Yenta::Kibitz::Status::Client;
use AC::Yenta::Debug 'kibitz_status';
use AC::Yenta::Config;
use AC::Yenta::Stats;
use AC::Yenta::MySelf;
lib/AC/Yenta/Status.pm view on Meta::CPAN
        delete $DATA->{peertype}{$ss}{$id} if $ss;
        $DATA->{peertype}{$up->{subsystem}}{$id} = $id;
    }
    # update map info
    $DATA->{peermap}{$id} ||= [];
    $up->{map} ||= [];
    my @curmap = @{$DATA->{peermap}{$id}};
    my @newmap = sort @{$up->{map}};
    return if "@curmap" eq "@newmap";		# unchanged
    # what do we need to add/remove
    my (%remove, %add);
    @remove{@curmap} = @curmap;
    @add{@newmap}    = @newmap;
    delete $remove{$_} for @newmap;
    delete $add{$_}    for @curmap;
    for my $map (keys %remove){
        debug("removing $map from $id");
lib/AC/Yenta/Store/Map.pm view on Meta::CPAN
    # add new version to list. newest 1st
    @versions = sort {$b cmp $a} (@versions, $v);
    if( $cf->{history} && @versions > $cf->{history} ){
        # trim list
        my @rm = splice @versions, $cf->{history}, @versions, ();
        push @deletehist, (map { ({version => decode_version($_), key => $key, shard => $shard}) } @rm);
        $deletedata{$_} = 1 for @_;
    }
    if( $me->is_sharded() ){
        # QQQ - shard changed?
        $db->put($me->{name}, 'shard', $key, encode_shard($shard || 0));
    }
    my $dd = join(' ', map { $_->{version} } @deletehist);
    debug("version list: @versions [delete: $dd]");
    $me->_versput( $key, @versions );
    # update merkles
    $me->merkle( { shard => $shard, key => $key, version => $ver }, @deletehist);
lib/AC/Yenta/Store/Merkle.pm view on Meta::CPAN
        # remove
        debug("updating merkle node $k1 - { $k0 => empty }");
        delete $d{$k0};
    }
    if( keys %d ){
        $d = join("\0", map {"$_\0$d{$_}"} (sort keys %d));
        $me->_mcput( $k1, $d );
        my $newh = sha1_base64($d);
        return if $newh eq $oldh;	# unchanged
        return ($nextshard, $nextver, $newh, scalar keys %d);
    }else{
        $me->_mcdel( $k1 );
        return unless $oldh;		# unchanged
        return ($nextshard, $nextver, undef);
    }
}
# leaf nodes:
#   list of all "ver/key"
#   \0 delimited. sorted by "ver/key"
# add new <key,version> to merkle leaf
sub _merkle_leaf_add {
proto/yenta_status.proto view on Meta::CPAN
// Copyright (c) 2009 AdCopy
// Author: Jeff Weisberg
// Created: 2009-Mar-27 16:05 (EDT)
// Function: yenta status exchanges
//
// $Id$
import "std_ipport.proto";
message ACPYentaStatus {
        required string         hostname        = 1;
        required string         datacenter      = 2;
	required string		subsystem	= 3;
        required string         environment     = 4;
( run in 0.470 second using v1.01-cache-2.11-cpan-c333fce770f )