Browse Source

rpc: start/stop cpu profiler

pull/205/head
Ethan Buchman 9 years ago
parent
commit
f5be3cd8f9
6 changed files with 87 additions and 32 deletions
  1. +4
    -0
      mempool/mempool.go
  2. +56
    -0
      rpc/core/dev.go
  3. +1
    -2
      rpc/core/mempool.go
  4. +19
    -1
      rpc/core/routes.go
  5. +0
    -28
      rpc/core/status.go
  6. +7
    -1
      rpc/core/types/responses.go

+ 4
- 0
mempool/mempool.go View File

@ -77,6 +77,10 @@ func NewMempool(proxyAppConn proxy.AppConn) *Mempool {
return mempool
}
func (mem *Mempool) Size() int {
return mem.txs.Len()
}
// Return the first element of mem.txs for peer goroutines to call .NextWait() on.
// Blocks until txs has elements.
func (mem *Mempool) TxsFrontWait() *clist.CElement {


+ 56
- 0
rpc/core/dev.go View File

@ -0,0 +1,56 @@
package core
import (
"fmt"
"os"
"runtime/pprof"
"strconv"
ctypes "github.com/tendermint/tendermint/rpc/core/types"
)
func UnsafeSetConfig(typ, key, value string) (*ctypes.ResultUnsafeSetConfig, error) {
switch typ {
case "string":
config.Set(key, value)
case "int":
val, err := strconv.Atoi(value)
if err != nil {
return nil, fmt.Errorf("non-integer value found. key:%s; value:%s; err:%v", key, value, err)
}
config.Set(key, val)
case "bool":
switch value {
case "true":
config.Set(key, true)
case "false":
config.Set(key, false)
default:
return nil, fmt.Errorf("bool value must be true or false. got %s", value)
}
default:
return nil, fmt.Errorf("Unknown type %s", typ)
}
return &ctypes.ResultUnsafeSetConfig{}, nil
}
var profFile *os.File
func UnsafeStartCPUProfiler(filename string) (*ctypes.ResultUnsafeCPUProfiler, error) {
var err error
profFile, err = os.Create(filename)
if err != nil {
return nil, err
}
err = pprof.StartCPUProfile(profFile)
if err != nil {
return nil, err
}
return &ctypes.ResultUnsafeCPUProfiler{}, nil
}
func UnsafeStopCPUProfiler() (*ctypes.ResultUnsafeCPUProfiler, error) {
pprof.StopCPUProfile()
profFile.Close()
return &ctypes.ResultUnsafeCPUProfiler{}, nil
}

+ 1
- 2
rpc/core/mempool.go View File

@ -41,6 +41,5 @@ func UnconfirmedTxs() (*ctypes.ResultUnconfirmedTxs, error) {
}
func NumUnconfirmedTxs() (*ctypes.ResultUnconfirmedTxs, error) {
txs := mempoolReactor.Mempool.Reap()
return &ctypes.ResultUnconfirmedTxs{len(txs), txs[:0]}, nil
return &ctypes.ResultUnconfirmedTxs{N: mempoolReactor.Mempool.Size()}, nil
}

+ 19
- 1
rpc/core/routes.go View File

@ -24,7 +24,9 @@ var Routes = map[string]*rpc.RPCFunc{
"unconfirmed_txs": rpc.NewRPCFunc(UnconfirmedTxsResult, ""),
"num_unconfirmed_txs": rpc.NewRPCFunc(NumUnconfirmedTxsResult, ""),
"unsafe_set_config": rpc.NewRPCFunc(UnsafeSetConfigResult, "type,key,value"),
"unsafe_set_config": rpc.NewRPCFunc(UnsafeSetConfigResult, "type,key,value"),
"unsafe_start_cpu_profiler": rpc.NewRPCFunc(UnsafeStartCPUProfilerResult, "filename"),
"unsafe_stop_cpu_profiler": rpc.NewRPCFunc(UnsafeStopCPUProfilerResult, ""),
}
func SubscribeResult(wsCtx rpctypes.WSRPCContext, event string) (ctypes.TMResult, error) {
@ -146,3 +148,19 @@ func UnsafeSetConfigResult(typ, key, value string) (ctypes.TMResult, error) {
return r, nil
}
}
func UnsafeStartCPUProfilerResult(filename string) (ctypes.TMResult, error) {
if r, err := UnsafeStartCPUProfiler(filename); err != nil {
return nil, err
} else {
return r, nil
}
}
func UnsafeStopCPUProfilerResult() (ctypes.TMResult, error) {
if r, err := UnsafeStopCPUProfiler(); err != nil {
return nil, err
} else {
return r, nil
}
}

+ 0
- 28
rpc/core/status.go View File

@ -1,9 +1,6 @@
package core
import (
"fmt"
"strconv"
ctypes "github.com/tendermint/tendermint/rpc/core/types"
"github.com/tendermint/tendermint/types"
)
@ -31,28 +28,3 @@ func Status() (*ctypes.ResultStatus, error) {
LatestBlockHeight: latestHeight,
LatestBlockTime: latestBlockTime}, nil
}
func UnsafeSetConfig(typ, key, value string) (*ctypes.ResultUnsafeSetConfig, error) {
switch typ {
case "string":
config.Set(key, value)
case "int":
val, err := strconv.Atoi(value)
if err != nil {
return nil, fmt.Errorf("non-integer value found. key:%s; value:%s; err:%v", key, value, err)
}
config.Set(key, val)
case "bool":
switch value {
case "true":
config.Set(key, true)
case "false":
config.Set(key, false)
default:
return nil, fmt.Errorf("bool value must be true or false. got %s", value)
}
default:
return nil, fmt.Errorf("Unknown type %s", typ)
}
return &ctypes.ResultUnsafeSetConfig{}, nil
}

+ 7
- 1
rpc/core/types/responses.go View File

@ -70,6 +70,8 @@ type ResultUnconfirmedTxs struct {
type ResultUnsafeSetConfig struct{}
type ResultUnsafeCPUProfiler struct{}
type ResultSubscribe struct {
}
@ -109,7 +111,9 @@ const (
ResultTypeEvent = byte(0x82)
// 0xa bytes for testing
ResultTypeUnsafeSetConfig = byte(0xa0)
ResultTypeUnsafeSetConfig = byte(0xa0)
ResultTypeUnsafeStartCPUProfiler = byte(0xa1)
ResultTypeUnsafeStopCPUProfiler = byte(0xa2)
)
type TMResult interface {
@ -133,4 +137,6 @@ var _ = wire.RegisterInterface(
wire.ConcreteType{&ResultUnsubscribe{}, ResultTypeUnsubscribe},
wire.ConcreteType{&ResultEvent{}, ResultTypeEvent},
wire.ConcreteType{&ResultUnsafeSetConfig{}, ResultTypeUnsafeSetConfig},
wire.ConcreteType{&ResultUnsafeCPUProfiler{}, ResultTypeUnsafeStartCPUProfiler},
wire.ConcreteType{&ResultUnsafeCPUProfiler{}, ResultTypeUnsafeStopCPUProfiler},
)

Loading…
Cancel
Save