...

Source file src/sync/atomic/example_test.go

Documentation: sync/atomic

		 1  // Copyright 2018 The Go Authors. All rights reserved.
		 2  // Use of this source code is governed by a BSD-style
		 3  // license that can be found in the LICENSE file.
		 4  
		 5  package atomic_test
		 6  
		 7  import (
		 8  	"sync"
		 9  	"sync/atomic"
		10  	"time"
		11  )
		12  
		13  func loadConfig() map[string]string {
		14  	return make(map[string]string)
		15  }
		16  
		17  func requests() chan int {
		18  	return make(chan int)
		19  }
		20  
		21  // The following example shows how to use Value for periodic program config updates
		22  // and propagation of the changes to worker goroutines.
		23  func ExampleValue_config() {
		24  	var config atomic.Value // holds current server configuration
		25  	// Create initial config value and store into config.
		26  	config.Store(loadConfig())
		27  	go func() {
		28  		// Reload config every 10 seconds
		29  		// and update config value with the new version.
		30  		for {
		31  			time.Sleep(10 * time.Second)
		32  			config.Store(loadConfig())
		33  		}
		34  	}()
		35  	// Create worker goroutines that handle incoming requests
		36  	// using the latest config value.
		37  	for i := 0; i < 10; i++ {
		38  		go func() {
		39  			for r := range requests() {
		40  				c := config.Load()
		41  				// Handle request r using config c.
		42  				_, _ = r, c
		43  			}
		44  		}()
		45  	}
		46  }
		47  
		48  // The following example shows how to maintain a scalable frequently read,
		49  // but infrequently updated data structure using copy-on-write idiom.
		50  func ExampleValue_readMostly() {
		51  	type Map map[string]string
		52  	var m atomic.Value
		53  	m.Store(make(Map))
		54  	var mu sync.Mutex // used only by writers
		55  	// read function can be used to read the data without further synchronization
		56  	read := func(key string) (val string) {
		57  		m1 := m.Load().(Map)
		58  		return m1[key]
		59  	}
		60  	// insert function can be used to update the data without further synchronization
		61  	insert := func(key, val string) {
		62  		mu.Lock() // synchronize with other potential writers
		63  		defer mu.Unlock()
		64  		m1 := m.Load().(Map) // load current value of the data structure
		65  		m2 := make(Map)			// create a new value
		66  		for k, v := range m1 {
		67  			m2[k] = v // copy all data from the current object to the new one
		68  		}
		69  		m2[key] = val // do the update that we need
		70  		m.Store(m2)	 // atomically replace the current object with the new one
		71  		// At this point all new readers start working with the new version.
		72  		// The old version will be garbage collected once the existing readers
		73  		// (if any) are done with it.
		74  	}
		75  	_, _ = read, insert
		76  }
		77  

View as plain text