func CallWithBackoff(block func() bool, policy BackoffPolicy) {
	for {
		if !block() {
			break
		}
		if next, ok := policy.Next(); ok {
			time.Sleep(next)
		} else {
			break
		}
	}
}
A helper which sleeps with the value returned by policy.Next() as long as the
block provided returns true.
package mongoproxy
import (
	"math/rand"
	"time"
)
type BackoffPolicy interface {
	Next() (next time.Duration, ok bool)
}
type ConstantBackoffPolicy struct {
	i, maxRetries int
	interval      time.Duration
}
func NewConstantBackoffPolicy(maxRetries int, interval time.Duration) BackoffPolicy {
	return &ConstantBackoffPolicy{maxRetries: maxRetries, interval: interval}
}
func (p *ConstantBackoffPolicy) Next() (next time.Duration, ok bool) {
	if p.i < p.maxRetries {
		ok = true
		next = p.interval
		p.i++
	}
	return
}
type ExpBackoffPolicy struct {
	i, maxRetries int
	interval      time.Duration
}
func NewExpBackoffPolicy(maxRetries int, interval time.Duration) BackoffPolicy {
	return &ExpBackoffPolicy{maxRetries: maxRetries, interval: interval}
}
func (p *ExpBackoffPolicy) Next() (next time.Duration, ok bool) {
	if p.i < p.maxRetries {
		ok = true
		cur := int64(p.interval)
		next = time.Duration((1<<uint(p.i))*cur + rand.Int63n(cur))
		p.i++
	}
	return
}