autopool

package
v1.0.2 Latest Latest
Warning

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

Go to latest
Published: Apr 1, 2020 License: Apache-2.0 Imports: 5 Imported by: 0

Documentation

Overview

Package autopool provides a collection of sync.Pool(s) that holds values that are collected when they go out of scope vs. a standard sync.Pool that requires a .Put(). This is useful when the value goes out of scope in a package you do not control, like gRPC. If the value is under your control, a standard sync.Pool is superior in every way. Use when the struct holds a map or slice that is sizeable (> 50KiB). Also, YOU MUST KNOW that the third-party package does not hold a reference to any of the fields when the pointer's value is garbage collected. Either look at the code or use --race to verify.

Usage is simple:

	...
	// Create our pool and assign it to "s", which represents a gRPC service.
	s.pool = New()
	s.outputID = p.Add(
		func() interface{} {
			&pb.Output{
				Payload: make([]byte, 100), // Presizing when I need to create new ones because the pool is empty.
			},
		},
	)
	...

	// Use our pool to construct out Output and allow reclaining after gRPC finishes with our Output object.
	func (s *service) Call(ctx context.Context, in *pb.Input) (*pb.Output, error) {
		output := s.pool.Get(s.outputID).(*pb.Output)
		resetOutput(output)

		...
		return output, nil
	}
	...

	// resetOutput prepates our object for reuse by setting the zero values and making our Payload
	// have a 0 len (but not a 0 capacity). If your pointer to a struct is for a Protocol Buffer,
	// you cannot use the built in .Reset(), as this destroys the buffers.
	func resetOutput(o *pb.Output) {
		o.Id = 0
		o.User = ""
		o.Payload = o.Payload[0:0]
	}

Final note: this code is suseptible to finalizer hijacking by other slow code in other finalizers.
If using other finalizers that are non-trivial, sping their code off in a goroutine to avoid slowing
this down.  This finalizer is trivial, two atomic additions and a pool.Put() call.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type Pool

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

Pool provides a sync.Pool where GC'd objects are put back into the Pool automatically.

func New

func New() *Pool

New is the constructor for Pool.

func (*Pool) Add

func (p *Pool) Add(f func() interface{}) int

Add adds support for type returned by f(). This must be a pointer to a struct. Calling this after the first call to Get() or Put() is a race condition.

func (*Pool) Get

func (p *Pool) Get(i int) interface{}

Get retrieves a value from a pool that has the type reflect.Type. This will panic if that type is an unsupported type or was not a sub type of the value that was provided by the function passed to New().

func (*Pool) IntLookup

func (p *Pool) IntLookup(t reflect.Type) int

IntLookup will return the id used in Get() to fetch a value of this type. Returns -1 if the Pool does not suppor the type.

func (*Pool) Stats

func (p *Pool) Stats() [][2]uint64

Stats returns the number of misses (when we didn't have anything in a pool) and total attempts for each type we are storing. So if Add(<type>) returned 10, Stats()[10] will return a [2]uint64, with position 0 storing the misses and postion 1 the total.

Directories

Path Synopsis

Jump to

Keyboard shortcuts

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