[ 
https://issues.apache.org/jira/browse/IGNITE-20127?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel
 ]

Alexander Lapin updated IGNITE-20127:
-------------------------------------
    Description: 
h3. 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.
h3. 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
{code:java}
CompletableFuture<?> result = replica.processRequest(request);

result.handle((res, ex) -> {
        ...
        msg = prepareReplicaResponse(requestTimestamp, res);
        ...

    clusterNetSvc.messagingService().respond(senderConsistentId, msg, 
correlationId); {code}

 * And of course it's required to await all commands replication at once in 
pre-commit. We already have such logic in ReadWriteTransactionImpl#finish
{code:java}
protected CompletableFuture<Void> finish(boolean commit) {
    ...
    CompletableFuture<Void> mainFinishFut = CompletableFuture
            .allOf(enlistedResults.toArray(new CompletableFuture[0]))
            .thenCompose( 
                ...
                return txManager.finish(
                ...{code}
however, it should use not the result from primary, but the replication 
completion one.

h3. 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.

  was:
h3. 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.
h3. 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

{code:java}
CompletableFuture<?> result = replica.processRequest(request);

result.handle((res, ex) -> {
        ...
        msg = prepareReplicaResponse(requestTimestamp, res);
        ...

    clusterNetSvc.messagingService().respond(senderConsistentId, msg, 
correlationId); {code}

 * And of course it's required to await all commands replication at once in 
pre-commit. We already have such logic in ReadWriteTransactionImpl#finish
{code:java}
protected CompletableFuture<Void> finish(boolean commit) {
    ...
    CompletableFuture<Void> mainFinishFut = CompletableFuture
            .allOf(enlistedResults.toArray(new CompletableFuture[0]))
            .thenCompose( 
                ...
                return txManager.finish(
                ...{code}
however, it should use not the result from primary, but the replication 
completion one.

h3. 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.


> Implement 1rtt RW transaction await logic in pre commit
> -------------------------------------------------------
>
>                 Key: IGNITE-20127
>                 URL: https://issues.apache.org/jira/browse/IGNITE-20127
>             Project: Ignite
>          Issue Type: Improvement
>            Reporter: Alexander Lapin
>            Priority: Major
>              Labels: ignite-3, transactions
>
> h3. 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.
> h3. 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
> {code:java}
> CompletableFuture<?> result = replica.processRequest(request);
> result.handle((res, ex) -> {
>         ...
>         msg = prepareReplicaResponse(requestTimestamp, res);
>         ...
>     clusterNetSvc.messagingService().respond(senderConsistentId, msg, 
> correlationId); {code}
>  * And of course it's required to await all commands replication at once in 
> pre-commit. We already have such logic in ReadWriteTransactionImpl#finish
> {code:java}
> protected CompletableFuture<Void> finish(boolean commit) {
>     ...
>     CompletableFuture<Void> mainFinishFut = CompletableFuture
>             .allOf(enlistedResults.toArray(new CompletableFuture[0]))
>             .thenCompose( 
>                 ...
>                 return txManager.finish(
>                 ...{code}
> however, it should use not the result from primary, but the replication 
> completion one.
> h3. 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.



--
This message was sent by Atlassian Jira
(v8.20.10#820010)

Reply via email to