Amazon-DynamoDB-Simple
view release on metacpan or search on metacpan
lib/Amazon/DynamoDB/Simple.pm view on Meta::CPAN
This module provides a simple UI layer on top of Amazon::DynamoDB. It also
makes your data highly available across exactly 2 AWS regions. In other words
it provides redundancy in case one region goes down. It doesn't do async. It
doesn't (currently) support secondary keys.
Note Amazon::DynamoDB can't handle complex data structures. But this module
can because it serializes yer stuff to JSON if needed.
At the moment you cannot use this module against a single dynamodb server. The
table must exist in 2 regions. I want to make the high availability part
optional in the future. It should not be hard. Patches welcome.
=head1 DATA REDUNDANCY
TODO
=cut
has table => (is => 'rw', required => 1);
has primary_key => (is => 'rw', required => 1);
has dynamodbs => (is => 'lazy');
has hosts => (is => 'rw', lazy => 1, builder => 1);
has access_key_id => (is => 'rw', lazy => 1, builder => 1);
has secret_access_key => (is => 'rw', lazy => 1, builder => 1);
sub _build_access_key_id { $ENV{AWS_ACCESS_KEY_ID} }
sub _build_secret_access_key { $ENV{AWS_SECRET_ACCESS_KEY} }
sub _build_hosts {
return [qw/
dynamodb.us-east-1.amazonaws.com
dynamodb.us-west-1.amazonaws.com
/];
}
sub _build_dynamodbs {
my $self = shift;
my @dynamodbs;
my $hosts = $self->hosts();
for my $host (@$hosts) {
push @dynamodbs,
Amazon::DynamoDB->new(
access_key => $self->access_key_id,
secret_key => $self->secret_access_key,
ssl => 1,
version => '20120810',
implementation => 'Amazon::DynamoDB::MojoUA',
host => $host,
);
}
return \@dynamodbs;
}
sub put {
my ($self, %item) = @_;
# timestamp this transaction
$item{last_updated} = DateTime->now . ""; # stringify datetime
$item{deleted} ||= 0;
%item = $self->deflate(%item);
my $dynamodbs = $self->dynamodbs();
my $success = 0;
for my $dynamodb (@$dynamodbs) {
try {
$dynamodb->put_item(
TableName => $self->table,
Item => \%item,
)->get;
$success++;
}
catch {
warn "caught error: " . p $_;
};
}
# make sure at least one put_item() was successful
confess "unable to save to any dynamodb" unless $success;
}
sub delete {
my ($self, $key) = @_;
my %item = $self->get($key);
return unless keys %item;
$self->put(%item, deleted => 1);
}
# Amazon::DynamoDB can't handle anything other than simple scalars
sub inflate {
my ($self, %item) = @_;
my %new;
for my $key (keys %item) {
my $value = $item{$key};
$new{$key} = $self->is_valid_json($value)
? JSON::XS->new->utf8->pretty->decode($value)
: $value;
}
return %new;
}
# Amazon::DynamoDB can't handle anything other than simple scalars
sub deflate {
my ($self, %item) = @_;
my %new;
for my $key (keys %item) {
my $value = $item{$key};
$new{$key} = ref $value
? JSON::XS->new->utf8->pretty->encode($value)
: $item{$key};
}
( run in 1.416 second using v1.01-cache-2.11-cpan-cdf2f3d4e48 )