gopeek

package module
v0.0.0-...-c318af2 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jan 3, 2017 License: Apache-2.0 Imports: 8 Imported by: 0

README

gopeek

Go Report Card Build Status Coverage Status GoDoc

Peeks goroutines and helps gophers cope with those in intuitive ways such as waiting for some goroutines to change its state into waiting a lock primitive and so on.

It is mostly useful on test code now using time.Sleep to yield other goroutines a moment to make something happen. Such tests tend to take long if time.Sleep invoked many times. With gopeek you can do within the order of magnitude less time.

https://github.com/uber-go/ratelimit/pull/1#discussion-diff-78767601 motivated me solve this problem in a generalized way.

Example

import "github.com/cat2neat/gopeek"
import "github.com/maruel/panicparse/stack"

// Wait for goroutines
// - created by a func that matches "gopeek_test.TestGoPeek.*" (Regex can be used)
// - locked at a M (Any fields in stack.Gorotine can be used at user-defined)
// - blocked by channel primitives
// - the number of goroutines which satisfy the above conditions == 3
// Return goroutines that satisfy the above all conditions or
// Timeout after time.Millisecond passed if no goroutines satisfy.
gopeek.NewCondition().
       CreatedBy("gopeek_test.TestGoPeek.*").
       FilterByGo(func(g *stack.Gorotine) bool {
          return g.Signature.Locked
       }).
       Is(gopeek.StateWaitingChannel).
       EQ(3).
       Wait(time.Millisecond)

// Wait for goroutines
// - created by a func that matches "gopeek_test.TestGoPeek.*"
// - blocked by I/O (net poller) or Lock caused by sync primitives or time.Sleep
// - the number of goroutines which satisfy the above conditions == 3 or >= 6
// Return goroutines that satisfy the above all conditions or
// Timeout after time.Millisecond passed if no goroutines satisfy.
gopeek.NewCondition().
       CreatedBy("gopeek_test.TestGoPeek.*").
       In(gopeek.StateWaitingIO, gopeek.StateWaitingLock, gopeek.StateSleeping).
       FilterByGoes(func(gs []stack.Gorotine) bool {
          return len(gs) == 3 || len(gs) >= 6
       }).
       Wait(time.Millisecond)

Install

go get -u github.com/cat2neat/gopeek

Features

  • Wait for goroutines to satisfy specified conditions
  • Retrieve goroutines that satisfy specified conditions

with built-in filters and|or user-defined ones.

All filters are lazy evaluated when (Wait|Eval) called.

Usage

See the above example code or gopeek_test.go for the actual use.

Cautions

Don't use gopeek except in test code. You should be wrong if you will try to solve a real concurrency problem with gopeek.

Documentation

Overview

Package gopeek peeks goroutines and helps gophers cope with those in intuitive ways such as waiting for some goroutines to change its state into waiting a lock primitive and so on.

It is mostly useful on test code now using time.Sleep to yield other goroutines a moment to make something happen. Such tests tend to take long if time.Sleep invoked many times. With gopeek you can do within the order of magnitude less time.

Index

Constants

This section is empty.

Variables

View Source
var (
	// ErrTimeout indicates timeout happened while calling Wait.
	ErrTimeout = errors.New("Timeout occurred while waiting")
)

Functions

This section is empty.

Types

type Condition

type Condition struct {
	// contains filtered or unexported fields
}

Condition provides the way to describe what/how many goroutines exist and what state they are by using built-in|user-defined filters and retrieve goroutines that satisfy all filters or wait until there is at least one goroutine that satisfy all filters.

func NewCondition

func NewCondition(opts ...Option) *Condition

NewCondition returns a new Condition that filters goroutines based on built-in|used-defined filters added later.

func (*Condition) CreatedBy

func (c *Condition) CreatedBy(fun string) *Condition

CreatedBy adds a FilterByGo filter that return true if a goroutine's Signature.CreatedBy.Func.PkgDotName() matches fun regexp or false otherwise. It returns Condition itself for method chaining. Panic happens if regexp failed to compile fun.

func (*Condition) EQ

func (c *Condition) EQ(v int) *Condition

EQ adds a FilterByGoes filter that return true if len(goroutines) == v or false otherwise. It returns Condition itself for method chaining.

func (*Condition) Eval

func (c *Condition) Eval() ([]stack.Goroutine, error)

