App-SD

 view release on metacpan or  search on metacpan

lib/App/SD/ForeignReplica.pm  view on Meta::CPAN

=head2 integrate_change $change $changeset

Given a change (and the changeset it's part of), this routine will load
the push encoder for the foreign replica's type and call integrate_change
on it.

To avoid publishing prophet-private data, It skips any change with a record type
that record_type starts with '__'.

This is probably a bug.

=cut

sub integrate_change {
    my $self = shift;
    my ( $change, $changeset ) = validate_pos(
        @_,
        { isa => 'Prophet::Change' },
        { isa => 'Prophet::ChangeSet' },
    );

    # don't push internal records
    return if $change->record_type =~ /^__/;


    Prophet::App->require( $self->push_encoder());
    my $recoder = $self->push_encoder->new( { sync_source => $self } );
    $recoder->integrate_change($change,$changeset);
}

=head2 record_pushed_transactions

Walk the set of transactions on the ticket whose id you've passed in, looking
for updates by the 'current user' which happened after start_time and before
now. Then mark those transactions as ones that originated in SD, so we don't
accidentally push them later.

=over

=item ticket

=item changeset

=item start_time

=back

=cut

sub record_pushed_transactions {
    my $self = shift;
    my %args = validate( @_,
        { ticket => 1,
          changeset => { isa => 'Prophet::ChangeSet' }, start_time => 1} );

    my $earliest_valid_txn_date;

    # walk through every transaction on the ticket, starting with the latest

    for my $txn ( $self->get_txn_list_by_date($args{ticket}) ) {
        # walk backwards through all transactions on the ticket we just updated
        # Skip any transaction where the remote user isn't me, this might
        # include any transaction RT created with a scrip on your behalf

        next unless $txn->{creator} eq $self->foreign_username;

        # get the completion time _after_ we do our next round trip to rt to
        # try to make sure a bit of lag doesn't skew us to the wrong side of a
        # 1s boundary
       if (!$earliest_valid_txn_date){
            my $change_window =  time() - $args{start_time};
            # skip any transaction created more than 5 seconds before the push
            # started. I can't think of any reason that number shouldn't be 1,
            # but clocks are fickle
            $earliest_valid_txn_date = $txn->{created} - ($change_window + 5);
        }

        last if $txn->{created} < $earliest_valid_txn_date;

        # if the transaction id is older than the id of the last changeset
        # we got from the original source of this changeset, we're done
        last if $txn->{id} <= $self->app_handle->handle->last_changeset_from_source(
           $args{changeset}->original_source_uuid);

        # if the transaction from RT is more recent than the most recent
        # transaction we got from the original source of the changeset
        # then we should record that we sent that transaction upstream

        $self->record_pushed_transaction(
            transaction => $txn->{id},
            changeset   => $args{'changeset'},
            record      => $args{'ticket'}
        );
    }
}


=head2 record_pushed_transaction $foreign_transaction_id, $changeset

Record that this replica was the original source of $foreign_transaction_id
(with changeset $changeset)

=cut

sub record_pushed_transaction {
    my $self = shift;
    my %args = validate( @_,
        { transaction => 1, changeset => { isa => 'Prophet::ChangeSet' },
          record => 1 } );

    my $key = join('-', "foreign-txn-from" , $self->uuid ,
                   'record' , $args{record} , 'txn' , $args{transaction} );
    my $value = join(':', $args{changeset}->original_source_uuid,
                     $args{changeset}->original_sequence_no );

    $self->store_local_metadata($key => $value);

}

=head2 foreign_transaction_originated_locally $transaction_id $foreign_record_id



( run in 2.644 seconds using v1.01-cache-2.11-cpan-39bf76dae61 )