SkillAgentSearch skills...

It

A collection of helpful error handling, performance measuring, execution retrial, benchmarking & other useful patterns for golang under one package.

Install / Use

/learn @theHamdiz/It
About this skill

Quality Score

0/100

Supported Platforms

Universal

README

it 🎭

Because we kinda need this shit daily and we know it!

GoDoc Go Report Card License: The Whatever, Just Take It License Tests Panic Rate

Installation 🚀

go get github.com/theHamdiz/it

Core Features

Error Handling (Because panic() is a lifestyle)

import "github.com/theHamdiz/it"

// The "I believe in miracles" approach
config := it.Must(LoadConfig())

// The "let's log and pray" method
user := it.Should(GetUser())

// Maybe we'll connect to the database... eventually
maybeConnect := it.Could(func() (*sql.DB, error) {
    return sql.Open("postgres", "postgres://procrastinator:later@localhost")
})

// Sometime later, when we feel ready...
db := maybeConnect() // First call actually does the work
alsoDb := maybeConnect() // Returns same result, wasn't worth trying again anyway

if value, ok := it.Might(maybeThisWorks); ok {
    // Nice, we got something
} else {
    // No biggie, we weren't counting on it anyway
}

// The "cover your tracks" strategy
err := it.WrapError(dbErr, "database had an existential crisis",
    map[string]any{"attempt": 42, "mood": "gothic"})

SafeGo - Panic-Proof Goroutines

Because letting goroutines die alone in the dark is just cruel.

import "github.com/theHamdiz/it"

// Fire and forget (but not really)
it.SafeGo(func() {
    DoSomethingDangerous()  // We'll catch you if you fall
})

// For the context-aware crowd
it.SafeGoWithContext(ctx, func(ctx context.Context) {
    ResponsiblyDangerous(ctx)  // Safety first, but make it contextual
})

Includes automatic panic recovery and proper context propagation. Perfect for when you want to live dangerously but with a safety net.

Now go forth and spawn goroutines without fear of them taking your program down with them.

Logging (Now with proper prefixes)

import "github.com/theHamdiz/it"

it.Trace("Like println() but fancier")
it.Debug("For when you're feeling verbose")
it.Info("FYI: Something happened")
it.Warn("Houston, we have a potential problem")
it.Error("Everything is fine 🔥")
it.Audit("For when legal is watching")

// Structured logging (because JSON makes everything enterpriseTM)
it.StructuredInfo("API Call", map[string]any{
    "status": 200,
    "response_time": "too long",
    "excuse": "network congestion"
})

Sub-Packages (For the Control Freaks)

Pool - Object Recycling Center

import "github.com/theHamdiz/it/pool"

pool_ := pool.NewPool(func() *ExpensiveObject {
    // Save the environment, reuse your objects
    return &ExpensiveObject{}
})
obj := pool_.Get()
// Return your shopping cart
defer pool_.Put(obj)

Debouncer - Function Anger Management

import "github.com/theHamdiz/it/debouncer"

calm := debouncer.NewDebouncer(100 * time.Millisecond)
relaxedFunc := calm.Debounce(func() {
    // Now with less spam
    NotifyEveryone("Updates!")
})

Load Balancer - Work Distribution Committee

import "github.com/theHamdiz/it/lb"

// Democratic work distribution
lb_ := lb.NewLoadBalancer(10)
err := lb_.Execute(ctx, func() error {
    // Share the pain
    return HeavyLifting()
})

Benchmarker - The Performance Theater

Because measuring performance makes you feel better about your terrible code.

import "github.com/theHamdiz/it/bm"

// Run your function until the numbers look good
result := bm.Benchmark("definitely-fast", 1000, func() {
    SuperOptimizedCode() // yeah right
})

// Or collect your own timings when you don't trust us
timings := []time.Duration{...}
result := bm.AnalyzeBenchmark("probably-fast", timings)

// Slack-friendly output for bragging rights
fmt.Println(result) // Screenshots or it didn't happen

Gives you min, max, average, median, and that standard deviation thing nobody really understands. Perfect for making your code look faster than it is in production.

JSON support included because apparently everything needs to be in a dashboard these days.

Now go forth and benchmark the hell out of that O(n2) algorithm you're trying to justify.

Exponential Backoff - Professional Failure Management

Because at some point, everything fails. Might as well be ready for it.

import "github.com/theHamdiz/it/retry"

// For when you're feeling optimistic
cfg := retry.DefaultRetryConfig()

// For when you know it's going to be rough
cfg := retry.Config{
    Attempts:     5,
    InitialDelay: time.Second,
    MaxDelay:     30 * time.Second,
    Multiplier:   2.0,
    RandomFactor: 0.1,
}

// Actually doing the thing
result, err := retry.WithBackoff(ctx, cfg, func(ctx context.Context) (string, error) {
    return CallThatFlakyService()
})

