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 )