objswm

package module
v0.0.1 Latest Latest
Warning

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

Go to latest
Published: Mar 17, 2025 License: MIT Imports: 6 Imported by: 0

README

objswm

Go Reference Go Report Card

A memory-optimized, fast, and thread-safe object pool for Go applications.

Features

  • Memory Efficient: Stores objects directly without wrapper structures
  • Thread-Safe: Fully concurrent access support with no race conditions
  • TTL Support: Automatic time-based object expiration
  • Configurable: Flexible sizing, blocking behavior, and timeouts
  • Generic: Type-safe implementation using Go generics

Installation

go get github.com/flaticols/objswm

Performance

ObjectPool is designed for high-performance scenarios where object creation is expensive.

BenchmarkObjectGet/Small-Pool
BenchmarkObjectGet/Small-Pool-10                39542130                30.26 ns/op            0 B/op          0 allocs/op
BenchmarkObjectGet/Medium-Pool
BenchmarkObjectGet/Medium-Pool-10               40135009                29.83 ns/op            0 B/op          0 allocs/op
BenchmarkObjectGet/Large-Pool
BenchmarkObjectGet/Large-Pool-10                39074690                30.03 ns/op            0 B/op          0 allocs/op
BenchmarkObjectGet/With-TTL
BenchmarkObjectGet/With-TTL-10                  12790063                93.55 ns/op            0 B/op          0 allocs/op
BenchmarkObjectGet/Unlimited-Pool
BenchmarkObjectGet/Unlimited-Pool-10            40188382                29.67 ns/op            0 B/op          0 allocs/op

Quick Start

package main

import (
    "context"
    "fmt"
    "time"

    "github.com/yourusername/objswm"
)

type Connection struct {
    ID int
}

func main() {
    // Create a new pool with default configuration
    pool, err := objswm.NewObjectPool(
        func() (Connection, error) {
            // Simulate expensive connection creation
            time.Sleep(10 * time.Millisecond)
            return Connection{ID: rand.Intn(1000)}, nil
        },
        objswm.DefaultPoolConfig(),
    )
    if err != nil {
        panic(err)
    }
    defer pool.Close()

    // Get an object from the pool
    ctx := context.Background()
    conn, err := pool.Get(ctx)
    if err != nil {
        panic(err)
    }

    // Use the connection
    fmt.Printf("Using connection: %d\n", conn.ID)

    // Return it to the pool when done
    pool.Put(conn)
}

Configuration

ObjectPool is highly configurable to meet different use cases:

config := objswm.PoolConfig{
    InitialSize:  20,     // Pre-create 20 objects
    MaxSize:      100,    // Pool will never exceed 100 objects
    MaxIdle:      50,     // Keep at most 50 idle objects
    TTL:          30 * time.Second,  // Objects expire after 30 seconds
    AllowBlock:   true,   // Get() will block when pool is empty
    BlockTimeout: 5 * time.Second,   // Wait up to 5 seconds for an object
}

pool, err := objswm.NewObjectPool(factory, config)

Best Practices

  1. Right-Size Your Pool: Set InitialSize, MaxSize, and MaxIdle based on your workload patterns.
  2. Use TTL for Long-Lived Pools: Enable TTL for long-lived connections that might go stale.
  3. Clean Resource Disposal: Ensure the pool's Close() method is called to properly dispose of resources.
  4. Error Handling: Always check errors from Get() operations, especially with non-blocking pools.

Advanced Usage

Wait for Available Objects
// Create a context with a specific timeout
ctx, cancel := context.WithTimeout(context.Background(), 500*time.Millisecond)
defer cancel()

// Get will respect the context deadline
obj, err := pool.Get(ctx)
if err != nil {
    if errors.Is(err, context.DeadlineExceeded) {
        // Handle timeout specifically
    }
    // Handle other errors
}
Custom Object Lifecycle

For objects that require specific initialization or cleanup:

factory := func() (Database, error) {
    db := Database{}
    err := db.Connect("localhost:5432")
    return db, err
}

pool, _ := objswm.NewObjectPool(factory, objswm.DefaultPoolConfig())

// When application shuts down
pool.Close() // Will release all objects

How It Works

ObjectPool uses a channel-based design for thread safety and efficient blocking operations:

  1. Object Storage: Objects are stored directly in a channel without wrappers
  2. Memory Efficiency: TTL tracking uses unsafe pointers to avoid unnecessary allocations
  3. Concurrency: Atomic operations and mutexes for thread-safe counting and state management
  4. Expiration: A background goroutine periodically removes expired objects

License

MIT License - See LICENSE for details.

Documentation

Overview

Package objswm provides a memory-optimized, fast, thread-safe object pool implementation.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type Factory

type Factory[T any] func() (T, error)

Factory is a function that creates a new instance of the pooled object.

type ObjectPool

type ObjectPool[T any] struct {
	// contains filtered or unexported fields
}

ObjectPool is a memory-optimized, fast, thread-safe pool of objects.

func NewObjectPool

func NewObjectPool[T any](factory Factory[T], config PoolConfig) (*ObjectPool[T], error)

NewObjectPool creates a new thread-safe object pool.

func (*ObjectPool[T]) Close

func (p *ObjectPool[T]) Close()

Close shuts down the pool and discards all objects.

func (*ObjectPool[T]) Get

func (p *ObjectPool[T]) Get(ctx context.Context) (T, error)

Get retrieves an object from the pool. If the pool is empty:

  • If AllowBlock is true, it waits until an object is available or BlockTimeout is reached
  • If AllowBlock is false, it creates a new object if below MaxSize, or returns an error

func (*ObjectPool[T]) IdleCount

func (p *ObjectPool[T]) IdleCount() int

IdleCount returns the number of idle objects in the pool.

func (*ObjectPool[T]) Put

func (p *ObjectPool[T]) Put(obj T)

Put returns an object to the pool. If the pool is full or closed, the object may be discarded.

func (*ObjectPool[T]) Size

func (p *ObjectPool[T]) Size() int

Size returns the current total size of the pool (in use + idle).

type PoolConfig

type PoolConfig struct {
	// InitialSize is the number of objects to pre-create when the pool is initialized.
	InitialSize int

	// MaxSize is the maximum number of objects the pool can hold.
	// If set to 0, the pool has no size limit.
	MaxSize int

	// MaxIdle is the maximum number of idle objects to keep in the pool.
	// If set to 0, all idle objects are kept until MaxSize is reached.
	MaxIdle int

	// TTL is the time-to-live for an idle object before it's removed from the pool.
	// If set to 0, objects don't expire.
	TTL time.Duration

	// AllowBlock determines if Get() should block when the pool is empty.
	// If false, Get() will return an error when no objects are available.
	AllowBlock bool

	// BlockTimeout is the maximum time to wait for an object to become available.
	// If set to 0 and AllowBlock is true, Get() will wait indefinitely.
	BlockTimeout time.Duration
}

PoolConfig contains configuration options for the ObjectPool.

func DefaultPoolConfig

func DefaultPoolConfig() PoolConfig

DefaultPoolConfig returns a default configuration for ObjectPool.

Jump to

Keyboard shortcuts

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