From f3962b1849a405995420fef4452f2a8493aa19e0 Mon Sep 17 00:00:00 2001 From: Kevin Burke Date: Wed, 18 Apr 2018 15:49:06 -0700 Subject: [PATCH] sync/atomic: use package prefix in examples Previously these examples declared "var v Value" but any caller would need to write "var v atomic.Value", so we should use the external package declaration form to avoid confusion about where Value comes from. Change-Id: Ic0b1a05fb6b700da61cfc8efca594c49a9bedb69 Reviewed-on: https://go-review.googlesource.com/107975 Reviewed-by: Ian Lance Taylor Run-TryBot: Ian Lance Taylor TryBot-Result: Gobot Gobot --- src/sync/atomic/example_test.go | 76 +++++++++++++++++++++++++++++++++ src/sync/atomic/value_test.go | 67 ----------------------------- 2 files changed, 76 insertions(+), 67 deletions(-) create mode 100644 src/sync/atomic/example_test.go diff --git a/src/sync/atomic/example_test.go b/src/sync/atomic/example_test.go new file mode 100644 index 0000000000..09ae0aad1a --- /dev/null +++ b/src/sync/atomic/example_test.go @@ -0,0 +1,76 @@ +// Copyright 2018 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package atomic_test + +import ( + "sync" + "sync/atomic" + "time" +) + +func loadConfig() map[string]string { + return make(map[string]string) +} + +func requests() chan int { + return make(chan int) +} + +// The following example shows how to use Value for periodic program config updates +// and propagation of the changes to worker goroutines. +func ExampleValue_config() { + var config atomic.Value // holds current server configuration + // Create initial config value and store into config. + config.Store(loadConfig()) + go func() { + // Reload config every 10 seconds + // and update config value with the new version. + for { + time.Sleep(10 * time.Second) + config.Store(loadConfig()) + } + }() + // Create worker goroutines that handle incoming requests + // using the latest config value. + for i := 0; i < 10; i++ { + go func() { + for r := range requests() { + c := config.Load() + // Handle request r using config c. + _, _ = r, c + } + }() + } +} + +// The following example shows how to maintain a scalable frequently read, +// but infrequently updated data structure using copy-on-write idiom. +func ExampleValue_readMostly() { + type Map map[string]string + var m atomic.Value + m.Store(make(Map)) + var mu sync.Mutex // used only by writers + // read function can be used to read the data without further synchronization + read := func(key string) (val string) { + m1 := m.Load().(Map) + return m1[key] + } + // insert function can be used to update the data without further synchronization + insert := func(key, val string) { + mu.Lock() // synchronize with other potential writers + defer mu.Unlock() + m1 := m.Load().(Map) // load current value of the data structure + m2 := make(Map) // create a new value + for k, v := range m1 { + m2[k] = v // copy all data from the current object to the new one + } + m2[key] = val // do the update that we need + m.Store(m2) // atomically replace the current object with the new one + // At this point all new readers start working with the new version. + // The old version will be garbage collected once the existing readers + // (if any) are done with it. + } + _, _ = read, insert +} diff --git a/src/sync/atomic/value_test.go b/src/sync/atomic/value_test.go index fd90451dd8..fd69ba30dc 100644 --- a/src/sync/atomic/value_test.go +++ b/src/sync/atomic/value_test.go @@ -7,10 +7,8 @@ package atomic_test import ( "math/rand" "runtime" - "sync" . "sync/atomic" "testing" - "time" ) func TestValue(t *testing.T) { @@ -133,68 +131,3 @@ func BenchmarkValueRead(b *testing.B) { } }) } - -// The following example shows how to use Value for periodic program config updates -// and propagation of the changes to worker goroutines. -func ExampleValue_config() { - var config Value // holds current server configuration - // Create initial config value and store into config. - config.Store(loadConfig()) - go func() { - // Reload config every 10 seconds - // and update config value with the new version. - for { - time.Sleep(10 * time.Second) - config.Store(loadConfig()) - } - }() - // Create worker goroutines that handle incoming requests - // using the latest config value. - for i := 0; i < 10; i++ { - go func() { - for r := range requests() { - c := config.Load() - // Handle request r using config c. - _, _ = r, c - } - }() - } -} - -func loadConfig() map[string]string { - return make(map[string]string) -} - -func requests() chan int { - return make(chan int) -} - -// The following example shows how to maintain a scalable frequently read, -// but infrequently updated data structure using copy-on-write idiom. -func ExampleValue_readMostly() { - type Map map[string]string - var m Value - m.Store(make(Map)) - var mu sync.Mutex // used only by writers - // read function can be used to read the data without further synchronization - read := func(key string) (val string) { - m1 := m.Load().(Map) - return m1[key] - } - // insert function can be used to update the data without further synchronization - insert := func(key, val string) { - mu.Lock() // synchronize with other potential writers - defer mu.Unlock() - m1 := m.Load().(Map) // load current value of the data structure - m2 := make(Map) // create a new value - for k, v := range m1 { - m2[k] = v // copy all data from the current object to the new one - } - m2[key] = val // do the update that we need - m.Store(m2) // atomically replace the current object with the new one - // At this point all new readers start working with the new version. - // The old version will be garbage collected once the existing readers - // (if any) are done with it. - } - _, _ = read, insert -} -- 2.48.1