This is definitely strange. You're using the atomics correctly. Are you on a 32-bit platform by any chance? If so, try replacing 64-bit atomics with 32-bit atomics. The 64-bit atomics should work on 32-bit platforms, but it wouldn't hurt to test that theory.
If you can extract a standalone test case, please file an issue at https://github.com/golang/go/issues On Thursday, August 2, 2018 at 8:12:28 AM UTC-7, James Hartig wrote: > > We are having a weird case where an atomic number was increasing and not > decreasing, despite calls to decrease it. Hopefully, someone on the list > can point out something I'm doing wrong with the atomic package. > > The function with the issue is: > > func UnhealthyOverConcurrent(prefix string, limit int64) Middleware { > var concur int64 > lhealth.Register(lflag.Prefixed("lhttp-concurrent", prefix), func() error { > c := atomic.LoadInt64(&concur) > if c <= limit { > return nil > } > return fmt.Errorf("requests at %d and limit is %d", c, limit) > }) > return func(h http.Handler) http.Handler { > return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { > atomic.AddInt64(&concur, 1) > h.ServeHTTP(w, r) > atomic.AddInt64(&concur, -1) > }) > } > } > > We started to observe that the error was being returned from the register > callback because c was over 500 (limit value in this case) but there was > definitely not 500 concurrent connections. There actually was only around > 50. The lhealth.Register callback is called roughly every second and until > the service was restarted it had stayed constant over 500. This happened to > multiple instances of the service across multiple servers. The weird thing > is that we don't use atomic in another spot that also happens to track > concurrent requests and it didn't have the issue. > > That spot roughly does: > func Metrics() Middleware { > var l sync.Mutex > var val float64 > > incr := func(by float64) { > l.Lock() > defer l.Unlock() > val += by > } > > return func(h http.Handler) http.Handler { > return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { > incr(1) > h.ServeHTTP(w, r) > incr(-1) > }) > } > } > > This second instance reported the correct number of concurrent requests > while the other function was off by a factor of 10. > > Is there anything I'm doing wrong with the atomic package? Is it better to > just switch to a locking version like the second case? Since an http > handler can panic and cause the counts to be off, we are switching the > decrements to be deferred but we don't see any panics in the logs during > this time period. > -- You received this message because you are subscribed to the Google Groups "golang-nuts" group. To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/d/optout.