Implements exponential backoff with jitter because hammering a failing service is both rude and stupid. Comes with sane defaults for when you're too lazy to think.

Default config gives you 3 attempts with increasing delays, starting at 100ms and capping at 10s. Add some randomness to avoid the thundering herd, because your systems have enough problems already.

Now go forth and embrace failure like a professional.

Shutdown Manager - Graceful Program Retirement

Because even software needs a dignified exit strategy.

import "github.com/theHamdiz/it/sm"

// Set up the end times
sm_ := sm.NewShutdownManager()

// Add some last wishes
sm_.AddAction(
    "save-data",
    func(ctx context.Context) error {
        return db.Close()
    },
    5 * time.Second,
    true, // This one matters
)

// Start watching for the end
sm_.Start()

// Wait for the inevitable
if err := sm_.Wait(); err != nil {
    log.Fatal("Failed to die gracefully:", err)
}
// Or just use the global shortcut (for the pragmatists)
import "github.com/theHamdiz/it"

it.GracefulShutdown(ctx, server, 30*time.Second, done, func() {
    // Your last words here
})

// Need a phoenix-like rebirth?
it.GracefulRestart(ctx, server, 30*time.Second, done, func() {
    // Rise from the ashes
})

Handles shutdown signals (SIGINT, SIGTERM by default), manages cleanup tasks with timeouts, and ensures your program dies with dignity instead of just crashing.

Critical actions fail the whole shutdown if they fail, non-critical ones just log and continue, because some things aren't worth dying twice over.

Perfect for when you need your program to clean up after itself instead of leaving a mess for the OS to deal with.

Rate Limiter - Traffic Control for Functions

// The proper way (for when you need full control)
import "github.com/theHamdiz/it/rl"

limiter := rl.NewRateLimiter(time.Second, 10)
defer limiter.Close()

err := limiter.Execute(ctx, func() error {
    return DoSomethingFast()  // But not too fast
})

// Or better yet, with actual returns
result, err := rl.ExecuteRateLimited(limiter, ctx, func() (string, error) {
    return GetSomethingQuickly()  // Responsibly quick
})
// The shortcut (for the rest of us)
import "github.com/theHamdiz/it"

// Turn any function into a well-behaved citizen
chillVersion := it.RateLimiter(time.Second, func() string {
    return IWouldSpamThisIfICould()
}).(func() string)

// Usage:
result := chillVersion()  // Now properly paced

// Waiting (but not forever)
success := it.WaitFor(5*time.Second, func() bool {
    return systemIsReady()  // Are we there yet?
})

if !success {
    // Time to give up and go home
}

Perfect for when your functions need to learn some self-control, without all the ceremony.

Now go forth and rate limit responsibly. Your servers will thank you.

Time Keeper - Time Tracking for the Obsessed

Because if you're not measuring it, you're just guessing.

import "github.com/theHamdiz/it/tk"

// Basic timing
tk_ := tk.NewTimeKeeper("database-query").Start()
defer tk_.Stop()

// With a callback for the micromanagers
tk_ := tk.NewTimeKeeper("expensive-operation",
    tk.WithCallback(func(d time.Duration) {
        metrics.Record("too-slow", d)
    }),
).Start()

// Quick one-liner for the lazy
result := tk.TimeFn("important-stuff", func() string {
    return DoTheWork()
})

// Async timing for the parallel obsessed
atk := tk.NewAsyncTimeKeeper("batch-process")
for task := range tasks {
    atk.Track(func() { process(task) })
}
durations := atk.Wait()
// The dirty shortcut approach!!
import "github.com/theHamdiz/it"

result := it.TimeFunction("critical-operation", func() string {
    return DoSomethingWorthTiming()
})

// Block timing with defer
defer it.TimeBlock("expensive-stuff")()

// Custom timing callback
it.TimeFunctionWithCallback("important-task",
    func() string {
        return ExpensiveOperation()
    },
    func(d time.Duration) {
        if d > time.Second {
            alertSomeone()  // Someone's being slow
    },
)

// Parallel timing (for the impatient)
durations := it.TimeParallel("batch-process",
    func() { task1() },
    func() { task2() },
    func() { task3() },
)
// Now you know which one to blame

Times your operations, logs the results, and lets you obsess over performance with minimal effort. Supports both synchronous and async operations, because sometimes you need to time multiple failures simultaneously.

Perfect for when you need to prove that it's not your code that's slow, it's everyone else's.

Circuit Breaker - Your Code's Emotional Support System

Because sometimes your dependencies need a time-out, just like your ex.

import "github.com/theHamdiz/it/cb"

// Create a breaker that gives up after 3 failures
// and needs 30 seconds of alone time
breaker := cb.NewCircuitBreaker(3, 30*time.Second)

// Wrap your flaky 
View on GitHub
GitHub Stars429
CategoryDevelopment
Updated3d ago
Forks3

Languages

Go

Security Score

100/100

Audited on Mar 27, 2026

No findings