diff --git a/deployments/pulumi/go.mod b/deployments/pulumi/go.mod index 078ac05a01..b00ff9f847 100644 --- a/deployments/pulumi/go.mod +++ b/deployments/pulumi/go.mod @@ -5,7 +5,7 @@ go 1.23.1 toolchain go1.23.3 require ( - github.com/formancehq/go-libs/v3 v3.0.0-20250407102820-68fa020e67bb + github.com/formancehq/go-libs/v3 v3.0.0-20250422113236-ec98813a1539 github.com/google/uuid v1.6.0 github.com/invopop/jsonschema v0.13.0 github.com/kos-v/dsnparser v1.1.0 diff --git a/deployments/pulumi/go.sum b/deployments/pulumi/go.sum index c067398b83..842801d690 100644 --- a/deployments/pulumi/go.sum +++ b/deployments/pulumi/go.sum @@ -146,8 +146,8 @@ github.com/fatih/color v1.18.0 h1:S8gINlzdQ840/4pfAwic/ZE0djQEH3wM94VfqLTZcOM= github.com/fatih/color v1.18.0/go.mod h1:4FelSpRwEGDpQ12mAdzqdOukCy4u8WUtOY6lkT/6HfU= github.com/felixge/httpsnoop v1.0.4 h1:NFTV2Zj1bL4mc9sqWACXbQFVBBg2W3GPvqp8/ESS2Wg= github.com/felixge/httpsnoop v1.0.4/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U= -github.com/formancehq/go-libs/v3 v3.0.0-20250407102820-68fa020e67bb h1:bX/OQdZJryJlOzc1Ao8mMKg1kV9qSmmJ1aHxv5N71HE= -github.com/formancehq/go-libs/v3 v3.0.0-20250407102820-68fa020e67bb/go.mod h1:mRr5/y0I64iJ4I+BXNkUy49izwrh3SA5L+MTWD1d/7Q= +github.com/formancehq/go-libs/v3 v3.0.0-20250422113236-ec98813a1539 h1:6kUkmD2GiZGB7TDpGaPas2ipaAKqP/os3PVk4XFVrpI= +github.com/formancehq/go-libs/v3 v3.0.0-20250422113236-ec98813a1539/go.mod h1:mRr5/y0I64iJ4I+BXNkUy49izwrh3SA5L+MTWD1d/7Q= github.com/gliderlabs/ssh v0.3.8 h1:a4YXD1V7xMF9g5nTkdfnja3Sxy1PVDCj1Zg4Wb8vY6c= github.com/gliderlabs/ssh v0.3.8/go.mod h1:xYoytBv1sV0aL3CavoDuJIQNURXkkfPA/wxQ1pL1fAU= github.com/go-git/gcfg v1.5.1-0.20230307220236-3a3c6141e376 h1:+zs/tPmkDkHx3U66DAb0lQFJrpS6731Oaa12ikc+DiI= diff --git a/go.mod b/go.mod index b0c567948f..977999f904 100644 --- a/go.mod +++ b/go.mod @@ -50,7 +50,7 @@ require ( ) require ( - github.com/formancehq/go-libs/v3 v3.0.0-20250408113106-7b3525e0b25b + github.com/formancehq/go-libs/v3 v3.0.0-20250422113236-ec98813a1539 github.com/robfig/cron/v3 v3.0.1 github.com/spf13/viper v1.20.1 gopkg.in/yaml.v3 v3.0.1 diff --git a/go.sum b/go.sum index b298df17a8..934fdd130b 100644 --- a/go.sum +++ b/go.sum @@ -104,8 +104,8 @@ github.com/fatih/color v1.18.0 h1:S8gINlzdQ840/4pfAwic/ZE0djQEH3wM94VfqLTZcOM= github.com/fatih/color v1.18.0/go.mod h1:4FelSpRwEGDpQ12mAdzqdOukCy4u8WUtOY6lkT/6HfU= github.com/felixge/httpsnoop v1.0.4 h1:NFTV2Zj1bL4mc9sqWACXbQFVBBg2W3GPvqp8/ESS2Wg= github.com/felixge/httpsnoop v1.0.4/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U= -github.com/formancehq/go-libs/v3 v3.0.0-20250408113106-7b3525e0b25b h1:EvnYMGyZo+fq9fsrraedKBlVTbeE2mqpJ/edj8FRTtU= -github.com/formancehq/go-libs/v3 v3.0.0-20250408113106-7b3525e0b25b/go.mod h1:mRr5/y0I64iJ4I+BXNkUy49izwrh3SA5L+MTWD1d/7Q= +github.com/formancehq/go-libs/v3 v3.0.0-20250422113236-ec98813a1539 h1:6kUkmD2GiZGB7TDpGaPas2ipaAKqP/os3PVk4XFVrpI= +github.com/formancehq/go-libs/v3 v3.0.0-20250422113236-ec98813a1539/go.mod h1:mRr5/y0I64iJ4I+BXNkUy49izwrh3SA5L+MTWD1d/7Q= github.com/formancehq/numscript v0.0.16 h1:kNNpPTmTvhRUrMXonZPMwUXUpJ06Io1WwC56Yf3nr1E= github.com/formancehq/numscript v0.0.16/go.mod h1:8WhBIqcK6zu27njxy7ZG7CaDX0MHtI9qF9Ggfj07wfU= github.com/fortytw2/leaktest v1.3.0 h1:u8491cBMTQ8ft8aeV+adlcytMZylmA5nnwwkRZjI8vw= diff --git a/internal/controller/ledger/controller_default.go b/internal/controller/ledger/controller_default.go index e9fed1d79c..19f4144988 100644 --- a/internal/controller/ledger/controller_default.go +++ b/internal/controller/ledger/controller_default.go @@ -204,21 +204,40 @@ func (ctrl *DefaultController) Import(ctx context.Context, stream chan ledger.Lo } lastLogID = log.ID - if err := ctrl.importLog(ctx, log); err != nil { - switch { - case errors.Is(err, postgres.ErrSerialization) || - errors.Is(err, ErrConcurrentTransaction{}): - return NewErrImport(errors.New("concurrent transaction occur" + - "red, cannot import the ledger")) + store, _, err := ctrl.store.BeginTX(ctx, nil) + if err != nil { + return fmt.Errorf("starting transaction: %w", err) + } + err = func() error { + defer func() { + _ = store.Rollback() + }() + + if err := ctrl.importLog(ctx, store, log); err != nil { + switch { + case errors.Is(err, postgres.ErrSerialization) || + errors.Is(err, ErrConcurrentTransaction{}): + return NewErrImport(errors.New("concurrent transaction occur" + + "red, cannot import the ledger")) + } + return fmt.Errorf("importing log %d: %w", *log.ID, err) + } + + if err := store.Commit(); err != nil { + return fmt.Errorf("committing transaction: %w", err) } - return fmt.Errorf("importing log %d: %w", *log.ID, err) + + return nil + }() + if err != nil { + return err } } return err } -func (ctrl *DefaultController) importLog(ctx context.Context, log ledger.Log) error { +func (ctrl *DefaultController) importLog(ctx context.Context, store Store, log ledger.Log) error { _, err := tracing.Trace( ctx, ctrl.tracer, @@ -227,13 +246,13 @@ func (ctrl *DefaultController) importLog(ctx context.Context, log ledger.Log) er switch payload := log.Data.(type) { case ledger.CreatedTransaction: logging.FromContext(ctx).Debugf("Importing transaction %d", *payload.Transaction.ID) - if err := ctrl.store.CommitTransaction(ctx, &payload.Transaction, payload.AccountMetadata); err != nil { + if err := store.CommitTransaction(ctx, &payload.Transaction, payload.AccountMetadata); err != nil { return nil, fmt.Errorf("failed to commit transaction: %w", err) } logging.FromContext(ctx).Debugf("Imported transaction %d", *payload.Transaction.ID) case ledger.RevertedTransaction: logging.FromContext(ctx).Debugf("Reverting transaction %d", *payload.RevertedTransaction.ID) - _, _, err := ctrl.store.RevertTransaction( + _, _, err := store.RevertTransaction( ctx, *payload.RevertedTransaction.ID, *payload.RevertedTransaction.RevertedAt, @@ -241,19 +260,19 @@ func (ctrl *DefaultController) importLog(ctx context.Context, log ledger.Log) er if err != nil { return nil, fmt.Errorf("failed to revert transaction: %w", err) } - if err := ctrl.store.CommitTransaction(ctx, &payload.RevertTransaction, nil); err != nil { + if err := store.CommitTransaction(ctx, &payload.RevertTransaction, nil); err != nil { return nil, fmt.Errorf("failed to commit transaction: %w", err) } case ledger.SavedMetadata: switch payload.TargetType { case ledger.MetaTargetTypeTransaction: logging.FromContext(ctx).Debugf("Saving metadata of transaction %d", payload.TargetID) - if _, _, err := ctrl.store.UpdateTransactionMetadata(ctx, payload.TargetID.(uint64), payload.Metadata, log.Date); err != nil { + if _, _, err := store.UpdateTransactionMetadata(ctx, payload.TargetID.(uint64), payload.Metadata, log.Date); err != nil { return nil, fmt.Errorf("failed to update transaction metadata: %w", err) } case ledger.MetaTargetTypeAccount: logging.FromContext(ctx).Debugf("Saving metadata of account %s", payload.TargetID) - if err := ctrl.store.UpdateAccountsMetadata(ctx, ledger.AccountMetadata{ + if err := store.UpdateAccountsMetadata(ctx, ledger.AccountMetadata{ payload.TargetID.(string): payload.Metadata, }); err != nil { return nil, fmt.Errorf("failed to update account metadata: %w", err) @@ -263,12 +282,12 @@ func (ctrl *DefaultController) importLog(ctx context.Context, log ledger.Log) er switch payload.TargetType { case ledger.MetaTargetTypeTransaction: logging.FromContext(ctx).Debugf("Deleting metadata of transaction %d", payload.TargetID) - if _, _, err := ctrl.store.DeleteTransactionMetadata(ctx, payload.TargetID.(uint64), payload.Key, log.Date); err != nil { + if _, _, err := store.DeleteTransactionMetadata(ctx, payload.TargetID.(uint64), payload.Key, log.Date); err != nil { return nil, fmt.Errorf("failed to delete transaction metadata: %w", err) } case ledger.MetaTargetTypeAccount: logging.FromContext(ctx).Debugf("Deleting metadata of account %s", payload.TargetID) - if err := ctrl.store.DeleteAccountMetadata(ctx, payload.TargetID.(string), payload.Key); err != nil { + if err := store.DeleteAccountMetadata(ctx, payload.TargetID.(string), payload.Key); err != nil { return nil, fmt.Errorf("failed to delete account metadata: %w", err) } } @@ -276,7 +295,7 @@ func (ctrl *DefaultController) importLog(ctx context.Context, log ledger.Log) er logCopy := log logging.FromContext(ctx).Debugf("Inserting log %d", *log.ID) - if err := ctrl.store.InsertLog(ctx, &log); err != nil { + if err := store.InsertLog(ctx, &log); err != nil { return nil, fmt.Errorf("failed to insert log: %w", err) } diff --git a/test/rolling-upgrades/go.mod b/test/rolling-upgrades/go.mod index 165b5ff84d..f9f056e4de 100644 --- a/test/rolling-upgrades/go.mod +++ b/test/rolling-upgrades/go.mod @@ -36,7 +36,7 @@ require ( github.com/cyphar/filepath-securejoin v0.3.6 // indirect github.com/djherbis/times v1.5.0 // indirect github.com/emirpasic/gods v1.18.1 // indirect - github.com/formancehq/go-libs/v3 v3.0.0-20250407102820-68fa020e67bb // indirect + github.com/formancehq/go-libs/v3 v3.0.0-20250422113236-ec98813a1539 // indirect github.com/fsnotify/fsnotify v1.6.0 // indirect github.com/go-git/gcfg v1.5.1-0.20230307220236-3a3c6141e376 // indirect github.com/go-git/go-billy/v5 v5.6.1 // indirect diff --git a/test/rolling-upgrades/go.sum b/test/rolling-upgrades/go.sum index 11c2e7cc5e..7a4c5edcc0 100644 --- a/test/rolling-upgrades/go.sum +++ b/test/rolling-upgrades/go.sum @@ -74,8 +74,8 @@ github.com/emirpasic/gods v1.18.1/go.mod h1:8tpGGwCnJ5H4r6BWwaV6OrWmMoPhUl5jm/FM github.com/fatih/color v1.9.0/go.mod h1:eQcE1qtQxscV5RaZvpXrrb8Drkc3/DdQ+uUYCNjL+zU= github.com/fatih/color v1.18.0 h1:S8gINlzdQ840/4pfAwic/ZE0djQEH3wM94VfqLTZcOM= github.com/fatih/color v1.18.0/go.mod h1:4FelSpRwEGDpQ12mAdzqdOukCy4u8WUtOY6lkT/6HfU= -github.com/formancehq/go-libs/v3 v3.0.0-20250407102820-68fa020e67bb h1:bX/OQdZJryJlOzc1Ao8mMKg1kV9qSmmJ1aHxv5N71HE= -github.com/formancehq/go-libs/v3 v3.0.0-20250407102820-68fa020e67bb/go.mod h1:mRr5/y0I64iJ4I+BXNkUy49izwrh3SA5L+MTWD1d/7Q= +github.com/formancehq/go-libs/v3 v3.0.0-20250422113236-ec98813a1539 h1:6kUkmD2GiZGB7TDpGaPas2ipaAKqP/os3PVk4XFVrpI= +github.com/formancehq/go-libs/v3 v3.0.0-20250422113236-ec98813a1539/go.mod h1:mRr5/y0I64iJ4I+BXNkUy49izwrh3SA5L+MTWD1d/7Q= github.com/fsnotify/fsnotify v1.6.0 h1:n+5WquG0fcWoWp6xPWfHdbskMCQaFnG6PfBrh1Ky4HY= github.com/fsnotify/fsnotify v1.6.0/go.mod h1:sl3t1tCWJFWoRz9R8WJCbQihKKwmorjAbSClcnxKAGw= github.com/gliderlabs/ssh v0.3.8 h1:a4YXD1V7xMF9g5nTkdfnja3Sxy1PVDCj1Zg4Wb8vY6c= diff --git a/tools/generator/go.mod b/tools/generator/go.mod index 28a60c53d6..b9a0c561c2 100644 --- a/tools/generator/go.mod +++ b/tools/generator/go.mod @@ -9,7 +9,7 @@ replace github.com/formancehq/ledger => ../.. replace github.com/formancehq/ledger/pkg/client => ../../pkg/client require ( - github.com/formancehq/go-libs/v3 v3.0.0-20250408113106-7b3525e0b25b + github.com/formancehq/go-libs/v3 v3.0.0-20250422113236-ec98813a1539 github.com/formancehq/ledger v0.0.0-00010101000000-000000000000 github.com/formancehq/ledger/pkg/client v0.0.0-00010101000000-000000000000 github.com/spf13/cobra v1.9.1 diff --git a/tools/generator/go.sum b/tools/generator/go.sum index cf4f54324e..fa28774522 100644 --- a/tools/generator/go.sum +++ b/tools/generator/go.sum @@ -102,8 +102,8 @@ github.com/fatih/color v1.18.0 h1:S8gINlzdQ840/4pfAwic/ZE0djQEH3wM94VfqLTZcOM= github.com/fatih/color v1.18.0/go.mod h1:4FelSpRwEGDpQ12mAdzqdOukCy4u8WUtOY6lkT/6HfU= github.com/felixge/httpsnoop v1.0.4 h1:NFTV2Zj1bL4mc9sqWACXbQFVBBg2W3GPvqp8/ESS2Wg= github.com/felixge/httpsnoop v1.0.4/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U= -github.com/formancehq/go-libs/v3 v3.0.0-20250408113106-7b3525e0b25b h1:EvnYMGyZo+fq9fsrraedKBlVTbeE2mqpJ/edj8FRTtU= -github.com/formancehq/go-libs/v3 v3.0.0-20250408113106-7b3525e0b25b/go.mod h1:mRr5/y0I64iJ4I+BXNkUy49izwrh3SA5L+MTWD1d/7Q= +github.com/formancehq/go-libs/v3 v3.0.0-20250422113236-ec98813a1539 h1:6kUkmD2GiZGB7TDpGaPas2ipaAKqP/os3PVk4XFVrpI= +github.com/formancehq/go-libs/v3 v3.0.0-20250422113236-ec98813a1539/go.mod h1:mRr5/y0I64iJ4I+BXNkUy49izwrh3SA5L+MTWD1d/7Q= github.com/formancehq/numscript v0.0.16 h1:kNNpPTmTvhRUrMXonZPMwUXUpJ06Io1WwC56Yf3nr1E= github.com/formancehq/numscript v0.0.16/go.mod h1:8WhBIqcK6zu27njxy7ZG7CaDX0MHtI9qF9Ggfj07wfU= github.com/fsnotify/fsnotify v1.8.0 h1:dAwr6QBTBZIkG8roQaJjGof0pp0EeF+tNV7YBP3F/8M=