gotcha

package module
v1.1.0 Latest Latest
Warning

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

Go to latest
Published: Mar 20, 2021 License: MIT Imports: 10 Imported by: 0

README

Gotcha 🎯

lint test report version license godoc

go get -u github.com/1pkg/gotcha

blog post article

Introduction

Gotcha seamlessly patches go runtime to provide a convenient way to track amount of heap allocated bytes, objects, calls per goroutine.

package main

import (
	"context"
	"fmt"

	"github.com/1pkg/gotcha"
)

func main() {
	var v []int
	gotcha.Trace(context.Background(), func(ctx gotcha.Context) {
		v = make([]int, 100)
		b, o, c := ctx.Used() // bytes objects calls
		fmt.Println("initial allocation", b, o, c) // will print "initial allocation 824 101 2"
		gotcha.Trace(ctx, func(ctx gotcha.Context) {
			v = make([]int, 5000)
			b, o, c := ctx.Used() // bytes objects calls
			fmt.Println("derived allocation", b, o, c) // will print "derived allocation 40024 5001 2"
		})
		select {
		case <-ctx.Done():
			b, o, c := ctx.Used() // bytes objects calls
			fmt.Println("total allocations", b, o, c) // will print "total allocations 41840 5116 15"
		default:
			panic("unreachable")
		}
	}, gotcha.ContextWithLimitBytes(gotcha.KiB)) // set context allocation limit to one kilobit
	// note that prints above might be slightly different on your machine
	fmt.Println(len(v)) // 5000
}

Internals

Gotcha exposes function Track that tracks memory allocations for provided Tracer function. All traced allocations are attached to the single parameter of this tracer function Context object. Gotcha context fully implements context.Context interface and could be used to cancel execution if provided limits were exceeded. Gotcha supports nested tracing by providing gotcha context as the parent context for derived Tracer; then gotcha tracing context methods will also be targeting parent context as well as derived context.

Note that in order to work gotcha uses 1pkg/gomonkey based on bou.ke/monkey and 1pkg/golocal based on modern-go/gls packages to patch runtime mallocgc allocator entrypoint and trace per goroutine context limts. This makes gotcha inherits the same list of restrictions as modern-go/gls and bou.ke/monkey has.

It's important to know that gotcha is not trying to measure momentary memory usage which involves GC tracing into the act, keeping track on GC is rather a big task on it's own and out of scope for gotcha. Instead gotcha traces all memory allocated in monotonic increasing fashion where is only allocations are taken into consideration and all deallocations are discarded.

Note: despite that gotcha might work on your machine, it's super unsafe. It uses code assumption about mallocgc, depends on calling convention that could be changed, uses platform specific machine code direcly, etc. Alsp gotcha isn't expected to work on anything apart from amd64 with latest go runtime. So I highly discourage anyone to use gotcha in any production code or maybe even any code at all as it's extremely unsafe and not reliable and won't be supported in foreseeable future. Nevertheless, one could probably imagine reasonable use cases for this concept library in go benchmarks or test. Finally it's worth to say that primary intention to develop gotcha was learning and that gotcha doesn't have comprehensive tests coverage and support and not ready for any serious use case anyway

Licence

Gotcha is licensed under the MIT License.
See LICENSE for the full license text.

Documentation

Index

Constants

View Source
const (
	Kibibyte int64 = 1024
	KiB            = Kibibyte
	Mebibyte       = Kibibyte * 1024
	MiB            = Mebibyte
	Gibibyte       = Mebibyte * 1024
	GiB            = Gibibyte
	Tebibyte       = Gibibyte * 1024
	TiB            = Tebibyte
	Pebibyte       = Tebibyte * 1024
	PiB            = Pebibyte
	Exbibyte       = Pebibyte * 1024
	EiB            = Exbibyte
)

nolint

View Source
const (
	Kilobyte int64 = 1000
	KB             = Kilobyte
	Megabyte       = Kilobyte * 1000
	MB             = Megabyte
	Gigabyte       = Megabyte * 1000
	GB             = Gigabyte
	Terabyte       = Gigabyte * 1000
	TB             = Terabyte
	Petabyte       = Terabyte * 1000
	PB             = Petabyte
	Exabyte        = Petabyte * 1000
	EB             = Exabyte
)

nolint

View Source
const (
	Kilo     int64 = 1000
	Mega           = Kilo * 1000
	Giga           = Mega * 1000
	Tera           = Giga * 1000
	Peta           = Tera * 1000
	Exa            = Peta * 1000
	Infinity       = -1
)

nolint

Variables

This section is empty.

Functions

func Trace

func Trace(ctx context.Context, t Tracer, opts ...ContextOpt)

Trace starts memory tracing for provided tracer function. Note that trace function could be cobined with each other by providing gotcha context to child trace function.

Types

type Context

type Context interface {
	context.Context
	String() string
	Tracker
}

Context defines gotcha context type which is union between `context.Context` and `Tracker` that additionally could be stringified.

func NewContext

func NewContext(parent context.Context, opts ...ContextOpt) Context

NewContext creates new gotcha context instance from provided parent context and list of context limit options. By default next limits are used: - bytes: 64 * MiB - objects: Infinity - calls: Infinity Note that if parent context is gotcha context then Add, Remains and Exceeded will also target parent context as well which is useful if nested tracking is required.

type ContextLimitsExceeded

type ContextLimitsExceeded struct {
	Context Context
}

ContextLimitsExceeded defines error type for context limit exceeded.

func (ContextLimitsExceeded) Error

func (err ContextLimitsExceeded) Error() string

type ContextOpt

type ContextOpt func(*gotchactx)

ContextOpt defines gotcha context limit options that could be applied to gotchactx.

func ContextWithLimitBytes

func ContextWithLimitBytes(lbytes int64) ContextOpt

ContextWithLimitBytes defines allocation limit bytes gotcha context option.

func ContextWithLimitCalls

func ContextWithLimitCalls(lcalls int64) ContextOpt

ContextWithLimitCalls defines allocation limit calls gotcha context option.

func ContextWithLimitObjects

func ContextWithLimitObjects(lobjects int64) ContextOpt

ContextWithLimitObjects defines allocation limit objects gotcha context option.

type Tracer

type Tracer func(Context)

Tracer defines function type that will be traced by gotcha it accepts gotcha context that will be seamlessly tracking all allocations inside tracer function.

type Tracker

type Tracker interface {
	Add(bytes, objects, calls int64)
	Used() (bytes, objects, calls int64)
	Limits() (lbytes, lobjects, lcalls int64)
	Remains() (rbytes, robjects, rcalls int64)
	Exceeded() bool
	Reset()
}

Tracker defines memory limit tracker type that is capble to track bytes, objects and calls allocations update, reset and compare them against provided limits.

Jump to

Keyboard shortcuts

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