Uploaded image for project: 'Ignite'
  1. Ignite
  2. IGNITE-20127

Implement 1rtt RW transaction await logic in pre commit

    XMLWordPrintableJSON

Details

    • Improvement
    • Status: Resolved
    • Major
    • Resolution: Fixed
    • None
    • None
    • None

    Description

      Motivation

      Our transaction protocol assumes that all required request validations, lock acquisitions and similar activities are performed on a primary replica prior to command replication, meaning that it's not necessary to await replication for every request one by one rather it's required to await them all at once in pre-commit phase. Most of what is required for such all at once await has already been implemented.

      Definition of Done

      • It's required to do the command replication in an async manner, meaning that it's necessary to return the result to the client right after replication is triggered. Currently, we return replication result in PartitionReplicaListener#applyCmdWithExceptionHandling and await it in ReplicaManager#onReplicaMessageReceive
        CompletableFuture<?> result = replica.processRequest(request);
        
        result.handle((res, ex) -> {
                ...
                msg = prepareReplicaResponse(requestTimestamp, res);
                ...
        
            clusterNetSvc.messagingService().respond(senderConsistentId, msg, correlationId); 
      • And of course it's required to await all commands replication at once in pre-commit. We already have such logic in ReadWriteTransactionImpl#finish
        protected CompletableFuture<Void> finish(boolean commit) {
            ...
            CompletableFuture<Void> mainFinishFut = CompletableFuture
                    .allOf(enlistedResults.toArray(new CompletableFuture[0]))
                    .thenCompose( 
                        ...
                        return txManager.finish(
                        ...

        however, it should use not the result from primary, but the replication completion one.

      Implementation Notes

      I believe it's possible to implement it in a following way:

      • ReplicaManager should await only primary related actions like lock acquisition and store the replication future in a sort of map. It's possible to use safeTime as request Id.
      • Transaction should send replicationAwaitRequest in an async manner right after replicationResponse from primary was achieved.
      • enlistedResults should be switched to replicationAwaitResponse.

      Attachments

        Issue Links

          Activity

            People

              ascherbakov Alexey Scherbakov
              alapin Alexander Lapin
              Votes:
              0 Vote for this issue
              Watchers:
              2 Start watching this issue

              Dates

                Created:
                Updated:
                Resolved:

                Time Tracking

                  Estimated:
                  Original Estimate - Not Specified
                  Not Specified
                  Remaining:
                  Remaining Estimate - 0h
                  0h
                  Logged:
                  Time Spent - 8h 20m
                  8h 20m