App-karr
view release on metacpan or search on metacpan
lib/App/karr/Role/SyncLifecycle.pm view on Meta::CPAN
#
# On success: so its DESTROY does not fire a second, redundant push once
# the command body returns (#28).
#
# On failure: the three attempts the insurance would make have just been
# made and the error below carries the same "run karr sync" guidance, so
# leaving the guard armed would only make the END flush in bin/karr (#37)
# repeat the identical failing push, doubling both the delay and the noise
# on an already-failing command. On a per-ref rejection the attempts were
# not spent, but the answer was given (#84), so it holds there too.
$self->_release_guard;
return if $ok;
App::karr::Error::user_error(
"Push rejected by the remote. Local refs are intact.\n"
. "The refs above were refused, not lost in transit, so pushing again "
. "would only be refused again." ) if $rejected;
App::karr::Error::user_error(
"Push failed after 3 attempts. Local refs are intact.\n"
. "Run 'karr sync' to retry." );
}
sub _release_guard {
my ($self) = @_;
if ( my $guard = $self->_sync_guard ) {
$guard->done;
$self->_sync_guard(undef);
}
return;
}
1;
__END__
=pod
=encoding UTF-8
=head1 NAME
App::karr::Role::SyncLifecycle - Role providing sync lifecycle with retry and guard insurance
=head1 VERSION
version 0.500
=head1 DESCRIPTION
This role provides C<sync_before> and C<sync_after> methods that wrap Git pull
and push operations with retry logic. C<sync_before> creates a
L<App::karr::SyncGuard> and retains it on the object as insurance: if the
command body dies or croaks before C<sync_after> runs, the guard's DESTROY
pushes with 3 retries. Because the guard is held by the role (not by the
caller), commands may call both methods in void context; C<sync_after>
neutralises the guard so it never pushes twice.
Holding the guard on the command object is also why the CLI cannot rely on
DESTROY alone: L<MooX::Cmd>'s command chain keeps that object alive past
F<bin/karr>'s error handler, so on the die path the guard is only reaped in
global destruction, where pushing is forbidden. F<bin/karr> therefore drains
L<App::karr::SyncGuard/flush_armed> from an C<END> block.
Commands that compose this role must also have a C<store> attribute (provided
by L<App::karr::Role::BoardDiscovery>) with a C<git> accessor.
=head1 METHODS
=head2 sync_before
$self->sync_before;
Pulls refs from remote with up to 3 attempts. Output is retry-only: the first
attempt is silent, retries are announced from attempt 2 ("Pull retry 2 of
3..."), and errors always reach STDERR. C<--quiet> additionally suppresses the
retry announcements but never the errors. Each distinct error is shown once:
neither a repeat of the previous attempt's error nor the message that ends the
command prints it again. Creates a L<App::karr::SyncGuard>,
retains it on the object (so it outlives the call and covers the command body),
and also returns it for callers that want to manage it explicitly. C<sync_after>
clears it on a successful push.
=head2 sync_after
$self->sync_after; # push with up to 3 attempts
Pushes refs to remote with up to 3 attempts, using the same retry-only output
convention as L</sync_before> (silent first attempt, retries announced from
attempt 2, errors always on STDERR, C<--quiet> silencing only the
announcements). It marks the retained guard done and clears it on both
outcomes: after a successful push there is nothing left to insure, and after a
failed one the guard's three attempts have just been spent, so re-running them
from L<App::karr::SyncGuard/flush_armed> would only repeat the failure.
A push the remote I<rejected> per ref (a pre-receive hook, a protected ref)
is not retried at all: the connection worked and the far side gave its answer,
which the error message carries ref by ref.
=head1 SUPPORT
=head2 Issues
Please report bugs and feature requests on GitHub at
L<https://github.com/Getty/karr/issues>.
=head2 IRC
Join C<#langertha> on C<irc.perl.org> or message Getty directly.
=head1 CONTRIBUTING
Contributions are welcome! Please fork the repository and submit a pull request.
=head1 AUTHOR
Torsten Raudssus <getty@cpan.org>
=head1 COPYRIGHT AND LICENSE
( run in 1.533 second using v1.01-cache-2.11-cpan-14f38c9f855 )