feat: add expiry
This commit is contained in:
parent
369c6ebf85
commit
5ad307868e
|
@ -105,7 +105,7 @@ func (sb *smtpBackend) shouldReportOutgoingNoEnc() bool {
|
|||
}
|
||||
|
||||
func (sb *smtpBackend) ConfirmNoEncryption(messageID string, shouldSend bool) {
|
||||
if err := sb.confirmer.SetResponse(messageID, shouldSend); err != nil {
|
||||
if err := sb.confirmer.SetResult(messageID, shouldSend); err != nil {
|
||||
logrus.WithError(err).Error("Failed to set confirmation value")
|
||||
}
|
||||
}
|
||||
|
|
|
@ -61,9 +61,9 @@ func (c *Confirmer) SetResult(id string, value bool) error {
|
|||
return errors.New("no such request")
|
||||
}
|
||||
|
||||
req.value <- value
|
||||
req.ch <- value
|
||||
|
||||
close(req.value)
|
||||
close(req.ch)
|
||||
delete(c.requests, id)
|
||||
|
||||
return nil
|
||||
|
|
|
@ -65,3 +65,20 @@ func TestConfirmerTimeout(t *testing.T) {
|
|||
_, err := req.Result()
|
||||
assert.Error(t, err)
|
||||
}
|
||||
|
||||
func TestConfirmerMultipleRequestCalls(t *testing.T) {
|
||||
c := New()
|
||||
|
||||
req := c.NewRequest(1 * time.Second)
|
||||
|
||||
go func() {
|
||||
assert.NoError(t, c.SetResult(req.ID(), true))
|
||||
}()
|
||||
|
||||
res, err := req.Result()
|
||||
assert.NoError(t, err)
|
||||
assert.True(t, res)
|
||||
|
||||
_, errAgain := req.Result()
|
||||
assert.Error(t, errAgain)
|
||||
}
|
||||
|
|
|
@ -19,6 +19,7 @@ package confirmer
|
|||
|
||||
import (
|
||||
"errors"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"github.com/google/uuid"
|
||||
|
@ -27,15 +28,19 @@ import (
|
|||
// Request provides a result when it becomes available.
|
||||
type Request struct {
|
||||
uuid string
|
||||
value chan bool
|
||||
ch chan bool
|
||||
timeout time.Duration
|
||||
|
||||
expired bool
|
||||
locker sync.Locker
|
||||
}
|
||||
|
||||
func newRequest(timeout time.Duration) *Request {
|
||||
return &Request{
|
||||
uuid: uuid.New().String(),
|
||||
value: make(chan bool),
|
||||
ch: make(chan bool),
|
||||
timeout: timeout,
|
||||
locker: &sync.Mutex{},
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -46,11 +51,31 @@ func (r *Request) ID() string {
|
|||
|
||||
// Result returns the result or an error if it is not available within the request timeout.
|
||||
func (r *Request) Result() (bool, error) {
|
||||
if r.hasExpired() {
|
||||
return false, errors.New("this result has expired")
|
||||
}
|
||||
|
||||
defer r.done()
|
||||
|
||||
select {
|
||||
case res := <-r.value:
|
||||
case res := <-r.ch:
|
||||
return res, nil
|
||||
|
||||
case <-time.After(r.timeout):
|
||||
return false, errors.New("timed out waiting for result")
|
||||
}
|
||||
}
|
||||
|
||||
func (r *Request) hasExpired() bool {
|
||||
r.locker.Lock()
|
||||
defer r.locker.Unlock()
|
||||
|
||||
return r.expired
|
||||
}
|
||||
|
||||
func (r *Request) done() {
|
||||
r.locker.Lock()
|
||||
defer r.locker.Unlock()
|
||||
|
||||
r.expired = true
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue