Skip to content

Conversation

@prawilny
Copy link
Collaborator

@prawilny prawilny commented Oct 1, 2021

This change is Reviewable

Copy link
Collaborator Author

@prawilny prawilny left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have little to absolutely no idea how to test it (integration tests?).

Reviewable status: 0 of 1 files reviewed, all discussions resolved (waiting on @dopiera and @mwalkiewicz)

Copy link

@mwalkiewicz mwalkiewicz left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reviewed 1 of 1 files at r1, all commit messages.
Reviewable status: all files reviewed, 3 unresolved discussions (waiting on @dopiera and @prawilny)


bigtable-hbase-mirroring-client-2.x-parent/bigtable-hbase-mirroring-client-2.x/src/main/java/com/google/cloud/bigtable/mirroring/hbase2_x/MirroringAsyncConnection.java, line 183 at r1 (raw file):

    @Override
    public AsyncTable<C> build() {
      return new MirroringAsyncTable(

MirroringAsyncTable -> MirroringAsyncTable<C>? I would assume that Intelij warns about this with light yellow background - if contrast is a problem and you can't notice it maybe setting high contrast theme will help you.


bigtable-hbase-mirroring-client-2.x-parent/bigtable-hbase-mirroring-client-2.x/src/main/java/com/google/cloud/bigtable/mirroring/hbase2_x/MirroringAsyncConnection.java, line 193 at r1 (raw file):

    private AsyncTableBuilder<C> setTime(
        long l,

Autogenerated ls and is are the best names, you can steal better names from documentation.


bigtable-hbase-mirroring-client-2.x-parent/bigtable-hbase-mirroring-client-2.x/src/main/java/com/google/cloud/bigtable/mirroring/hbase2_x/MirroringAsyncConnection.java, line 197 at r1 (raw file):

        BiFunction<Long, TimeUnit, AsyncTableBuilder<C>> primaryFunction,
        BiFunction<Long, TimeUnit, AsyncTableBuilder<C>> secondaryFunction) {
      return new MirroringAsyncTableBuilder<>(

Add a comment why you are doing that.

@prawilny prawilny changed the base branch from master to ac/increment-append-as-put October 1, 2021 15:28
Copy link

@mwalkiewicz mwalkiewicz left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reviewed 4 of 4 files at r2, 4 of 4 files at r3, all commit messages.
Reviewable status: all files reviewed, 7 unresolved discussions (waiting on @dopiera and @prawilny)


bigtable-hbase-mirroring-client-2.x-parent/bigtable-hbase-mirroring-client-2.x/src/main/java/com/google/cloud/bigtable/mirroring/hbase2_x/MirroringAsyncTable.java, line 132 at r2 (raw file):

        new MirroringTable.WriteOperationInfo(append),
        this.primaryTable.append(append),
        (put) -> this.secondaryWriteErrorConsumer.consume(HBaseOperation.APPEND, put));

We are performing a put on a secondary database, we should report PUT here.

This callback can be created inside mutationAsPut.


bigtable-hbase-mirroring-client-2.x-parent/bigtable-hbase-mirroring-client-2.x/src/main/java/com/google/cloud/bigtable/mirroring/hbase2_x/MirroringAsyncTable.java, line 341 at r2 (raw file):

              @Override
              public void onFailure(Throwable throwable) {
                secondaryWriteErrorHandler.run();

Isn't this change part of a different PR?


bigtable-hbase-mirroring-client-2.x-parent/bigtable-hbase-mirroring-client-2.x/src/test/java/com/google/cloud/bigtable/mirroring/hbase2_x/TestMirroringAsyncTable.java, line 591 at r2 (raw file):

  }

  private void assertPutsAreEqual(Put expectedPut, Put value) {

Honestly, can't we extract this to a helper class in 1.x and then add a dependency to 1.x tests?


bigtable-hbase-mirroring-client-2.x-parent/bigtable-hbase-mirroring-client-2.x/src/test/java/com/google/cloud/bigtable/mirroring/hbase2_x/TestMirroringAsyncTable.java, line 635 at r2 (raw file):

    ArgumentCaptor<Put> argument = ArgumentCaptor.forClass(Put.class);
    verify(secondaryTable, never()).increment(any(Increment.class));
    verify(secondaryTable, times(3)).put(argument.capture());

Do we need to check every argument explicitly using argument captor? we can just use ...put(expectedPut) here and times(3) will make sure that we have used this values three times.

@prawilny prawilny force-pushed the ac/increment-append-as-put branch from 8a66cfb to edc6993 Compare October 5, 2021 17:14
Copy link
Collaborator Author

@prawilny prawilny left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reviewable status: all files reviewed, 7 unresolved discussions (waiting on @dopiera and @mwalkiewicz)


bigtable-hbase-mirroring-client-2.x-parent/bigtable-hbase-mirroring-client-2.x/src/main/java/com/google/cloud/bigtable/mirroring/hbase2_x/MirroringAsyncConnection.java, line 183 at r1 (raw file):

Previously, mwalkiewicz (Mateusz Walkiewicz) wrote…

MirroringAsyncTable -> MirroringAsyncTable<C>? I would assume that Intelij warns about this with light yellow background - if contrast is a problem and you can't notice it maybe setting high contrast theme will help you.

Done.
Thanks for care - I can see them, just got used to the fact that some code is usually highlighted with some pointless suggestion. Will care about them a lot more from now on.


bigtable-hbase-mirroring-client-2.x-parent/bigtable-hbase-mirroring-client-2.x/src/main/java/com/google/cloud/bigtable/mirroring/hbase2_x/MirroringAsyncConnection.java, line 193 at r1 (raw file):

Previously, mwalkiewicz (Mateusz Walkiewicz) wrote…

Autogenerated ls and is are the best names, you can steal better names from documentation.

I feel rather embarassed - I thought I took these from the docs.


bigtable-hbase-mirroring-client-2.x-parent/bigtable-hbase-mirroring-client-2.x/src/main/java/com/google/cloud/bigtable/mirroring/hbase2_x/MirroringAsyncConnection.java, line 197 at r1 (raw file):

Previously, mwalkiewicz (Mateusz Walkiewicz) wrote…

Add a comment why you are doing that.

Done.


bigtable-hbase-mirroring-client-2.x-parent/bigtable-hbase-mirroring-client-2.x/src/main/java/com/google/cloud/bigtable/mirroring/hbase2_x/MirroringAsyncTable.java, line 132 at r2 (raw file):

Previously, mwalkiewicz (Mateusz Walkiewicz) wrote…

We are performing a put on a secondary database, we should report PUT here.

This callback can be created inside mutationAsPut.

Irrelevant. Messed up relations between branches and this is a change from another PR.


bigtable-hbase-mirroring-client-2.x-parent/bigtable-hbase-mirroring-client-2.x/src/main/java/com/google/cloud/bigtable/mirroring/hbase2_x/MirroringAsyncTable.java, line 341 at r2 (raw file):

Previously, mwalkiewicz (Mateusz Walkiewicz) wrote…

Isn't this change part of a different PR?

Irrelevant. Messed up relations between branches and this is a change from another PR.


bigtable-hbase-mirroring-client-2.x-parent/bigtable-hbase-mirroring-client-2.x/src/test/java/com/google/cloud/bigtable/mirroring/hbase2_x/TestMirroringAsyncTable.java, line 591 at r2 (raw file):

Previously, mwalkiewicz (Mateusz Walkiewicz) wrote…

Honestly, can't we extract this to a helper class in 1.x and then add a dependency to 1.x tests?

Responded in another PR (branch ac/increment-append-as-put)


bigtable-hbase-mirroring-client-2.x-parent/bigtable-hbase-mirroring-client-2.x/src/test/java/com/google/cloud/bigtable/mirroring/hbase2_x/TestMirroringAsyncTable.java, line 635 at r2 (raw file):

Previously, mwalkiewicz (Mateusz Walkiewicz) wrote…

Do we need to check every argument explicitly using argument captor? we can just use ...put(expectedPut) here and times(3) will make sure that we have used this values three times.

Responded in another PR (branch ac/increment-append-as-put)

@prawilny prawilny changed the base branch from ac/increment-append-as-put to master October 5, 2021 17:34
@prawilny prawilny requested a review from mwalkiewicz October 5, 2021 18:06
Copy link

@mwalkiewicz mwalkiewicz left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reviewed 5 of 5 files at r4, all commit messages.
Reviewable status: all files reviewed, 1 unresolved discussion (waiting on @dopiera and @prawilny)


bigtable-hbase-mirroring-client-2.x-parent/bigtable-hbase-mirroring-client-2.x/src/main/java/com/google/cloud/bigtable/mirroring/hbase2_x/MirroringAsyncConnection.java, line 219 at r4 (raw file):

    @Override
    public AsyncTableBuilder<C> setOperationTimeout(long l, TimeUnit timeUnit) {

ls and is are still present in those methods.

Copy link
Collaborator Author

@prawilny prawilny left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reviewable status: 4 of 5 files reviewed, 1 unresolved discussion (waiting on @dopiera and @mwalkiewicz)


bigtable-hbase-mirroring-client-2.x-parent/bigtable-hbase-mirroring-client-2.x/src/main/java/com/google/cloud/bigtable/mirroring/hbase2_x/MirroringAsyncConnection.java, line 219 at r4 (raw file):

Previously, mwalkiewicz (Mateusz Walkiewicz) wrote…

ls and is are still present in those methods.

Done.

@prawilny prawilny requested a review from mwalkiewicz October 6, 2021 12:31
mwalkiewicz
mwalkiewicz previously approved these changes Oct 8, 2021
Copy link

@mwalkiewicz mwalkiewicz left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reviewed 1 of 1 files at r5, all commit messages.
Reviewable status: :shipit: complete! all files reviewed, all discussions resolved (waiting on @dopiera)

@prawilny prawilny changed the base branch from master to ac/refcounting October 12, 2021 16:23
@prawilny prawilny requested a review from mwalkiewicz October 12, 2021 16:23
mwalkiewicz
mwalkiewicz previously approved these changes Oct 13, 2021
Copy link

@mwalkiewicz mwalkiewicz left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reviewed 1 of 1 files at r6, all commit messages.
Reviewable status: :shipit: complete! all files reviewed, all discussions resolved (waiting on @dopiera)

Copy link

@dopiera dopiera left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reviewable status: all files reviewed, 1 unresolved discussion (waiting on @prawilny)


bigtable-hbase-mirroring-client-2.x-parent/bigtable-hbase-mirroring-client-2.x/src/main/java/com/google/cloud/bigtable/mirroring/hbase2_x/MirroringAsyncConnection.java, line 219 at r6 (raw file):

        BiFunction<Long, TimeUnit, AsyncTableBuilder<C>> secondaryFunction) {
      /**
       * The documentation doesn't guarantee that the returned object is the object whose method is

Even though the docs don't guarantee it, I think it's idiomatic enough to expect it to work, so I think we should rewrite these to return this.

@prawilny prawilny force-pushed the ac/refcounting branch 2 times, most recently from 372fc07 to 1f6d43a Compare October 13, 2021 16:33
Copy link
Collaborator Author

@prawilny prawilny left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reviewable status: 2 of 5 files reviewed, 1 unresolved discussion (waiting on @dopiera and @mwalkiewicz)


bigtable-hbase-mirroring-client-2.x-parent/bigtable-hbase-mirroring-client-2.x/src/main/java/com/google/cloud/bigtable/mirroring/hbase2_x/MirroringAsyncConnection.java, line 219 at r6 (raw file):

Previously, dopiera (Marek Dopiera) wrote…

Even though the docs don't guarantee it, I think it's idiomatic enough to expect it to work, so I think we should rewrite these to return this.

Done.

@prawilny prawilny requested a review from dopiera October 13, 2021 17:03
dopiera
dopiera previously approved these changes Oct 14, 2021
Copy link

@dopiera dopiera left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reviewed 3 of 3 files at r7, all commit messages.
Reviewable status: all files reviewed, 1 unresolved discussion (waiting on @dopiera)

@prawilny prawilny force-pushed the ac/refcounting branch 4 times, most recently from aa04629 to a6a619f Compare October 15, 2021 14:25
@prawilny prawilny changed the base branch from ac/refcounting to master October 15, 2021 14:42
@prawilny prawilny dismissed stale reviews from dopiera and mwalkiewicz October 15, 2021 14:42

The base branch was changed.

Copy link

@mwalkiewicz mwalkiewicz left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reviewed 3 of 3 files at r8, all commit messages.
Reviewable status: all files reviewed, 1 unresolved discussion (waiting on @dopiera)

@prawilny prawilny merged commit cc0e408 into master Oct 15, 2021
@prawilny prawilny deleted the ac/Builders/1 branch November 2, 2021 14:00
dopiera pushed a commit that referenced this pull request May 11, 2022
dopiera added a commit that referenced this pull request May 11, 2022
* Initial implementation of hbase1.x Mirroring Client (#1)

* Initial implementation of hbase1.x Mirroring Client

* MirroringTable and AsyncTableWrapper (#4)

* MirroringTable and AsyncTableWrapper

- Initial implementation of MirroringTable.
- Wrapper around HBase 1.x Table enabling scheduling asynchronous operations.
- Asynchronous verification of get/exists results.

* Add missing licence header to TestResultComparator (#6)

* Setup running tests in GitHub Actions (#7)

* Asynchronous ResultScanner (#5)

* Asynchronous ResultScanner

* Implement faillog.Appender (#2)

`faillog.Appender` is the lowermost component of the infrastructure for
dumping failed mutations in the `MirroringClient`. `faillog/README.md`
explains the design decisions in a bit more detail.

`faillog.Appender` essentially logs arbitrary data asynchronously,
through a separate thread reading from a bounded buffer.

* ListenableReferenceCounter (#8)

* Count references in asynchronous tasks before closing Table/Scanner.

* Flow controller (#10)

* Flow Controller
* Flow Control strategy based on single requests queue

* Mirroring table: writes (#12)

* Add missing condition in result comparator (#15)

* Add more mirroring config opitons (#16)

* MismatchDetector implementation.
* FlowControllerStrategy implementation.
* Maximal number of outstanding requests used by FlowControllerStrategy.
* Primary/Secondary connection implementation option now accepts
  "default" value which can be used when default HBase Connection
  implementation should be used by MirroringConnection.

* Make AsyncTableWrapper ListenableCloseable (#20)

Implements our standard interface for objects that can run callbacks
after asynchronous close to simplify reference counting of
MirroringTable.

* MirroringConnection: use new config options (#17)

* MirroringResultScanner improvements (#18)

* Count references to MirroringResultScanner

Current implementation of MirroringResultScanner doesn't count
verificaiton requests that it has scheduled and allows to close
instances while verificaiton requests are in-flight. This causes lost
verifications.

This PR fixes this issue by counting references to MirroringResultScanner
instances when scheduling verification requests. Moreover, ListenableClosable
interface is implemented for consistency with other classes that use this
scheme, because now the MirroringResultScanner instances will be closed
asynchronously, when all scheduled requests have finished.

* MirroringTable: count references to scanners and secondary wrapper (#21)

Current MirroringTable implementaion does not count its references held
by MirroringResultScanners and SecondaryAsyncWrapper, thus
MirroringConnection consideres it closed before we are sure that all
asynchronous operations have completed.

This PR adds correct reference counting of MirroringTable based on work
done in previously merged PRs.

* Result Scanner - ensure verification ordering (#22)

Current implementation assumes that next() operations on primary and
secondary scanners are called in the same order and uses this assumption
to match results for verification.

However, next()s on secondary database are called asynchronusly and
their order is not defined, which causes invalid mismatch reports.

This PR fixes this problem by placing data to be verified - results of
next()s called on primary scanner - and details of next() call - number
of requested elements - call on a queue. Each asynchronous call to
next() is synchonized and pops a single element from that queue.
Appropriate next is called based on number of requested elements.
Then results of that request and results from the queue are verified.
This ensures that results of next()s passed to verification are
correctly matched and ordered.

* Integration tests (#23)

HBase 1.x integration tests

* Add trace logging. (#24)

* Estimate memory overhead in RequestResourceDescription (#25)

* Tests: extract executor service to TestRule (#26)

Extract executor service utilities into TestRule to facilitate code
reuse in other test classes.

* Integration tests: read configuration from xml files

* MirroringBufferedMutator

* MirroringBufferedMutator: integration tests (#9)

* Fix error introduced in rebase (#11)

* Obtain resource reservation before scheduling secondary calls (#4)

Fixes a bug when secondary database request Future was created before obtaining resources from FlowController.

* Integration tests - MirroringTable operations (#10)

* MirroringAsyncConfiguration (#5)

Add configuration class to be used by MirroringAsyncConnection.

* SecondaryWriteErrorConsumer in MirroringTable (#15)

Use SecondaryWriteErrorConsumer to handle write errors in secondary database in MirroringTable's writes.

* Use Put to implement Increment and Append (#16)

* refactor: extract functions using reflection into package utils.reflection

* refactor: extract BatchHelpers into utils

Extract common part of batch() helpers into a class and add Predicate argument to nested classes' constructors making it possible to reuse the code in 2.x client.

* feat: Initial implementation of a subset of asynchronous HBase 2.x Mirroring Client

Contains basic implementation of MirroringAsyncConnection and MirroringAsyncTable.

* refactor: extract FlowController's request cancellation into a method

* fix: Increment ITs fail with Bigtable as primary (#21)

We were setting timerange on Increment objects used in integration tests
without any reason and Bigtable doesn't support this operation. Setting
timerange in ITs was removed.

* fix: RequestScheduling should handle rejected resource reservations (#24)

Custom FlowControlerStrategy implementations might, contrary to the
default implementation, resolve reservation requests with exception,
what we should handle by not performing the action that had to acquire
the resources.

* feat: Add OpenCensus tracing and metrics. (#14)

* fix: make BatchHelpers skip verification of empty read results

BatchHelpers provides error handling of batch() when there may be some partial results.
Before the commit, matching successful reads were redundantly verified if there were none of them.
This commit brings back the behaviour from up to 5a29253: when there are no successful matching reads, a MismatchDetector isn't called on empty arrays.

* refactor: make MirroringAsync{Connection,Table} use SecondaryWriteErrorConsumerWithMetrics

BatchHelpers require using SecondaryWriteErrorConsumerWithMetrics API.

* refactor: make AsyncRequestScheduling accept CompletableFuture<ResourceReservation> instead of ResourceReservation

This change is split off from commit introducing MirroringAsyncTable#batch()

* feat: implement batch() in MirroringAsyncTable

Implementation of MirroringAsyncTable's batch() and
MirroringAsyncTable's methods such as get(List<Get) and put(List<Put>) using it.

* feat: implement failed mutations log (#19)

Failed secondary mutations are written to disk in JSON format, which the user can parse programmatically or inspect visually.

Each failure is logged as a separate line, which makes it compatible with solutions like logstash.

* refactor: split SplitBatchResponse (#40)

SplitBatchResponse was refactored into two parts: splitting into
reads/writes and failed/successful. This makes the code simpler and
easier to maintain.

* refactor: extract helper methods in tests (#48)

* refactor: remove redundant writeWithControlFlow argument

* feat: copy HBase operations' input lists (#57)

* refactor: remove redundant field from MirroringConnection (#55)

* feat: verification with sampling (#28)

* fix: mirror Increment/Append in batch() using Put. (#47)

* refactor: Move HBaseOperation into WriteOperationInfo (#68)

* refactor: remove redundant parameter from scheduleWriteWithControlFlow (#69)

* fix: integration tests - fix build (#70)

* fix: count references to batch operations (#63)

* fix: close underlying connections when MirroringConnection is closed (#49)

* refactor: fix IDE warnings in MirroringAsyncTable test (#64)

* fix: integration tests - check if write errors were reported (#71)

* feat: make SecondaryWriteErrorConsumer accept error cause and operation (#65)

* fix: do not call callbacks with lock held (#53)

* refactor: use AccumulatedExceptions where appropriate (#54)

* fix: fix key used in verification sampling ITs (#77)

* feat: use faillog for handling write errors (#66)

* refactor: add utilities for Futures (FutureUtils)

* feat: defer closing connections until async operations complete (#37)

Mirroring client schedules asynchronous operations - to mirror the mutations and to verify reads. Before this PR, closing the MirroringAsyncConnection would result in closing the underlying connections immediately. This made the pending asynchronous operations fail. This PR defers closing the underlying connections until all pending operations complete. It is achieved by reference counting the operations.

* feat: implement AsyncTableBuilder (#42)

* feat: implement MirroringAsyncTable#checkAndMutate (#43)

* fix: Implement single Append and Increment as Put (#38)

* refactor: simplify SecondaryWriteErrorConsumer API (#78)

* feat: concurrent writes in MirroringTable (#79)

* test: fix failing concurrent write test (#120)

* refactor: renames and moves in RequestScheduling (#87)

* wip: handover session comments

Co-authored-by: Mateusz Walkiewicz <mwalkiewicz@unoperate.com>
Co-authored-by: Adam Czajkowski <prawilny@unoperate.com>
mwalkiewicz added a commit that referenced this pull request May 18, 2022
* Initial implementation of hbase1.x Mirroring Client (#1)

* Initial implementation of hbase1.x Mirroring Client

* MirroringTable and AsyncTableWrapper (#4)

* MirroringTable and AsyncTableWrapper

- Initial implementation of MirroringTable.
- Wrapper around HBase 1.x Table enabling scheduling asynchronous operations.
- Asynchronous verification of get/exists results.

* Add missing licence header to TestResultComparator (#6)

* Setup running tests in GitHub Actions (#7)

* Asynchronous ResultScanner (#5)

* Asynchronous ResultScanner

* Implement faillog.Appender (#2)

`faillog.Appender` is the lowermost component of the infrastructure for
dumping failed mutations in the `MirroringClient`. `faillog/README.md`
explains the design decisions in a bit more detail.

`faillog.Appender` essentially logs arbitrary data asynchronously,
through a separate thread reading from a bounded buffer.

* ListenableReferenceCounter (#8)

* Count references in asynchronous tasks before closing Table/Scanner.

* Flow controller (#10)

* Flow Controller
* Flow Control strategy based on single requests queue

* Mirroring table: writes (#12)

* Add missing condition in result comparator (#15)

* Add more mirroring config opitons (#16)

* MismatchDetector implementation.
* FlowControllerStrategy implementation.
* Maximal number of outstanding requests used by FlowControllerStrategy.
* Primary/Secondary connection implementation option now accepts
  "default" value which can be used when default HBase Connection
  implementation should be used by MirroringConnection.

* Make AsyncTableWrapper ListenableCloseable (#20)

Implements our standard interface for objects that can run callbacks
after asynchronous close to simplify reference counting of
MirroringTable.

* MirroringConnection: use new config options (#17)

* MirroringResultScanner improvements (#18)

* Count references to MirroringResultScanner

Current implementation of MirroringResultScanner doesn't count
verificaiton requests that it has scheduled and allows to close
instances while verificaiton requests are in-flight. This causes lost
verifications.

This PR fixes this issue by counting references to MirroringResultScanner
instances when scheduling verification requests. Moreover, ListenableClosable
interface is implemented for consistency with other classes that use this
scheme, because now the MirroringResultScanner instances will be closed
asynchronously, when all scheduled requests have finished.

* MirroringTable: count references to scanners and secondary wrapper (#21)

Current MirroringTable implementaion does not count its references held
by MirroringResultScanners and SecondaryAsyncWrapper, thus
MirroringConnection consideres it closed before we are sure that all
asynchronous operations have completed.

This PR adds correct reference counting of MirroringTable based on work
done in previously merged PRs.

* Result Scanner - ensure verification ordering (#22)

Current implementation assumes that next() operations on primary and
secondary scanners are called in the same order and uses this assumption
to match results for verification.

However, next()s on secondary database are called asynchronusly and
their order is not defined, which causes invalid mismatch reports.

This PR fixes this problem by placing data to be verified - results of
next()s called on primary scanner - and details of next() call - number
of requested elements - call on a queue. Each asynchronous call to
next() is synchonized and pops a single element from that queue.
Appropriate next is called based on number of requested elements.
Then results of that request and results from the queue are verified.
This ensures that results of next()s passed to verification are
correctly matched and ordered.

* Integration tests (#23)

HBase 1.x integration tests

* Add trace logging. (#24)

* Estimate memory overhead in RequestResourceDescription (#25)

* Tests: extract executor service to TestRule (#26)

Extract executor service utilities into TestRule to facilitate code
reuse in other test classes.

* Integration tests: read configuration from xml files

* MirroringBufferedMutator

* MirroringBufferedMutator: integration tests (#9)

* Fix error introduced in rebase (#11)

* Obtain resource reservation before scheduling secondary calls (#4)

Fixes a bug when secondary database request Future was created before obtaining resources from FlowController.

* Integration tests - MirroringTable operations (#10)

* MirroringAsyncConfiguration (#5)

Add configuration class to be used by MirroringAsyncConnection.

* SecondaryWriteErrorConsumer in MirroringTable (#15)

Use SecondaryWriteErrorConsumer to handle write errors in secondary database in MirroringTable's writes.

* Use Put to implement Increment and Append (#16)

* refactor: extract functions using reflection into package utils.reflection

* refactor: extract BatchHelpers into utils

Extract common part of batch() helpers into a class and add Predicate argument to nested classes' constructors making it possible to reuse the code in 2.x client.

* feat: Initial implementation of a subset of asynchronous HBase 2.x Mirroring Client

Contains basic implementation of MirroringAsyncConnection and MirroringAsyncTable.

* refactor: extract FlowController's request cancellation into a method

* fix: Increment ITs fail with Bigtable as primary (#21)

We were setting timerange on Increment objects used in integration tests
without any reason and Bigtable doesn't support this operation. Setting
timerange in ITs was removed.

* fix: RequestScheduling should handle rejected resource reservations (#24)

Custom FlowControlerStrategy implementations might, contrary to the
default implementation, resolve reservation requests with exception,
what we should handle by not performing the action that had to acquire
the resources.

* feat: Add OpenCensus tracing and metrics. (#14)

* fix: make BatchHelpers skip verification of empty read results

BatchHelpers provides error handling of batch() when there may be some partial results.
Before the commit, matching successful reads were redundantly verified if there were none of them.
This commit brings back the behaviour from up to 5a29253: when there are no successful matching reads, a MismatchDetector isn't called on empty arrays.

* refactor: make MirroringAsync{Connection,Table} use SecondaryWriteErrorConsumerWithMetrics

BatchHelpers require using SecondaryWriteErrorConsumerWithMetrics API.

* refactor: make AsyncRequestScheduling accept CompletableFuture<ResourceReservation> instead of ResourceReservation

This change is split off from commit introducing MirroringAsyncTable#batch()

* feat: implement batch() in MirroringAsyncTable

Implementation of MirroringAsyncTable's batch() and
MirroringAsyncTable's methods such as get(List<Get) and put(List<Put>) using it.

* feat: implement failed mutations log (#19)

Failed secondary mutations are written to disk in JSON format, which the user can parse programmatically or inspect visually.

Each failure is logged as a separate line, which makes it compatible with solutions like logstash.

* refactor: split SplitBatchResponse (#40)

SplitBatchResponse was refactored into two parts: splitting into
reads/writes and failed/successful. This makes the code simpler and
easier to maintain.

* refactor: extract helper methods in tests (#48)

* refactor: remove redundant writeWithControlFlow argument

* feat: copy HBase operations' input lists (#57)

* refactor: remove redundant field from MirroringConnection (#55)

* feat: verification with sampling (#28)

* fix: mirror Increment/Append in batch() using Put. (#47)

* refactor: Move HBaseOperation into WriteOperationInfo (#68)

* refactor: remove redundant parameter from scheduleWriteWithControlFlow (#69)

* fix: integration tests - fix build (#70)

* fix: count references to batch operations (#63)

* fix: close underlying connections when MirroringConnection is closed (#49)

* refactor: fix IDE warnings in MirroringAsyncTable test (#64)

* fix: integration tests - check if write errors were reported (#71)

* feat: make SecondaryWriteErrorConsumer accept error cause and operation (#65)

* fix: do not call callbacks with lock held (#53)

* refactor: use AccumulatedExceptions where appropriate (#54)

* fix: fix key used in verification sampling ITs (#77)

* feat: use faillog for handling write errors (#66)

* refactor: add utilities for Futures (FutureUtils)

* feat: defer closing connections until async operations complete (#37)

Mirroring client schedules asynchronous operations - to mirror the mutations and to verify reads. Before this PR, closing the MirroringAsyncConnection would result in closing the underlying connections immediately. This made the pending asynchronous operations fail. This PR defers closing the underlying connections until all pending operations complete. It is achieved by reference counting the operations.

* feat: implement AsyncTableBuilder (#42)

* feat: implement MirroringAsyncTable#checkAndMutate (#43)

* fix: Implement single Append and Increment as Put (#38)

* refactor: simplify SecondaryWriteErrorConsumer API (#78)

* feat: concurrent writes in MirroringTable (#79)

* test: fix failing concurrent write test (#120)

* refactor: renames and moves in RequestScheduling (#87)

* wip: handover session comments

Co-authored-by: Mateusz Walkiewicz <mwalkiewicz@unoperate.com>
Co-authored-by: Adam Czajkowski <prawilny@unoperate.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants