Learning Go: expvar in RPC server

It is great to build RPC upon HTTP, so we can use Web browsers to test/debug a RPC server.  If an RPC server is built using Go’s RPC package and is over HTTP, we can check its states (how many times every method has been invoked) by following the URL: http://<ip&gt;:<port>/debug/rpc.

This is good, but not enough in many cases.  We might want to add more counters than those for method invocations.  We might also want browse-able variables other than counters of integer type, including float, string and map.  In Go, these can be handled by the expvar package, which export variables values through HTTP.  If an RPC server (is also an HTTP server)  have the expvar package linked (imported), we would be able to following http://<ip&gt;:<port>/debug/vars to check exported variables’ values.

An example RPC server follows:

package main

import (
 "fmt"
 "net/rpc"
 "net/http"
 "expvar"
)

var CountPageFeatureRequest expvar.Int

type ExtractPageFeaturesRequest struct {
 PageURL string
 Title string
 Body string
}

type ExtractPageFeaturesResponse struct {
 TitleKeywords []string
 BodyKeywords []string
}

type PageFeatureService int

func (pageServer *PageFeatureService) ExtractPageFeatures(
 args *ExtractPageFeaturesRequest,
 reply *ExtractPageFeaturesResponse) error {
 reply.TitleKeywords = []string{"apple", "orange"}
 reply.BodyKeywords = nil
 CountPageFeatureRequest.Add(1)
 return nil
}

func main() {
 CountPageFeatureRequest := new(expvar.Int)
 expvar.Publish("CountPageFeatureRequest", CountPageFeatureRequest)

pageServer := new(PageFeatureService)
 rpc.Register(pageServer)
 rpc.HandleHTTP()

if err := http.ListenAndServe(":1234", nil); err != nil {
 fmt.Println(err.Error())
 }
}