A report the store cannot take yet is handed back to the broker, not acknowledged and lost (novox/hq issue 082)
This commit is contained in:
@@ -52,8 +52,20 @@ type Server struct {
|
||||
log *log.Logger
|
||||
upgrader Upgrader
|
||||
replayer Replayer
|
||||
// again is how long a report the store could not take waits before it is handed back to
|
||||
// the broker; zero means TryAgainAfter.
|
||||
again time.Duration
|
||||
}
|
||||
|
||||
// ErrTryAgain marks a listener's failure as "not now": what it was given is worth keeping and
|
||||
// asking again, as when the store is restarting (novox/hq issue 082).
|
||||
var ErrTryAgain = errors.New("not now, try again")
|
||||
|
||||
// TryAgainAfter is the pause before a report the store could not take goes back to the broker.
|
||||
// The consumer takes one message at a time, so without it a restarting store would be asked in
|
||||
// a tight loop; a store comes back in seconds, and a report a few seconds late is still current.
|
||||
const TryAgainAfter = 2 * time.Second
|
||||
|
||||
// Records tells the server where to keep build results.
|
||||
//
|
||||
// Set after Connect rather than passed to it, because a control plane that only publishes — the
|
||||
@@ -311,6 +323,19 @@ func (s *Server) handleReport(delivery amqp.Delivery) {
|
||||
}
|
||||
if s.listener != nil {
|
||||
if err := s.listener.Heard(context.Background(), report); err != nil {
|
||||
if errors.Is(err, ErrTryAgain) {
|
||||
// Kept, not acknowledged. The node reports an apply once, and a report lost here
|
||||
// is a node the mesh never hears from again: the store restarting under the
|
||||
// adoption that node just applied lost exactly that (novox/hq issue 082).
|
||||
again := s.again
|
||||
if again == 0 {
|
||||
again = TryAgainAfter
|
||||
}
|
||||
s.log.Printf("could not record %s's report yet, and will again in %s: %v", report.Node, again, err)
|
||||
time.Sleep(again)
|
||||
_ = delivery.Nack(false, true)
|
||||
return
|
||||
}
|
||||
// Said rather than swallowed. A report the mesh heard and failed to write down is a
|
||||
// node whose recovery copy is silently older than it looks.
|
||||
s.log.Printf("could not record %s's report: %v", report.Node, err)
|
||||
|
||||
Reference in New Issue
Block a user