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 )