Eval retrieves all goroutines that currently exist and apply all filters. It returns goroutines that satisfy all filter's conditions or nil otherwise and error when stack.ParseDump failed.

func (*Condition) FilterByGo

func (c *Condition) FilterByGo(f FilterByGo) *Condition

FilterByGo adds a user-defined FilterByGo filter. It returns Condition itself for method chaining.

func (*Condition) FilterByGoes

func (c *Condition) FilterByGoes(f FilterByGoes) *Condition

FilterByGoes adds a user-defined FilterByGoes filter. It returns Condition itself for method chaining.

func (*Condition) GT

func (c *Condition) GT(v int) *Condition

GT adds a FilterByGoes filter that return true if len(goroutines) > v or false otherwise. It returns Condition itself for method chaining.

func (*Condition) In

func (c *Condition) In(states ...State) *Condition

In adds a FilterByGo filter that return true if a goroutine's state is included in states or false otherwise. It returns Condition itself for method chaining.

func (*Condition) Is

func (c *Condition) Is(state State) *Condition

Is adds a FilterByGo filter that return true if a goroutine's state == state or false otherwise. It returns Condition itself for method chaining.

func (*Condition) LT

func (c *Condition) LT(v int) *Condition

LT adds a FilterByGoes filter that return true if len(goroutines) < v or false otherwise. It returns Condition itself for method chaining.

func (*Condition) Not

func (c *Condition) Not(state State) *Condition

Not adds a FilterByGo filter that return true if a goroutine's state != state or false otherwise. It returns Condition itself for method chaining.

func (*Condition) Wait

func (c *Condition) Wait(timeout time.Duration) ([]stack.Goroutine, error)

Wait calls Eval repeatedly until Eval returns at least one goroutine or error or timeout passed. It returns goroutines that satisfy all filter's conditions or nil otherwise and error when stack.ParseDump failed or timeout happened.

type FilterByGo

type FilterByGo func(*stack.Goroutine) bool

FilterByGo returns true if a goroutine passed satisfies a condition implemented in this func or false otherwise.

type FilterByGoes

type FilterByGoes func([]stack.Goroutine) bool

FilterByGoes returns true if goroutines passed satisfies a condition implemented in this func or false otherwise.

type Option

type Option func(*Condition)

Option configures a Condition.

func WithBufSize

func WithBufSize(bs int) Option

WithBufSize returns an Option for gopeek.NewCondition that provides a initial buffer size used for storing data returned from runtime.Stack. In most cases the default(1M) is sufficient.

func WithFilterSize

func WithFilterSize(fs int) Option

WithFilterSize returns an Option for gopeek.NewCondition that provides a initial filter size. Setting this value is meory efficient if how many filters you will use is determined beforehand.

func WithYieldFunc

func WithYieldFunc(f func()) Option

WithYieldFunc returns an Option for gopeek.NewCondition that provides a function used for yielding other goroutines while waiting. The default is runtime.Gosched.

type State

type State int

State represents a state of a goroutine based on G's waitreason.

const (
	// StateIdle means a goroutine in idle.
	StateIdle State = iota
	// StateRunnable means a goroutine in runnable.
	StateRunnable
	// StateRunning means a goroutine in running.
	StateRunning
	// StateSysCall means a goroutine in calling a syscall.
	StateSysCall
	// StateWaiting means a goroutine in waiting.
	StateWaiting
	// StateDead means a goroutine in dead.
	StateDead
	// StateEnqueue means a goroutine in enqueue.
	StateEnqueue
	// StateCopyStack means a goroutine in copystack.
	StateCopyStack
	// StateSleeping means a goroutine blocked due to sleeping (time.Sleep).
	StateSleeping
	// StateWaitingChannel means a goroutine blocked due to waiting a channel.
	StateWaitingChannel
	// StateWaitingSelect means a goroutine blocked in a select clause.
	StateWaitingSelect
	// StateWaitingGCActivity means a goroutine blocked due to some GC activity.
	StateWaitingGCActivity
	// StateWaitingIO means a goroutine blocked due to network I/O.
	StateWaitingIO
	// StateWaitingLock means a goroutine blocked due to a lock primitive.
	StateWaitingLock
	// StateOther means a goroutine blocked due to some other reason.
	StateOther
)

func NewState

func NewState(state string) State

NewState returns a new State based on state.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL