provider/mesh: extract silence deletion into state

This commit is contained in:
Fabian Reinartz 2016-06-09 16:43:51 +02:00
parent 9039a3cffa
commit 3d350a34b5
3 changed files with 37 additions and 24 deletions

View File

@ -2,7 +2,6 @@ package mesh
import (
"fmt"
"time"
"github.com/prometheus/alertmanager/provider"
"github.com/prometheus/alertmanager/types"
@ -161,31 +160,16 @@ func (s *Silences) Set(sil *types.Silence) (uuid.UUID, error) {
}
func (s *Silences) Del(id uuid.UUID) error {
s.st.mtx.RLock()
sil, ok := s.st.m[id]
s.st.mtx.RUnlock()
if !ok {
return provider.ErrNotFound
sil, err := s.st.del(id)
if err != nil {
return err
}
now := time.Now()
if sil.EndsAt.Before(now) {
return fmt.Errorf("silence already ended")
}
// Silences are immutable by contract so we create a completely
// new object instead.
newSil := *sil
newSil.UpdatedAt = now
newSil.EndsAt = now
if err := newSil.Init(); err != nil {
return fmt.Errorf("silence init: %s", err)
}
update := &silenceState{
m: map[uuid.UUID]*types.Silence{
newSil.ID: &newSil,
sil.ID: sil,
},
}
s.st.Merge(update)
s.send.GossipBroadcast(update)
return nil

View File

@ -7,6 +7,7 @@ import (
"sync"
"time"
"github.com/prometheus/alertmanager/provider"
"github.com/prometheus/alertmanager/types"
"github.com/satori/go.uuid"
"github.com/weaveworks/mesh"
@ -133,11 +134,10 @@ func (st *silenceState) Encode() [][]byte {
// silenceModAllowed checks whether silence a may be changed to silence b.
// Returns an error stating the reason if not.
func (st *silenceState) silenceModAllowed(a, b *types.Silence) error {
func silenceModAllowed(a, b *types.Silence, now time.Time) error {
if !b.StartsAt.Equal(a.StartsAt) {
return fmt.Errorf("silence start time must not be modified")
}
now := st.now()
if a.EndsAt.Before(now) {
return fmt.Errorf("end time must not be modified for elapsed silence")
}
@ -154,7 +154,8 @@ func (st *silenceState) set(s *types.Silence) error {
st.mtx.Lock()
defer st.mtx.Unlock()
s.UpdatedAt = st.now()
now := st.now()
s.UpdatedAt = now
if err := s.Validate(); err != nil {
return err
@ -165,13 +166,39 @@ func (st *silenceState) set(s *types.Silence) error {
st.m[s.ID] = s
return nil
}
if err := st.silenceModAllowed(prev, s); err != nil {
if err := silenceModAllowed(prev, s, now); err != nil {
return err
}
st.m[s.ID] = s
return nil
}
func (st *silenceState) del(id uuid.UUID) (*types.Silence, error) {
st.mtx.Lock()
defer st.mtx.Unlock()
prev, ok := st.m[id]
if !ok {
return nil, provider.ErrNotFound
}
// Silences are immutable by contract so we create a
// shallow copy.
sil := *prev
now := st.now()
sil.UpdatedAt = now
sil.EndsAt = now
if err := sil.Validate(); err != nil {
return nil, err
}
if err := silenceModAllowed(prev, &sil, now); err != nil {
return nil, err
}
st.m[sil.ID] = &sil
return &sil, nil
}
func (st *silenceState) Merge(other mesh.GossipData) mesh.GossipData {
o := other.(*silenceState)
o.mtx.RLock()

View File

@ -16,6 +16,7 @@ package types
import (
"fmt"
"hash/fnv"
"sort"
"strings"
"sync"
"time"
@ -276,6 +277,7 @@ func (s *Silence) Init() error {
return err
}
}
sort.Sort(s.Matchers)
return nil
}