79 lines
1.9 KiB
Go
79 lines
1.9 KiB
Go
package main
|
|
|
|
// What the tests stand on: an in-memory double of Store (store.go), for the hearing (1518) and health (1519)
|
|
// tests alike. The postgres-backed PgStore (pgstore.go) is proven only by pgstore_test.go's unit tests and by
|
|
// pgstore_integration_test.go, which this context never runs.
|
|
|
|
import (
|
|
"context"
|
|
"errors"
|
|
"sync"
|
|
)
|
|
|
|
type memStore struct {
|
|
mu sync.Mutex
|
|
waiting []WaitingMail
|
|
keys map[string]bool
|
|
nextSeq int64
|
|
failNext error // AddWaiting fails once with this, then clears, so a test can prove a failure is returned
|
|
health ReaderHealth
|
|
}
|
|
|
|
func newMemStore() *memStore {
|
|
return &memStore{keys: map[string]bool{}, health: ReaderHealth{Healthy: true}}
|
|
}
|
|
|
|
func (s *memStore) AddWaiting(_ context.Context, w WaitingMail) error {
|
|
s.mu.Lock()
|
|
defer s.mu.Unlock()
|
|
if s.failNext != nil {
|
|
err := s.failNext
|
|
s.failNext = nil
|
|
return err
|
|
}
|
|
key := w.Key()
|
|
if s.keys[key] {
|
|
return nil // 1518/AC3: the same mail heard twice is recorded once.
|
|
}
|
|
s.keys[key] = true
|
|
s.nextSeq++
|
|
w.Seq = s.nextSeq
|
|
s.waiting = append(s.waiting, w)
|
|
return nil
|
|
}
|
|
|
|
func (s *memStore) Waiting(context.Context) ([]WaitingMail, error) {
|
|
s.mu.Lock()
|
|
defer s.mu.Unlock()
|
|
out := make([]WaitingMail, len(s.waiting))
|
|
copy(out, s.waiting) // already in arrival order: appended in the order AddWaiting succeeded (1518/AC4).
|
|
return out, nil
|
|
}
|
|
|
|
func (s *memStore) TakeWaiting(_ context.Context, seq int64) error {
|
|
s.mu.Lock()
|
|
defer s.mu.Unlock()
|
|
for i, w := range s.waiting {
|
|
if w.Seq == seq {
|
|
s.waiting = append(s.waiting[:i], s.waiting[i+1:]...)
|
|
return nil
|
|
}
|
|
}
|
|
return nil
|
|
}
|
|
|
|
func (s *memStore) ReaderHealth(context.Context) (ReaderHealth, error) {
|
|
s.mu.Lock()
|
|
defer s.mu.Unlock()
|
|
return s.health, nil
|
|
}
|
|
|
|
func (s *memStore) SetReaderHealth(_ context.Context, h ReaderHealth) error {
|
|
s.mu.Lock()
|
|
defer s.mu.Unlock()
|
|
s.health = h
|
|
return nil
|
|
}
|
|
|
|
var errStoreFake = errors.New("the store refused (fake, for a test)")
|