mirror of
https://github.com/golang/go
synced 2024-11-18 21:05:02 -07:00
Initial cut at an "exported variables" (exvar) package.
This handles integer-valued vars in a singleton struct, and exports functions for incrementing, setting and getting those vars, as well as rendering all the vars in a standard format. Demonstrate the use of the exvar package in the http/triv server. R=dcross,r APPROVED=r DELTA=122 (122 added, 0 deleted, 0 changed) OCL=27617 CL=27622
This commit is contained in:
parent
f1820b50ff
commit
3cc702ba60
@ -30,6 +30,7 @@ FILES=\
|
||||
bignum\
|
||||
bufio\
|
||||
exec\
|
||||
exvar\
|
||||
flag\
|
||||
log\
|
||||
malloc\
|
||||
@ -44,6 +45,7 @@ TEST=\
|
||||
bignum\
|
||||
bufio\
|
||||
exec\
|
||||
exvar\
|
||||
flag\
|
||||
log\
|
||||
once\
|
||||
@ -97,6 +99,7 @@ test: test.files
|
||||
bignum.6: fmt.dirinstall
|
||||
bufio.6: io.dirinstall os.dirinstall
|
||||
exec.6: os.dirinstall strings.install
|
||||
exvar.6: fmt.dirinstall sync.dirinstall
|
||||
flag.6: fmt.dirinstall os.dirinstall strconv.dirinstall
|
||||
log.6: fmt.dirinstall io.dirinstall os.dirinstall time.dirinstall
|
||||
path.6: io.dirinstall
|
||||
|
60
src/lib/exvar.go
Normal file
60
src/lib/exvar.go
Normal file
@ -0,0 +1,60 @@
|
||||
// Copyright 2009 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.
|
||||
|
||||
// The exvar package provides a standardized interface to public variables,
|
||||
// such as operation counters in servers.
|
||||
package exvar
|
||||
|
||||
import (
|
||||
"fmt";
|
||||
"sync";
|
||||
)
|
||||
|
||||
// Global state.
|
||||
var (
|
||||
mutex sync.Mutex;
|
||||
intVars = make(map[string] int);
|
||||
mapVars = make(map[string] map[string] int);
|
||||
// TODO(dsymonds):
|
||||
// - string-valued vars
|
||||
// - docstrings
|
||||
// - dynamic lookup vars (via chan)
|
||||
)
|
||||
|
||||
// Increment adds inc to the var called name.
|
||||
func Increment(name string, inc int) {
|
||||
mutex.Lock();
|
||||
defer mutex.Unlock();
|
||||
|
||||
if x, ok := intVars[name]; ok {
|
||||
intVars[name] += inc
|
||||
} else {
|
||||
intVars[name] = inc
|
||||
}
|
||||
}
|
||||
|
||||
// Set sets the var called name to value.
|
||||
func Set(name string, value int) {
|
||||
intVars[name] = value
|
||||
}
|
||||
|
||||
// Get retrieves an integer-valued var called name.
|
||||
func Get(name string) (x int, ok bool) {
|
||||
x, ok = intVars[name];
|
||||
return
|
||||
}
|
||||
|
||||
// TODO(dsymonds): Functions for map-valued vars.
|
||||
|
||||
// String produces a string of all the vars in textual format.
|
||||
func String() string {
|
||||
mutex.Lock();
|
||||
defer mutex.Unlock();
|
||||
|
||||
s := "";
|
||||
for name, value := range intVars {
|
||||
s += fmt.Sprintln(name, value)
|
||||
}
|
||||
return s
|
||||
}
|
54
src/lib/exvar_test.go
Normal file
54
src/lib/exvar_test.go
Normal file
@ -0,0 +1,54 @@
|
||||
// Copyright 2009 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 exvar
|
||||
|
||||
import (
|
||||
"exvar";
|
||||
"fmt";
|
||||
"testing";
|
||||
)
|
||||
|
||||
func TestSimpleCounter(t *testing.T) {
|
||||
// Unknown exvar should be zero, and return !ok.
|
||||
x, ok := Get("requests");
|
||||
if x != 0 || ok {
|
||||
t.Errorf("Get(nonexistent) = (%v, %v), want (%v, %v)",
|
||||
x, ok, 0, false)
|
||||
}
|
||||
|
||||
Increment("requests", 1);
|
||||
Increment("requests", 3);
|
||||
x, ok = Get("requests");
|
||||
if x != 4 || !ok {
|
||||
t.Errorf("Get('requests') = (%v, %v), want (%v, %v)",
|
||||
x, ok, 4, true)
|
||||
}
|
||||
|
||||
out := String();
|
||||
if out != "requests 4\n" {
|
||||
t.Errorf("String() = \"%v\", want \"requests 4\n\"",
|
||||
out);
|
||||
}
|
||||
}
|
||||
|
||||
func hammer(name string, total int, done chan <- int) {
|
||||
for i := 0; i < total; i++ {
|
||||
Increment(name, 1)
|
||||
}
|
||||
done <- 1
|
||||
}
|
||||
|
||||
func TestHammer(t *testing.T) {
|
||||
Set("hammer-times", 0);
|
||||
sync := make(chan int);
|
||||
hammer_times := int(1e5);
|
||||
go hammer("hammer-times", hammer_times, sync);
|
||||
go hammer("hammer-times", hammer_times, sync);
|
||||
<-sync;
|
||||
<-sync;
|
||||
if final, ok := Get("hammer-times"); final != 2 * hammer_times {
|
||||
t.Errorf("hammer-times = %v, want %v", final, 2 * hammer_times)
|
||||
}
|
||||
}
|
@ -6,6 +6,7 @@ package main
|
||||
|
||||
import (
|
||||
"bufio";
|
||||
"exvar";
|
||||
"flag";
|
||||
"fmt";
|
||||
"http";
|
||||
@ -17,15 +18,23 @@ import (
|
||||
|
||||
// hello world, the web server
|
||||
func HelloServer(c *http.Conn, req *http.Request) {
|
||||
exvar.Increment("hello-requests", 1);
|
||||
io.WriteString(c, "hello, world!\n");
|
||||
}
|
||||
|
||||
// Handler for /exvar requests.
|
||||
func ExvarServer(c *http.Conn, req *http.Request) {
|
||||
c.SetHeader("content-type", "text/plain; charset=utf-8");
|
||||
io.WriteString(c, exvar.String());
|
||||
}
|
||||
|
||||
// simple counter server
|
||||
type Counter struct {
|
||||
n int;
|
||||
}
|
||||
|
||||
func (ctr *Counter) ServeHTTP(c *http.Conn, req *http.Request) {
|
||||
exvar.Increment("counter-requests", 1);
|
||||
fmt.Fprintf(c, "counter = %d\n", ctr.n);
|
||||
ctr.n++;
|
||||
}
|
||||
@ -92,6 +101,7 @@ func main() {
|
||||
http.Handle("/args", http.HandlerFunc(ArgServer));
|
||||
http.Handle("/go/hello", http.HandlerFunc(HelloServer));
|
||||
http.Handle("/chan", ChanCreate());
|
||||
http.Handle("/exvar", http.HandlerFunc(ExvarServer));
|
||||
err := http.ListenAndServe(":12345", nil);
|
||||
if err != nil {
|
||||
panic("ListenAndServe: ", err.String())
|
||||
|
Loading…
Reference in New Issue
Block a user