Last active
July 18, 2019 20:57
-
-
Save tylerstillwater/7da6cc6c2180f48da66f64af0f7cd428 to your computer and use it in GitHub Desktop.
Simulate io blocking
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// All material is licensed under the Apache License Version 2.0, January 2004 | |
// http://www.apache.org/licenses/LICENSE-2.0 | |
// This sample program demonstrates how the logger package works. | |
package main | |
import ( | |
"fmt" | |
"log" | |
"os" | |
"os/signal" | |
"sync/atomic" | |
"time" | |
) | |
type device struct { | |
blocking int32 | |
toggle int32 | |
} | |
// toggleBlocking will toggle the blocking state of this device | |
func (d *device) toggleBlocking() { | |
toggle := 1 - d.toggle | |
atomic.CompareAndSwapInt32(&d.blocking, d.toggle, toggle) | |
d.toggle = toggle | |
} | |
// wait will wait until the device is ready for use | |
func (d *device) wait() { | |
for atomic.LoadInt32(&d.blocking) == 1 { | |
time.Sleep(100 * time.Millisecond) | |
} | |
} | |
// writer allows us to mock a writer we write logs to. | |
type writer struct { | |
d *device | |
} | |
// Write implements the io.Writer interface. | |
func (w *writer) Write(p []byte) (n int, err error) { | |
w.d.wait() | |
fmt.Print(string(p)) | |
return len(p), nil | |
} | |
func main() { | |
// Number of goroutines that will be writing logs. | |
const grs = 10 | |
// Create a logger value with a buffer of capacity | |
// for each goroutine that will be logging. | |
var d device | |
w := writer{d: &d} | |
l := log.New(&w, "prefix", 0) | |
// Generate goroutines, each writing to disk. | |
for i := 0; i < grs; i++ { | |
go func(id int) { | |
for { | |
l.Println(fmt.Sprintf("%d: log data", id)) | |
time.Sleep(100 * time.Millisecond) | |
} | |
}(i) | |
} | |
// We want to control the simulated disk blocking. Capture | |
// interrupt signals to toggle device issues. Use <ctrl> z | |
// to kill the program. | |
sigChan := make(chan os.Signal, 1) | |
signal.Notify(sigChan, os.Interrupt) | |
for { | |
<-sigChan | |
d.toggleBlocking() | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment