fix: serialise redirect writes so concurrent saves cannot store a loop (WR-10)
The save-time simulation read the rules at READ COMMITTED without a lock, so A -> B and B -> A written concurrently both passed. CheckRedirect, AddressChanged and every batch now take a transaction-level advisory lock before they read the rules.
This commit is contained in:
@@ -241,6 +241,11 @@ func (s *Service) runBatch(ctx context.Context, opts BatchOptions, build func(ct
|
||||
if opts.Via != "" {
|
||||
ctx = WithVia(ctx, opts.Via)
|
||||
}
|
||||
// One lock for the whole batch, so a refused change rolled back to
|
||||
// its savepoint does not let another redirect writer in (WR-10).
|
||||
if err := lockRedirectWrites(tx); err != nil {
|
||||
return err
|
||||
}
|
||||
changes, err := build(ctx, tx)
|
||||
if err != nil {
|
||||
return err
|
||||
|
||||
Reference in New Issue
Block a user