add kuba testcase, fix race

we fix the race by not returning pointers to the things which we're
keeping in the in-memory store
This commit is contained in:
Matt Jaffee 2020-04-22 15:17:25 -05:00
parent 85f57f9975
commit 97ae8e0db7
No known key found for this signature in database
GPG key ID: 08A3DFFF987B11BF
2 changed files with 34 additions and 5 deletions

View file

@ -36,6 +36,7 @@ import (
"github.com/pilosa/pilosa/v2/roaring"
"github.com/pilosa/pilosa/v2/server"
"github.com/pilosa/pilosa/v2/test"
"github.com/pkg/errors"
"golang.org/x/sync/errgroup"
)
@ -468,10 +469,27 @@ func TestTransactionsAPI(t *testing.T) {
}
// can poll exclusive transaction and is active
var excTrns *pilosa.Transaction
if trns, err := api0.GetTransaction(ctx, "exc", false); err != nil {
t.Errorf("couldn't poll exclusive transaction: %v", err)
} else {
test.CompareTransactions(t, &pilosa.Transaction{ID: "exc", Active: true, Exclusive: true, Timeout: time.Minute, Deadline: time.Now().Add(time.Minute)}, trns)
excTrns = &pilosa.Transaction{ID: "exc", Active: true, Exclusive: true, Timeout: time.Minute, Deadline: time.Now().Add(time.Minute)}
test.CompareTransactions(t, excTrns, trns)
}
// can't start another exclusive transaction
if trns, err := api0.StartTransaction(ctx, "exc2", time.Minute, true, false); errors.Cause(err) != pilosa.ErrTransactionExclusive {
t.Errorf("unexpected error: %v", err)
} else {
// returned transaction should be the exclusive one which is blocking this one
test.CompareTransactions(t, excTrns, trns)
}
// can't keep the second exclusive name but make it nonexclusive and start a transaction
if trns, err := api0.StartTransaction(ctx, "exc2", time.Minute, false, false); errors.Cause(err) != pilosa.ErrTransactionExclusive {
t.Errorf("unexpected error: %v", err)
} else {
test.CompareTransactions(t, excTrns, trns)
}
// transaction is active on other nodes with remote=true

View file

@ -330,7 +330,7 @@ func (s *InMemTransactionStore) Put(trns *Transaction) error {
s.mu.Lock()
defer s.mu.Unlock()
s.tmap[trns.ID] = trns
s.tmap[trns.ID] = trns.Copy()
return nil
}
@ -339,7 +339,7 @@ func (s *InMemTransactionStore) Get(id string) (*Transaction, error) {
defer s.mu.RUnlock()
if trns, ok := s.tmap[id]; ok {
return trns, nil
return trns.Copy(), nil
}
return nil, ErrTransactionNotFound
}
@ -347,7 +347,7 @@ func (s *InMemTransactionStore) Get(id string) (*Transaction, error) {
func (s *InMemTransactionStore) List() (map[string]*Transaction, error) {
cp := make(map[string]*Transaction)
for id, trns := range s.tmap {
cp[id] = trns
cp[id] = trns.Copy()
}
return cp, nil
}
@ -358,7 +358,7 @@ func (s *InMemTransactionStore) Remove(id string) (*Transaction, error) {
if trns, ok := s.tmap[id]; ok {
delete(s.tmap, id)
return trns, nil
return trns.Copy(), nil
}
return nil, ErrTransactionNotFound
}
@ -448,3 +448,14 @@ func (trns *Transaction) MarshalJSON() ([]byte, error) {
Deadline: trns.Deadline.In(time.UTC).Format(time.RFC3339Nano),
})
}
func (trns *Transaction) Copy() *Transaction {
return &Transaction{
ID: trns.ID,
Active: trns.Active,
Exclusive: trns.Exclusive,
Timeout: trns.Timeout,
Deadline: trns.Deadline,
Stats: trns.Stats,
}
}