-
Notifications
You must be signed in to change notification settings - Fork 6
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
24 changed files
with
221 additions
and
99 deletions.
There are no files selected for viewing
This file was deleted.
Oops, something went wrong.
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,4 +1,4 @@ | ||
package dtransaction | ||
package dtx | ||
|
||
type correlationIDType string | ||
|
||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,43 @@ | ||
/* | ||
Package dtx contains common utilities in the context of distributed transaction. | ||
Context Passing | ||
It is curial for all parties in the distributed transaction to share an | ||
transaction id. This package provides utility to pass this id across services. | ||
HTTPToContext() http.RequestFunc | ||
ContextToHTTP() http.RequestFunc | ||
GRPCToContext() grpc.ServerRequestFunc | ||
ContextToGRPC() grpc.ClientRequestFunc | ||
Idempotency | ||
Certain operations will be retried by the client more than once. A middleware is | ||
provided for the server to shield against repeated request in the same | ||
transaction. | ||
func MakeIdempotence(s Oncer) endpoint.Middleware | ||
Lock | ||
Certain resource in transaction cannot be concurrently accessed. A middleware is | ||
provided to lock such resources. | ||
func MakeLock(l Locker) endpoint.Middleware | ||
Allow Null Compensation and Prevent Resource Suspension | ||
Transaction participants may receive the compensation | ||
order before performing normal operations due to network exceptions. In this | ||
case, null compensation is required. | ||
If the forward operation arrives later than the compensating operation due to | ||
network exceptions, the forward operation must be discarded. Otherwise, resource | ||
suspension occurs. | ||
func MakeAttempt(s Sequencer) endpoint.Middleware | ||
func MakeCancel(s Sequencer) endpoint.Middleware | ||
*/ | ||
package dtx |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,4 +1,4 @@ | ||
package dtransaction | ||
package dtx | ||
|
||
import ( | ||
"context" | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,6 +1,6 @@ | ||
// +build integration | ||
|
||
package dtransaction | ||
package dtx | ||
|
||
import ( | ||
"context" | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,91 @@ | ||
/* | ||
Package sagas implements the orchestration based saga pattern. | ||
See https://microservices.io/patterns/data/saga.html | ||
Introduction | ||
A saga is a sequence of local transactions. Each local transaction updates the | ||
database and publishes a message or event to trigger the next local | ||
transaction in the saga. If a local transaction fails because it violates a | ||
business rule then the saga executes a series of compensating transactions | ||
that undo the changes that were made by the preceding local transactions. | ||
Usage | ||
The saga is managed by sagas.Registry. Each saga step has an forward operation | ||
and a rollback counterpart. They must be registered beforehand by calling | ||
Registry.AddStep. A new endpoint will be returned to the caller. Use the | ||
returned endpoint to perform transactional operation. | ||
store := sagas.NewInProcessStore() | ||
registry := sagas.NewRegistry(store) | ||
addOrder := registry.AddStep(&sagas.Step{ | ||
Name: "Add Order", | ||
Do: func(ctx context.Context, request interface{}) (response interface{}, err error) { | ||
resp, err := orderEndpoint(ctx, request.(OrderRequest)) | ||
if err != nil { | ||
return nil, err | ||
} | ||
return resp, nil | ||
}, | ||
Undo: func(ctx context.Context, req interface{}) (response interface{}, err error) { | ||
return orderCancelEndpoint(ctx, req) | ||
}, | ||
}) | ||
makePayment := registry.AddStep(&sagas.Step{ | ||
Name: "Make Payment", | ||
Do: func(ctx context.Context, request interface{}) (response interface{}, err error) { | ||
resp, err := paymentEndpoint(ctx, request.(PaymentRequest)) | ||
if err != nil { | ||
return nil, err | ||
} | ||
return resp, nil | ||
}, | ||
Undo: func(ctx context.Context, req interface{}) (response interface{}, err error) { | ||
return paymentCancelEndpoint(ctx) | ||
}, | ||
}) | ||
Initiate the transaction by calling registry.StartTX. Pass the context returned | ||
to the transaction branches. You can rollback or commit at your will. If the | ||
TX.Rollback is called, the previously registered rollback operations will be | ||
applied automatically, on condition that the forward operation is indeed | ||
executed within the transaction. | ||
tx, ctx := registry.StartTX(context.Background()) | ||
resp, err := addOrder(ctx, OrderRequest{Sku: "1"}) | ||
if err != nil { | ||
tx.Rollback(ctx) | ||
} | ||
resp, err = makePayment(ctx, PaymentRequest{}) | ||
if err != nil { | ||
tx.Rollback(ctx) | ||
} | ||
tx.Commit(ctx) | ||
Integration | ||
The package leader exports configuration in this format: | ||
saga: | ||
sagaTimeoutSecond: 600 | ||
recoverIntervalSecond: 60 | ||
To use package sagas with package core: | ||
var c *core.C = core.Default() | ||
c.Provide(sagas.Providers) | ||
c.Invoke(func(registry *sagas.Registry) { | ||
tx, ctx := registry.StartTX(context.Background()) | ||
resp, err := addOrder(ctx, OrderRequest{Sku: "1"}) | ||
if err != nil { | ||
tx.Rollback(ctx) | ||
} | ||
resp, err = makePayment(ctx, PaymentRequest{}) | ||
if err != nil { | ||
tx.Rollback(ctx) | ||
} | ||
tx.Commit(ctx) | ||
}) | ||
*/ | ||
package sagas |
Oops, something went wrong.