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 )