Commit f3962b18 authored by Kevin Burke's avatar Kevin Burke Committed by Brad Fitzpatrick

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/107975Reviewed-by: 's avatarIan Lance Taylor <iant@golang.org>
Run-TryBot: Ian Lance Taylor <iant@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
parent 744ccbb8
// 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
}
...@@ -7,10 +7,8 @@ package atomic_test ...@@ -7,10 +7,8 @@ package atomic_test
import ( import (
"math/rand" "math/rand"
"runtime" "runtime"
"sync"
. "sync/atomic" . "sync/atomic"
"testing" "testing"
"time"
) )
func TestValue(t *testing.T) { func TestValue(t *testing.T) {
...@@ -133,68 +131,3 @@ func BenchmarkValueRead(b *testing.B) { ...@@ -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
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment