The document discusses designing a Perl module called Net::AWS::Glacier for interacting with Amazon Glacier, a cloud storage service. It proposes a two-level design with a low-level API module that mirrors the Glacier API and a high-level module that provides a more object-oriented interface. The high-level module would use a "Vault" object to manage downloads and access to archive data, hiding low-level details like iterating through job lists. An inheritance-based approach is described where derived classes can customize initialization while reusing a common object structure and initialization logic.
2. Welcome to the Frozen Wasteland
Amazon Glacier: “cold” data storage.
Cheap: $0.01/month/GB.
CYA backups of input data.
Tax data.
Not for recovery backups.
3. No dashboard
No realtime access.
Use code for all operations.
Java & RESTful API's.
Perl uses RESTful.
4. Net::Amazon::Glacier
Stops at the API.
No high-level operations.
We all get to re-invent the wheel.
Common problem with Perl:
building-blocks, not frameworks.
10. Designing the high-level module.
What are the things you don't want to do?
Iterate alist of jobs, checking which ones
are done, checking if they have already
been processed, downloading their
contents if necessary, validating the
download, checking continuation
markers...
14. Designing the high-level module.
What are the things you want to do?
Download an archive.
Download an inventory.
15. Designing the high-level module.
What are the things you want to do?
Download whatever is ready.
16. Designing the high-level module.
What are the things you want to do?
Download whatever is ready.
Get a current inventory.
17. Bad design: Use API as base class.
API uses positional notation.
Errors tied to API structure.
No defaults.
Minimal sanity checking.
Not suitable for high-level interface.
18. Fix: use the API.
High-level interface is more complex:
Named args.
Sanity checks.
Detailed errors.
Uses dispatcher for low-level calls.
19. High-level interface
“Vault” object.
Const copy of the vault name.
Everything else managed inside the class.
Inside out data keeps object minimal.
Control data inherited from factory object.
20. Construct: minimal structure.
Guarantee
data &
type.
Ensure
inside-out
data is
present.
sub construct
{
my $proto = shift;
my $class = blessed $proto;
my $vault
= bless ( my $a = '' ),
$class || $proto;
$vault_argz{ refaddr $vault }
= $class
? $vault_argz{ refaddr $proto }
: []
;
$vault
}
21. Initialize: Populate the object...
sub initialize
{
my $vault = shift;
$$vault = shift;
dlock $vault;
…
}
dlock()
freezes
object
contents.
22. Initialize: … then the data.
sub initialize
{
…
if( @_ )
{
my %initz = @_;
for( @arg_fieldz )
{
my $value = $initz{ $_ }
// next;
$vault>$_( $value );
}
}
$vault
}
Use array
of field
names to
avoid
copying
cruft.
Method
simplifies
inheritence.
23. NEXT to LAST
NEXT module replaces “SUPER”.
Pseudo-class:
“EVERY” “EVERY::LAST”
New calls:
$obj->EVERY::LAST::initialize( @_ );
DESTROY calls:
$obj->EVERY::cleanup( @_ );
24. Derived classes layer initialize
sub new
{
# everyone gets the same structure.
my $vault = &construct;
# called in bottomup order.
# derived classes can interrogate object
# using methods at each level.
$vault>EVERY::LAST::initialize( @_ );
$vault
}
26. Resolution
Two-state solution: API + High-Level.
API looks like the published standard:
array messages, croaks up front.
High-level is saner:
factory with inheritence, named args.
27. Net::AWS
Alpha code currently lives in github:
https://github.com/lembark/netaws
this inclues the TreeHash & Signature modules.
Main doc's are in ./lib/Net/AWS/Glacier.pm.
Feedback welcome.