Golang Public Variable Package--expvar

Source: Internet
Author: User
This is a creation in Article, where the information may have evolved or changed.

Write in front

The Expvar package is a public variable package that is officially provided by Golang, which can assist in debugging global variables. Support for some common types: float64 , int64 , Map , String . If our program uses the four types mentioned above (where the Map type requires Key to be a string). You can consider using this package.

Function

    1. It supports the basic operation of variables, modify, query these;
    2. Type of shaping, can be used to do the counter;
    3. The operations are thread-safe. This is very good. Believe that we all have the whole global variable, in addition to the variable is the whole lock, write their own really very troublesome;
    4. The Debug interface is also available /debug/vars . It can show all the variables created through this package;
    5. All variables are Var types and can be extended by implementing the interface themselves.

       type Var interface {     // String returns a valid JSON value for the variable.     // Types with String methods that do not return valid JSON     // (such as time.Time) must not be used as a Var.     String() string }
    6. Handler()The method can get the debug interface http.Handler , and its own routing docking.

These basic functions are not much to say, you can directly read the official documents.

Debug interface

Look at the source of the time to find a very interesting debugging interface, /debug/vars will be all registered variables printed into the interface. This interface has a lot of feelings.

func init() {    http.HandleFunc("/debug/vars", expvarHandler)    Publish("cmdline", Func(cmdline))    Publish("memstats", Func(memstats))}

Source

var (    mutex   sync.RWMutex    vars    = make(map[string]Var)    varKeys []string // sorted)
    1. varKeysis the variable name of the global variable, and is orderly;
    2. varsThe corresponding data is saved according to the variable name. Of course mutex This is the MAP lock;
    3. The combination of these three variables is actually an orderly thread-safe hash table implementation.

       type Var interface {     // String returns a valid JSON value for the variable.     // Types with String methods that do not return valid JSON     // (such as time.Time) must not be used as a Var.     String() string } type Int struct {     i int64 } func (v *Int) Value() int64 {     return atomic.LoadInt64(&v.i) } func (v *Int) String() string {     return strconv.FormatInt(atomic.LoadInt64(&v.i), 10) } func (v *Int) Add(delta int64) {     atomic.AddInt64(&v.i, delta) } func (v *Int) Set(value int64) {     atomic.StoreInt64(&v.i, value) }
  1. All the types in this package implement this interface;
  2. An example of an Int type. The implementation is very simple, the attention Add and Set method is thread-safe. The same is true for other types of implementations

     func Publish(name string, v Var) {     mutex.Lock()     defer mutex.Unlock()     if _, existing := vars[name]; existing {         log.Panicln("Reuse of exported var name:", name)     }     vars[name] = v     varKeys = append(varKeys, name)     sort.Strings(varKeys) } func NewInt(name string) *Int {     v := new(Int)     Publish(name, v)     return v }
  3. Register variables at the beginning of the introduction vars and varKeys inside;

  4. Registration time is also thread-safe, all the variable names in the registration of the last row of the order;
  5. When you create an object, it is automatically registered.

     func Do(f func(KeyValue)) {     mutex.RLock()     defer mutex.RUnlock()     for _, k := range varKeys {         f(KeyValue{k, vars[k]})     } } func expvarHandler(w http.ResponseWriter, r *http.Request) {     w.Header().Set("Content-Type", "application/json; charset=utf-8")     fmt.Fprintf(w, "{\n")     first := true     Do(func(kv KeyValue) {         if !first {             fmt.Fprintf(w, ",\n")         }         first = false         fmt.Fprintf(w, "%q: %s", kv.Key, kv.Value)     })     fmt.Fprintf(w, "\n}\n") } func Handler() http.Handler {     return http.HandlerFunc(expvarHandler) }
  6. Domethod, using a closure, to varKeys traverse all global variables in the order of the packets;

  7. expvarHandlerThe method is the http.Handler type, which outputs all the variables through the interface, through which all the variables are traversed through the Do method. Very ingenious;
  8. By http.HandleFunc means of expvarHandler this external inaccessible method, this method is used to dock its own routing;
  9. The output data type, which fmt.Fprintf(w, "%q: %s", kv.Key, kv.Value) can be found, values the output of the string, so the output content is String() the result. Here's a tip, although the method of invoking the string, but because the output format is %s not quoted outside, all for JSON, the output is the object type. The equivalent of a type conversion at the time of JSON encoding.

     type Func func() interface{} func (f Func) Value() interface{} {     return f() } func (f Func) String() string {     v, _ := json.Marshal(f())     return string(v) } func cmdline() interface{} {     return os.Args }
  10. This is a very interesting notation, it can convert any type into a Var type;

  11. FuncThe definition is a function, and its type isfunc() interface{}
  12. Func(cmdline), the place to use needs to be seen clearly, parameters are cmdline instead cmdline() , so this notation is type conversion. After the conversion method cmdline has a method String() , in the String() method is called f() , through the JSON encoded output. This little trick is also useful in the above mentioned http.HandleFunc , Golang programmers to this is true love, we code time also need to use AH.

Insufficient

Feel this package is still for simple variables, such as shaping, string this is more useful.

    1. As already mentioned, the MAP type only supports variables where Key is a string. Other types also have to expand themselves, the problem of the extension of the lock will have to do their own. and the JSON encoding low version does not support Key is the shape of the encoding, is also a problem;
    2. VarInterface is too simple, only one String() method, basically can only output variable all content, nothing else to control, if your variable has 10,000 key value pairs, then this interface is basically not available. Say more, this is Golang design common problems, such as log packet, output type is io.Writer , and this interface only support a method Write([]byte) , want to extend the function of log package is very difficult, this also lost abstraction out of an interface meaning.
    3. The boot parameters and MemStats memory-related parameters are also appended by default in the route. I personally think that this should not add, call runtime.ReadMemStats(stats) will cause Stop the world, the total feeling is not worth it.

Summarize

See on the write, and there is no precipitate, write very messy. This package is very simple, but there are some code and design that can be used for reference. The new version of Golang has been able to parse the hash table for Key, when can this package keep up with the support?

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.