jet

package module
v0.1.0 Latest Latest
Warning

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

Go to latest
Published: May 27, 2026 License: MIT Imports: 45 Imported by: 0

README

jet

Go Reference CI Go Report Card Go Version

A pragmatic Go toolkit for building microservices — so you stop rewriting the same logger setup, graceful shutdown, database pool and Kafka consumer in every service.

jet is extracted from an internal toolkit that has been running 20+ production services for several years. It favors boring, explicit building blocks over magic.

Install

go get github.com/zloevil/jet

Requires Go 1.26+.

What's inside

Package What it gives you
jet (root) Structured logger (log/slog-based), typed config loader, request context, AppError model, healthcheck, JWT, crypto, validators, watchdog, generics helpers
jet/cluster Service lifecycle (Bootstrap + CLI), config loading, DB migrations
jet/goroutine Panic-safe goroutines and error groups
jet/retry Bounded retry with exponential backoff + jitter
jet/kafka Kafka producer/subscriber (segmentio/kafka-go) with SASL, workers, context propagation
jet/http, jet/grpc HTTP (gorilla/mux) and gRPC servers with middleware
jet/storages/pg PostgreSQL via GORM + JSONB/paging helpers
jet/storages/{redis,mongodb,clickhouse,migration,minio,aerospike} Storage adapters
jet/event, jet/batch In-process event bus, batch writer
jet/monitoring, jet/profile Prometheus metrics, pprof server
jet/aws/{s3,sqs}, jet/elasticsearch, … Additional integrations

Quick start

A minimal service. cluster wires config loading, signal handling and ordered shutdown around your Bootstrap.

package main

import (
	"context"
	"log"

	"github.com/zloevil/jet/cluster"
)

type Config struct {
	HTTP struct{ Port string }
}

type App struct{}

func (a *App) Init(ctx context.Context, cfg any) error {
	c := cfg.(*Config)
	_ = c // build dependencies here
	return nil
}

func (a *App) Start(ctx context.Context) error {
	// start background processes (servers, consumers, …)
	return nil
}

func (a *App) Close(ctx context.Context) {
	// release resources
}

func main() {
	svc := cluster.New[Config]("my-service", &App{})
	if err := svc.Execute(); err != nil { // runs the service CLI (db-up/db-down added when migrations are configured)
		log.Fatal(err)
	}
}

Building blocks

Logging
logger := jet.InitLogger(&jet.LogConfig{Level: jet.InfoLevel, Format: jet.FormatterJson})

log := jet.L(logger)
log.Cmp("orders").Mth("Create").C(ctx).F(jet.KV{"id": id}).Inf("order created")

CLogger is a chainable, context-aware wrapper over log/slog. Many jet components accept a jet.CLoggerFunc (func() jet.CLogger):

logFn := func() jet.CLogger { return jet.L(logger) }
Config

YAML files with environment-variable overrides, into your own typed struct:

cfg, err := jet.NewConfigLoader[Config]().WithPath("./config.yml").WithPrefix("MYSVC").Load()
Errors

AppError carries a code, type (business/system), request context, HTTP/gRPC status hints and structured fields:

return jet.NewAppErrBuilder("ORD-001", "order not found: %s", id).
	Business().C(ctx).F(jet.KV{"id": id}).Err()

if appErr, ok := jet.IsAppErr(err); ok {
	_ = appErr.Code() // "ORD-001"
}
PostgreSQL
db, err := pg.Open(&pg.DbConfig{
	Host: "localhost", Port: "5432", User: "app", Password: "secret", DBName: "app",
}, logFn)
Kafka
broker := kafka.NewBroker(logFn)
_ = broker.Init(ctx, &kafka.BrokerConfig{Url: "localhost:9092"})

_ = broker.AddSubscriber(ctx,
	kafka.NewTopicCfgBuilder("orders").Build(),
	kafka.NewSubscriberCfgBuilder().GroupId("my-service").Build(),
	func(payload []byte) error { /* handle message */ return nil },
)

_ = broker.Start(ctx)
defer broker.Close(ctx)
HTTP / gRPC
httpSrv := http.NewHttpServer(&http.Config{Port: "8080"}, logFn)
httpSrv.Listen()

grpcSrv, _ := grpc.NewServer("my-service", logFn, &grpc.ServerConfig{Host: "0.0.0.0", Port: "50051"})
_ = grpcSrv.Listen(ctx)

Testing

go test ./...                      # unit tests
go test -tags integration ./...    # integration tests (need real Postgres/Kafka/etc.)

Integration tests are guarded by the integration build tag and require the corresponding services to be running.

AI agents

The .agents/ directory ships two expert subagent definitions for building services on top of jet. They encode the toolkit's API (verified against this source) and its conventions — layering, error model, lifecycle, observability — so an agent can scaffold and extend a service without rediscovering the patterns each time.

Agent Use it for
jet-service-agent Domain / business microservices: a gRPC/HTTP service owning business logic and relational data, in the layered cmd → bootstrap → transport / usecase / domain / repository style.
jet-gateway-agent Gateway / external-integration services: fronting an external protocol behind an internal gRPC/HTTP facade, managing a bounded pool of long-lived client sessions with reconnection and graceful drain.

Each file is a self-contained system prompt (Markdown with name/description frontmatter): point your agent harness at it, or read it as a hands-on guide to building a service with jet.

Contributing

Contributions are welcome — see CONTRIBUTING.md.

License

MIT © Kukhtin Vasiliy

Documentation

Overview

Package jet is a pragmatic toolkit for building Go microservices.

It provides the building blocks most services re-implement from scratch:

  • CLogger — a structured, context-aware logger on top of log/slog.
  • ConfigLoader — a typed YAML + environment-variable configuration loader.
  • RequestContext — a request context (request id, user, session, roles, …) that propagates across HTTP, gRPC and Kafka boundaries.
  • AppError — a structured error model with codes, business/system/panic types and HTTP/gRPC status hints.
  • Healthcheck, JWT, crypto, validation, watchdog and generics helpers.

Sub-packages add the rest of a typical service: storage adapters (storages/pg, storages/redis, …), messaging (kafka, event), transport servers (http, grpc), service lifecycle (cluster), concurrency helpers (goroutine, retry) and observability (monitoring, profile).

The toolkit favors boring, explicit building blocks over magic, and is extracted from an internal kit that has run 20+ production services.

Index

Examples

Constants

View Source
const (
	ErrTypeBusiness = "business"
	ErrTypeSystem   = "system"
	ErrTypePanic    = "panic"

	ErrCodePanic = "PANIC-001"
)
View Source
const (
	ErrCodeCfgRead         = "CFG-001"
	ErrCodeCfgMerge        = "CFG-002"
	ErrCodeCfgUnmarshal    = "CFG-003"
	ErrCodeNoPathSpecified = "CFG-004"
	ErrCodeConfigNotLoaded = "CFG-005"
)
View Source
const (
	ErrCodeCryptoEncrypt = "CRP-001"
	ErrCodeCryptoDecrypt = "CRP-002"
)
View Source
const (
	TzUTC  = "UTC"
	TzP13  = "UTC+13"
	TzP12  = "UTC+12"
	TzP11  = "UTC+11"
	TzP10  = "UTC+10"
	TzP9   = "UTC+9"
	TzP8   = "UTC+8"
	TzP7   = "UTC+7"
	TzP6p5 = "UTC+6:30"
	TzP6   = "UTC+6"
	TzP5   = "UTC+5"
	TzP4   = "UTC+4"
	TzP3   = "UTC+3"
	TzP2   = "UTC+2"
	TzP1   = "UTC+1"
	TzM1   = "UTC-1"
	TzM2   = "UTC-2"
	TzM3   = "UTC-3"
	TzM4   = "UTC-4"
	TzM5   = "UTC-5"
	TzM6   = "UTC-6"
	TzM7   = "UTC-7"
	TzM8   = "UTC-8"
	TzM9   = "UTC-9"
	TzM10  = "UTC-10"
	TzM11  = "UTC-11"
)
View Source
const (
	ClaimCallerName = "caller_name"

	ErrCodeJwtParse              = "JWT-001"
	ErrCodeJwtMalformed          = "JWT-002"
	ErrCodeJwtTokenGen           = "JWT-003"
	ErrCodeJwtWrongSigningMethod = "JWT-004"
)
View Source
const (
	// PanicLevel level. Nothing below a panic is logged; reserved as the highest threshold.
	PanicLevel = "panic"
	// FatalLevel level. Logs and then calls os.Exit(1).
	FatalLevel = "fatal"
	// ErrorLevel level. Used for errors that should definitely be noted.
	ErrorLevel = "error"
	// WarnLevel level. Non-critical entries that deserve eyes.
	WarnLevel = "warning"
	// InfoLevel level. General operational entries about what's going on inside the application.
	InfoLevel = "info"
	// DebugLevel level. Usually only enabled when debugging. Very verbose logging.
	DebugLevel = "debug"
	// TraceLevel level. Finer-grained informational events than Debug.
	TraceLevel = "trace"

	FormatterText = "plain"
	FormatterJson = "json"
)
View Source
const (
	ErrCodeSysUtilsRetryMaxAttempts = "SU-001"
	ErrCodeSysUtilsRetryFnEmpty     = "SU-002"
)
View Source
const (
	ErrCodeJsonEncode = "TP-001"
	ErrCodeJsonDecode = "TP-002"
)
View Source
const (
	AppTest = "test"
)
View Source
const (
	ErrCodeAdapterConfigInvalid = "KIT-001"
)
View Source
const (
	ErrCodeNotSupportedTz = "DTU-001"
)
View Source
const (
	ErrCodeSplitLengthExceeded = "ARR-001"
)
View Source
const (
	ErrCodeValidatorNotEmpty = "VAL-001"
)
View Source
const (
	ErrCodeWatchdogWorkerStuck = "WDG-001"
)

Variables

View Source
var (
	ErrCfgRead = func(cause error, path string) error {
		return NewAppErrBuilder(ErrCodeCfgRead, "read config error: %s", path).Wrap(cause).Err()
	}
	ErrCfgMerge = func(cause error, path string) error {
		return NewAppErrBuilder(ErrCodeCfgMerge, "merge config error: %s", path).Wrap(cause).Err()
	}
	ErrCfgUnmarshal = func(cause error) error {
		return NewAppErrBuilder(ErrCodeCfgUnmarshal, "merge config error").Wrap(cause).Err()
	}
	ErrNoPathSpecified = func() error {
		return NewAppErrBuilder(ErrCodeNoPathSpecified, "neither env nor explicit path is specified").Business().Err()
	}
	ErrConfigNotLoaded = func() error {
		return NewAppErrBuilder(ErrCodeConfigNotLoaded, "config not loaded").Business().Err()
	}
)
View Source
var (
	ErrCryptoEncrypt = func(ctx context.Context, cause error) error {
		return NewAppErrBuilder(ErrCodeCryptoEncrypt, "encryption error").C(ctx).Wrap(cause).Err()
	}
	ErrCryptoDecrypt = func(ctx context.Context, cause error) error {
		return NewAppErrBuilder(ErrCodeCryptoDecrypt, "decryption error").C(ctx).Wrap(cause).Err()
	}
)
View Source
var (
	ErrJwtParse = func(cause error) error {
		return NewAppErrBuilder(ErrCodeJwtParse, "").Wrap(cause).Err()
	}
	ErrJwtMalformed = func() error {
		return NewAppErrBuilder(ErrCodeJwtMalformed, "").Err()
	}
	ErrJwtTokenGen = func(ctx context.Context, cause error) error {
		return NewAppErrBuilder(ErrCodeJwtTokenGen, "jwt gen").Wrap(cause).Err()
	}
	ErrJwtWrongSigningMethod = func(ctx context.Context) error {
		return NewAppErrBuilder(ErrCodeJwtWrongSigningMethod, "wrong signing method").Err()
	}
)
View Source
var (
	ErrSysUtilsRetryMaxAttempts = func(ctx context.Context) error {
		return NewAppErrBuilder(ErrCodeSysUtilsRetryMaxAttempts, "max attempts reached").C(ctx).Err()
	}
	ErrSysUtilsRetryFnEmpty = func(ctx context.Context) error {
		return NewAppErrBuilder(ErrCodeSysUtilsRetryFnEmpty, "function empty").C(ctx).Err()
	}
)
View Source
var (
	ErrJsonEncode = func(cause error) error {
		return NewAppErrBuilder(ErrCodeJsonEncode, "encode JSON").Wrap(cause).Err()
	}
	ErrJsonDecode = func(cause error) error {
		return NewAppErrBuilder(ErrCodeJsonDecode, "decode JSON").Wrap(cause).Err()
	}
)
View Source
var (
	ErrAdapterConfigInvalid = func(ctx context.Context) error {
		return NewAppErrBuilder(ErrCodeAdapterConfigInvalid, "invalid config").Err()
	}
)
View Source
var (
	ErrNotSupportedTz = func(err error, tz string) error {
		return NewAppErrBuilder(ErrCodeNotSupportedTz, "timezone isn't supported").Wrap(err).F(KV{"tz": tz}).Business().Err()
	}
)
View Source
var (
	ErrPanic = func(ctx context.Context, cause interface{}) error {
		var causeErr error
		switch v := cause.(type) {
		case nil:
			causeErr = fmt.Errorf("panic")
		case string:
			causeErr = fmt.Errorf("%s", v)
		case error:
			causeErr = v
		default:
			causeErr = fmt.Errorf("%v", v)
		}
		return NewAppErrBuilder(ErrCodePanic, "").Wrap(causeErr).C(ctx).Panic().Err()
	}
)
View Source
var (
	ErrSplitLengthExceeded = func() error {
		return NewAppErrBuilder(ErrCodeSplitLengthExceeded, "split length exceeded").Business().Err()
	}
)
View Source
var (
	ErrValidatorNotEmpty = func(ctx context.Context, method, attr string) error {
		return NewAppErrBuilder(ErrCodeValidatorNotEmpty, "empty: %s", method, attr).F(KV{"method": method}).C(ctx).Business().Err()
	}
)
View Source
var ErrWatchdogWorkerStuck = func(workerName string) error {
	return NewAppErrBuilder(ErrCodeWatchdogWorkerStuck, "worker is stuck").
		F(KV{"worker": workerName}).
		Business().
		Err()
}
View Source
var LanguageISO639_1 = map[string]struct{}{}/* 184 elements not displayed */

LanguageISO639_1 ISO 639-1 language codes set

Functions

func Await

func Await(fn func() (bool, error), tick, timeout time.Duration) chan error

Await allows awaiting some state by periodically hitting fn unless either it returns true or error or timeout It returns nil when fn results true

func BoolPtr

func BoolPtr(b bool) *bool

func BytesToMapInterfaces

func BytesToMapInterfaces(bytes []byte) map[string]interface{}

func ContainsIntersection

func ContainsIntersection(slice1, slice2 []string) bool

func ContextToGrpcMD

func ContextToGrpcMD(ctx context.Context) (metadata.MD, bool)

func ConvertFromAny

func ConvertFromAny[T any](data any) (*T, error)

func ConvertFromMap

func ConvertFromMap[T any](data map[string]interface{}) (*T, error)

func ConvertMapValues

func ConvertMapValues[T any](m map[string]interface{}, converter func(value any) T) map[string]T

func ConvertSlice

func ConvertSlice[TSrc any, TRes any](src []*TSrc, converter func(*TSrc) *TRes) []*TRes

ConvertSlice is a generic function to convert one slice to another with help of converter func

func ConvertToMap

func ConvertToMap(data any) (map[string]interface{}, error)

func Copy

func Copy(ctx context.Context) context.Context

func Date

func Date(date time.Time) time.Time

Date returns a date of a passed timestamp without time

func DecryptString

func DecryptString(ctx context.Context, key, val string) (string, error)

func Diff

func Diff(a, b time.Time) (year, month, day, hour, min, sec int)

Diff properly calculates difference between two dates in year, month etc.

func Digits

func Digits(s string) bool

func EncryptString

func EncryptString(ctx context.Context, key, val string) (string, error)

func Equal

func Equal(m1, m2 any) bool

func ExtractUrlExtension

func ExtractUrlExtension(s string) (string, error)

ExtractUrlExtension extract extension from url

func Filter

func Filter[TItem any](slice []TItem, filterFn func(TItem) bool) []TItem
Example
package main

import (
	"fmt"

	"github.com/zloevil/jet"
)

func main() {
	even := jet.Filter([]int{1, 2, 3, 4}, func(i int) bool { return i%2 == 0 })
	fmt.Println(even)
}
Output:
[2 4]

func First

func First[TItem any](slice []*TItem, selectFn func(*TItem) bool) *TItem

First returns selected by condition item or default

func Float32Ptr

func Float32Ptr(i float32) *float32

func Float64Ptr

func Float64Ptr(i float64) *float64

func ForAll

func ForAll[TItem any](slice []TItem, fn func(TItem)) []TItem

func FromGrpcMD

func FromGrpcMD(ctx context.Context, md metadata.MD) context.Context

func FromMap

func FromMap(ctx context.Context, mp map[string]interface{}) (context.Context, error)

func FromSet

func FromSet[TKey comparable](m map[TKey]struct{}) []TKey

func GenJwtToken

func GenJwtToken(ctx context.Context, rq *JwtRequest) (string, error)

GenJwtToken generates a new JWT token

func GenerateInternalAccessToken

func GenerateInternalAccessToken(ctx context.Context, secret []byte, ttl int, callerName string) (string, error)

GenerateInternalAccessToken generates token for internal communications between services

func GenerateTimeSeries

func GenerateTimeSeries(from, to time.Time, period time.Duration) []time.Time

GenerateTimeSeries takes period of time and generates slice of timestamps with the given period step

func GetDefault

func GetDefault[T any]() T

GetDefault get default value for type

func GetTzLocation

func GetTzLocation(tz string) *time.Location

func GroupBy

func GroupBy[TItem any, TKey comparable](slice []TItem, keyFn func(TItem) TKey) map[TKey][]TItem

GroupBy groups by slice by the key

func HashObj

func HashObj(obj any) uint64

func Int32ToIntPtr

func Int32ToIntPtr(i *int32) *int

func Int64ToIntPtr

func Int64ToIntPtr(i *int64) *int

func IntPtr

func IntPtr(i int) *int

func IntToInt32Ptr

func IntToInt32Ptr(i *int) *int32

func IntToInt64Ptr

func IntToInt64Ptr(i *int) *int64

func IsAppErrCode

func IsAppErrCode(e error, code string) bool

IsAppErrCode checks if error interface is asserted to *AppError and contains specific code

func IsCoordinateValid

func IsCoordinateValid(c string) bool

IsCoordinateValid checks if coordinate valid

func IsEmailValid

func IsEmailValid(email string) bool

IsEmailValid checks email format

func IsEmpty

func IsEmpty(object interface{}) bool

IsEmpty gets whether the specified object is considered empty or not

func IsIpV4Valid

func IsIpV4Valid(ip string) bool

IsIpV4Valid checks ip v4 format

func IsIpV6Valid

func IsIpV6Valid(ip string) bool

IsIpV6Valid checks ip v6 format

func IsPhoneValid

func IsPhoneValid(phone string) bool

IsPhoneValid checks phone format (with country code without special characters)

func IsPhoneWithCountryCodeValid

func IsPhoneWithCountryCodeValid(code, phone string) bool

IsPhoneWithCountryCodeValid checks phone with country code

func IsRussianPhoneValid

func IsRussianPhoneValid(phone string) bool

IsRussianPhoneValid checks Russian phone format (with country code without special characters)

func IsTelegramChannelValid

func IsTelegramChannelValid(channel string) bool

func IsTelegramUsernameValid

func IsTelegramUsernameValid(username string) bool

func IsTimeZoneIANA

func IsTimeZoneIANA(tz string) bool

IsTimeZoneIANA returns true if provided valid IANA time zone

func IsUrlValid

func IsUrlValid(url string) bool

func IsValidISO639_1

func IsValidISO639_1(lang string) bool

IsValidISO639_1 if the language is in ISO 639-1 format

func JsonDecode

func JsonDecode[T any](payload []byte) (*T, error)

JsonDecode decodes type from json bytes

func JsonDecodePlainSlice

func JsonDecodePlainSlice[T any](payload []byte) ([]T, error)

JsonDecodePlainSlice decodes type from json bytes to slice

func JsonDecodeSlice

func JsonDecodeSlice[T any](payload []byte) ([]*T, error)

JsonDecodeSlice decodes type from json bytes to slice

func JsonEncode

func JsonEncode(v any) ([]byte, error)

JsonEncode encodes type to json bytes

func LeftExclusive

func LeftExclusive[T comparable](left, right []T) []T

func Map

func Map[TItem any, TRes any](slice []TItem, mapFn func(TItem) TRes) []TRes
Example
package main

import (
	"fmt"

	"github.com/zloevil/jet"
)

func main() {
	doubled := jet.Map([]int{1, 2, 3}, func(i int) int { return i * 2 })
	fmt.Println(doubled)
}
Output:
[2 4 6]

func MapInterfacesToBytes

func MapInterfacesToBytes(m map[string]interface{}) []byte

func MapKeys

func MapKeys[TKey comparable, TItem any](m map[TKey]TItem) []TKey

func MapToLowerCamelKeys

func MapToLowerCamelKeys(m map[string]interface{}) map[string]interface{}

func MapValues

func MapValues[TKey comparable, TItem any](m map[TKey]TItem) []TItem

func MapsEqual

func MapsEqual(m1, m2 map[string]interface{}) bool

func MaxTime

func MaxTime(times ...time.Time) *time.Time

MaxTime returns maximum time of the provided slice

func Millis

func Millis(t time.Time) int64

Millis is a convenience method to get milliseconds since epoch for provided HourMinTime.

func MillisFromTime

func MillisFromTime(t time.Time) int64

func MinTime

func MinTime(times ...time.Time) *time.Time

MinTime returns minimum time of the provided slice

func Modified

func Modified[T comparable](modified bool, cur T, update T) (T, bool)

Modified returns result value and boolean flag that shows if the value was modified or not can be used for structs. For plain type use ModifiedPlain instead

func ModifiedNillable

func ModifiedNillable[T any](modified bool, cur *T, update *Nillable[T]) (*T, bool)

ModifiedNillable returns result value and boolean flag that shows if an object was modified or not if the 'update' parameter is nil means the value has not been updated []int{1,2,3} and []int{3,2,1} is NOT equal For plain types use ModifiedPlainNillable

func ModifiedPlain

func ModifiedPlain[T PlainType](modified bool, cur T, update T) (T, bool)

ModifiedPlain returns the result value, and a boolean flag that shows if the value was modified or not can be used for plain types: integer, float, string

func ModifiedPlainNillable

func ModifiedPlainNillable[T PlainType](modified bool, cur T, update *T) (T, bool)

ModifiedPlainNillable returns result value and boolean flag that shows if the value was modified or not if the 'update' parameter is nil means the value has not been updated

func ModifiedSliceNillable

func ModifiedSliceNillable[T constraints.Ordered](modified bool, cur []T, update []T) ([]T, bool)

ModifiedSliceNillable return result slice and boolean flag that shows if the slice was modified or not if the 'update' parameter is nil means value has not been updated if the 'update' parameter is empty means value has been updated to nil []int{1,2,3} and []int{3,2,1} is equal Side effect: result value can be sorted

func ModifiedSliceStructured

func ModifiedSliceStructured[T comparable](modified bool, sort func([]T), cur []T, update []T) ([]T, bool)

ModifiedSliceStructured return result slice and boolean flag that shows if the slice was modified or not if the 'update' parameter is nil means value has not been updated if the 'update' parameter is empty means value has been updated to nil []int{1,2,3} and []int{3,2,1} is equal Side effect: result value can be sorted

func NanoId

func NanoId() string

NanoId generates random string

func NewAppError

func NewAppError(code string, format string, args ...interface{}) error

NewAppError creates a new AppError and returns error interface

func NewId

func NewId() string

NewId generates UUID

func NewRandString

func NewRandString() string

NewRandString generates a unique string

func Nil

func Nil() string

Nil returns nil UUID

func NilOrInMap

func NilOrInMap[T comparable](value *T, m map[T]struct{}) bool

func Now

func Now() time.Time

Now is the current time

func NowDate

func NowDate() time.Time

NowDate returns current date without time

func NowMillis

func NowMillis() int64

NowMillis is the current time in millis

func NowNanos

func NowNanos() int64

NowNanos is the current time in UNIX NANO format

func NowPtr

func NowPtr() *time.Time

func NullToString

func NullToString(s *string) string

NullToString transforms NULL to empty string

func NumCode

func NumCode(size int) string

NumCode generates random number code with the given size

func Overlapped

func Overlapped(startA, endA, startB, endB time.Time) bool

func PaginateSlice

func PaginateSlice[T any](items []T, paging PagingRequest) []T

PaginateSlice paginates the given slice of items according to the provided paging request. Returns a slice containing a subset of the original items based on the specified page size and index.

func ParseDateAny

func ParseDateAny(s string) *time.Time

ParseDateAny parses multiple formats of dates

func ParseFloat32

func ParseFloat32(s string) *float32

func ParseFloat64

func ParseFloat64(s string) *float64

func ParseInternalAccessToken

func ParseInternalAccessToken(ctx context.Context, secret []byte, token string) (string, error)

ParseInternalAccessToken parses an internal token

func Reduce

func Reduce[TItem any, TRes any, TKey comparable](slice []TItem, grpFn func(TItem) TKey, accFn func(TItem, TRes) TRes) map[TKey]TRes

func RemoveNonAlfaDigital

func RemoveNonAlfaDigital(str string) string

func Retry

func Retry[TIn, TOut any](ctx context.Context, fn func(ctx context.Context, in TIn) (TOut, error), in TIn, cfg RetryCfg) (TOut, error)

Retry takes a generic function with parameters and run it with retry wrapper retry params are configured with RetryCfg

func Round100

func Round100(value float64) float64

func Round10000

func Round10000(value float64) float64

func SliceToMap

func SliceToMap[TItem any, TKey comparable](slice []TItem, grpFn func(TItem) TKey) map[TKey]TItem

SliceToMap converts a passed slice to a map by the given definition of key Caution!!! if specified key isn't unique for the slice, only last slice item for the given key is taken to the resulted map

func SplitArr

func SplitArr[T any](data []T, size int) [][]T

func SplitArrByItemLen

func SplitArrByItemLen[T ~string](data []T, max int) ([][]T, error)

func StrToInt64

func StrToInt64(s string) (int64, error)

func StringPtr

func StringPtr(s string) *string

func StringToNull

func StringToNull(s string) *string

StringToNull transforms empty string to nil string

func StringsToInterfaces

func StringsToInterfaces(sl []string) []interface{}

func TimeFromMillis

func TimeFromMillis(millis int64) time.Time

func TimePtr

func TimePtr(t time.Time) *time.Time

func ToSet

func ToSet[TItem any, TKey comparable](slice []TItem, keyFn func(TItem) TKey) map[TKey]struct{}

func ToSlicePtr

func ToSlicePtr[T any](src []T) []*T

ToSlicePtr convert slice to slice ptr

func ToStringDate

func ToStringDate(date *time.Time) string

func ToTz

func ToTz(t time.Time, tz string) (time.Time, error)

func TzValid

func TzValid(tz string) bool

func UInt32Ptr

func UInt32Ptr(i uint32) *uint32

func UInt64ToInt32Ptr

func UInt64ToInt32Ptr(i *uint64) *int32

func UUID

func UUID(size int) string

UUID generates UUID

func ValidateUUIDs

func ValidateUUIDs(uuids ...string) error

ValidateUUIDs check UUID format nad return error if at least one UUID isn't in a correct format

func VerifyJwtToken

func VerifyJwtToken(ctx context.Context, token string, secret []byte) (*jwt.Token, jwt.MapClaims, error)

VerifyJwtToken verifies a JWT token

Types

type Adapter

type Adapter[T any] interface {
	// Init initializes adapter
	Init(ctx context.Context, cfg *T) error
	// Close closes storage
	Close(ctx context.Context) error
}

Adapter common interface for adapters

type AdapterListener

type AdapterListener[T any] interface {
	Adapter[T]
	// ListenAsync runs async listening
	ListenAsync(ctx context.Context) error
}

AdapterListener common interface for adapters with listeners

type AppErrBuilder

type AppErrBuilder interface {
	// C attaches a request context to AppError
	C(ctx context.Context) AppErrBuilder
	// F attaches additional fields to AppError object
	// if type of passed field isn't valid, it's just silently ignored
	F(fields KV) AppErrBuilder
	// GrpcSt attaches gRPC status
	// when converting to grpc error it will be checked and if populated, corresponding grpc status is set
	GrpcSt(status uint32) AppErrBuilder
	// HttpSt attaches HTTP status
	// it gives some hint to API gateway layer what HTTP status to return client
	HttpSt(status uint32) AppErrBuilder
	// Business marks error as business validation error
	Business() AppErrBuilder
	// System marks error as system error (this is by default)
	System() AppErrBuilder
	// Panic marks error as panic error
	Panic() AppErrBuilder
	// Type sets type of error
	Type(t string) AppErrBuilder
	// Err builds error with all specified attributes
	Err() error
	// Wrap wraps another error
	Wrap(cause error) AppErrBuilder
}

AppErrBuilder allows building AppError object

func NewAppErrBuilder

func NewAppErrBuilder(code string, format string, args ...interface{}) AppErrBuilder

NewAppErrBuilder creates a new AppErrBuilder and default AppError object

Example
package main

import (
	"fmt"

	"github.com/zloevil/jet"
)

func main() {
	err := jet.NewAppErrBuilder("ORD-001", "order not found: %s", "42").Business().Err()

	appErr, _ := jet.IsAppErr(err)
	fmt.Println(appErr.Code())
	fmt.Println(appErr.Type())
	fmt.Println(appErr.Message())
}
Output:
ORD-001
business
order not found: 42

type AppError

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

AppError specifies application error object

func IsAppErr

func IsAppErr(e error) (*AppError, bool)

IsAppErr checks if error interface is asserted to *AppError if true, it returns *AppError

func (*AppError) Cause

func (e *AppError) Cause() error

Cause returns wrapped error

func (*AppError) Code

func (e *AppError) Code() string

Code returns error code

func (*AppError) Error

func (e *AppError) Error() string

Error returns default error message

func (*AppError) Fields

func (e *AppError) Fields() KV

Fields returns fields

func (*AppError) GrpcStatus

func (e *AppError) GrpcStatus() *uint32

GrpcStatus returns grpc status

func (*AppError) HttpStatus

func (e *AppError) HttpStatus() *uint32

HttpStatus returns http status

func (*AppError) Message

func (e *AppError) Message() string

Message returns error message

func (*AppError) Type

func (e *AppError) Type() string

Type returns error type

func (*AppError) WithStack

func (e *AppError) WithStack() string

WithStack return error message with stack trace attached if you need split fields, assert to *AppError

func (*AppError) WithStackErr

func (e *AppError) WithStackErr() error

type CLogger

type CLogger interface {
	// C - adds request context to log
	//
	// don't put context when logging error, as it makes sense a context of where error happens rather than a context of where error log is invoked
	// otherwise, context will be logged twice
	C(ctx context.Context) CLogger
	// F - adds fields to log
	F(fields KV) CLogger
	// E - adds error to log
	E(err error) CLogger
	// St - adds stack to log (if err is already set)
	St() CLogger
	// Cmp - adds component
	Cmp(c string) CLogger
	// Mth - adds method
	Mth(m string) CLogger
	// Pr - adds protocol
	Pr(m string) CLogger
	// Srv - adds unique service code
	Srv(s string) CLogger
	// Node - adds service instance code
	Node(n string) CLogger
	Inf(args ...interface{}) CLogger
	InfF(format string, args ...interface{}) CLogger
	Err(args ...interface{}) CLogger
	ErrF(format string, args ...interface{}) CLogger
	Dbg(args ...interface{}) CLogger
	DbgF(format string, args ...interface{}) CLogger
	Trc(args ...interface{}) CLogger
	TrcF(format string, args ...interface{}) CLogger
	// TrcObj marshals all args only if loglevel = Trace, otherwise bypass
	// Note that only Exported fields of objects are logged (due to nature of json.Marshal)
	TrcObj(format string, args ...interface{}) CLogger
	Warn(args ...interface{}) CLogger
	WarnF(format string, args ...interface{}) CLogger
	Fatal(args ...interface{}) CLogger
	FatalF(format string, args ...interface{}) CLogger
	Clone() CLogger
	Printf(string, ...interface{})
	PrintfErr(f string, args ...interface{})
	// Write writer implementation
	Write(p []byte) (n int, err error)
}

CLogger provides structured logging abilities. !!!! Not thread safe. Don't share one CLogger instance through multiple goroutines.

func L

func L(logger *Logger) CLogger

L creates a CLogger bound to logger.

type CLoggerFunc

type CLoggerFunc func() CLogger

type Check

type Check = healthcheck.Check

Check is a health check function that returns nil if healthy, or an error if unhealthy.

type ConfigLoader

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

func NewConfigLoader

func NewConfigLoader[T any]() *ConfigLoader[T]
Example

ExampleNewConfigLoader loads a typed config from YAML with env overrides.

package main

import (
	"github.com/zloevil/jet"
)

func main() {
	type Config struct {
		HTTP struct{ Port string }
	}

	cfg, err := jet.NewConfigLoader[Config]().WithPath("./config.yml").WithPrefix("MYSVC").Load()
	if err != nil {
		return
	}
	_ = cfg
}

func (*ConfigLoader[T]) Load

func (c *ConfigLoader[T]) Load() (*T, error)

Load loads config by provided parameters

func (*ConfigLoader[T]) WithEnv

func (c *ConfigLoader[T]) WithEnv(env string) *ConfigLoader[T]

func (*ConfigLoader[T]) WithPath

func (c *ConfigLoader[T]) WithPath(path string) *ConfigLoader[T]

func (*ConfigLoader[T]) WithPrefix

func (c *ConfigLoader[T]) WithPrefix(prefix string) *ConfigLoader[T]

type DayOfWeek

type DayOfWeek string

DayOfWeek specifies days of week

const (
	Monday    DayOfWeek = "Mon"
	Tuesday   DayOfWeek = "Tue"
	Wednesday DayOfWeek = "Wed"
	Thursday  DayOfWeek = "Thu"
	Friday    DayOfWeek = "Fri"
	Saturday  DayOfWeek = "Sat"
	Sunday    DayOfWeek = "Sun"
)

func (*DayOfWeek) IsValid

func (d *DayOfWeek) IsValid(s string) bool

type DaysOfWeek

type DaysOfWeek map[DayOfWeek]struct{}

func (DaysOfWeek) IsValid

func (d DaysOfWeek) IsValid() bool

type Error

type Error struct {
	Message    string                 `json:"message"`               // Message is error description
	Code       string                 `json:"code,omitempty"`        // Code is error code provided by error producer
	Type       string                 `json:"type,omitempty"`        // Type is error type (panic, system, business)
	HttpStatus *uint32                `json:"http_status,omitempty"` // HttpStatus http status
	Details    map[string]interface{} `json:"details,omitempty"`     // Details is additional info provided by error producer
	Stack      string                 `json:"stack,omitempty"`       // Stack trace
	GrpcStatus *uint32                `json:"grpc_status,omitempty"` // GrpcStatus grpc status
}

Error error for events

func ToError

func ToError(err error) *Error

func ToErrorFromString

func ToErrorFromString(e *string) (*Error, error)

func ToErrorFromStringEmptyIfInvalid

func ToErrorFromStringEmptyIfInvalid(e *string) *Error

func (*Error) ToError

func (e *Error) ToError() error

type ErrorHook

type ErrorHook interface {
	Error(err error)
}

ErrorHook allows specifying a hook invoked for every logged error.

type Flags

type Flags[T TFlags] struct {
	// contains filtered or unexported fields
}

func NewFlags

func NewFlags[T TFlags](flags ...T) Flags[T]

func (Flags[T]) HasAll

func (f Flags[T]) HasAll(flags ...T) bool

HasAll checks if all specified flags are set

func (Flags[T]) HasAny

func (f Flags[T]) HasAny(flags ...T) bool

HasAny checks if any of the specified flags are set

func (Flags[T]) MarshalJSON

func (f Flags[T]) MarshalJSON() ([]byte, error)

MarshalJSON implements the json.Marshaler interface

func (Flags[T]) Ptr

func (f Flags[T]) Ptr() *Flags[T]

func (Flags[T]) Set

func (f Flags[T]) Set(flags ...T) Flags[T]

Set sets the specified flags and returns the new value

func (Flags[T]) String

func (f Flags[T]) String() string

func (Flags[T]) Toggle

func (f Flags[T]) Toggle(flags ...T) Flags[T]

Toggle toggles the specified flags and returns the new value

func (Flags[T]) Uint

func (f Flags[T]) Uint() T

func (*Flags[T]) UnmarshalJSON

func (f *Flags[T]) UnmarshalJSON(data []byte) error

UnmarshalJSON implements the json.Unmarshaler interface

func (Flags[T]) Unset

func (f Flags[T]) Unset(flags ...T) Flags[T]

Unset clears the specified flags and returns the new value

type Healthcheck

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

Healthcheck provides HTTP endpoints for Kubernetes liveness and readiness probes. Endpoints:

  • GET /live - liveness probe (indicates if app should be restarted)
  • GET /ready - readiness probe (indicates if app can serve traffic)

func NewHealthCheck

func NewHealthCheck(cfg *HealthcheckConfig) *Healthcheck

NewHealthCheck creates a new Healthcheck instance.

func (*Healthcheck) AddLivenessCheck

func (h *Healthcheck) AddLivenessCheck(name string, check Check)

AddLivenessCheck adds a check that indicates whether this instance of the application should be destroyed or restarted.

A failed liveness check indicates that this instance is unhealthy and should be killed and restarted by Kubernetes. Use for detecting internal failures like deadlocks, infinite loops, or stuck workers.

Note: All liveness checks are automatically included as readiness checks.

Example:

hc.AddLivenessCheck("worker", func() error {
    if time.Since(workerLastActivity) > 5*time.Minute {
        return errors.New("worker is stuck")
    }
    return nil
})

func (*Healthcheck) AddReadinessCheck

func (h *Healthcheck) AddReadinessCheck(name string, check Check)

AddReadinessCheck adds a check that indicates whether this instance of the application is currently ready to serve requests.

A failed readiness check indicates that this instance should temporarily not receive traffic (e.g., during startup, when dependencies are unavailable). Kubernetes will stop routing traffic but won't restart the container.

Example:

hc.AddReadinessCheck("database", func() error {
    ctx, cancel := context.WithTimeout(context.Background(), time.Second)
    defer cancel()
    return db.PingContext(ctx)
})

func (*Healthcheck) Start

func (h *Healthcheck) Start()

Start starts the healthcheck HTTP server in a background goroutine. The server will automatically retry on failure with 5 second delay.

func (*Healthcheck) Stop

func (h *Healthcheck) Stop()

Stop gracefully stops the healthcheck HTTP server.

type HealthcheckConfig

type HealthcheckConfig struct {
	Port string
}

HealthcheckConfig configuration for healthcheck server.

type HourMinTime

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

HourMinTime - time (hour:min) representation in format 15:04

func (HourMinTime) Before

func (t HourMinTime) Before(other HourMinTime) bool

func (HourMinTime) FromTime

func (t HourMinTime) FromTime(tm time.Time) HourMinTime

func (HourMinTime) Hour

func (t HourMinTime) Hour() int

func (*HourMinTime) MarshalJSON

func (t *HourMinTime) MarshalJSON() ([]byte, error)

func (HourMinTime) Minute

func (t HourMinTime) Minute() int

func (HourMinTime) MustParse

func (t HourMinTime) MustParse(s string) HourMinTime

func (HourMinTime) Parse

func (t HourMinTime) Parse(s string) (HourMinTime, error)

func (HourMinTime) String

func (t HourMinTime) String() string

func (HourMinTime) Unix

func (t HourMinTime) Unix() int64

func (*HourMinTime) UnmarshalJSON

func (t *HourMinTime) UnmarshalJSON(b []byte) error

type JwtRequest

type JwtRequest struct {
	UserId   string
	Secret   []byte
	ExpireAt time.Time
	Claims   map[string]any
}

JwtRequest request to generate a new jwt token

type KV

type KV map[string]interface{}

KV key value type

type LogConfig

type LogConfig struct {
	Level   string // Level logging level
	Format  string // Format (plain, json)
	Context bool   // Context if true, request context params are part of logging
	Service bool   // Service if true, service params are part of logging
}

LogConfig represents logging configuration.

type Logger

type Logger struct {
	Cfg *LogConfig
	// contains filtered or unexported fields
}

Logger holds the configured slog logger and is the factory source for CLogger.

func InitLogger

func InitLogger(cfg *LogConfig) *Logger

InitLogger creates and configures a Logger from cfg.

Example

ExampleInitLogger shows logger setup and the chainable, context-aware API.

package main

import (
	"github.com/zloevil/jet"
)

func main() {
	logger := jet.InitLogger(&jet.LogConfig{Level: jet.InfoLevel, Format: jet.FormatterJson})

	log := jet.L(logger)
	log.Cmp("orders").Mth("Create").F(jet.KV{"id": "42"}).Inf("order created")
	// log lines are timestamped and written to stdout, so they are not asserted here.
}

func (*Logger) Init

func (l *Logger) Init(cfg *LogConfig)

Init (re)configures the logger from cfg.

func (*Logger) SetErrorHook

func (l *Logger) SetErrorHook(h ErrorHook)

SetErrorHook registers a hook invoked for every error logged at Error level or above.

func (*Logger) SetLevel

func (l *Logger) SetLevel(level string)

SetLevel changes the active logging level at runtime.

type Nillable

type Nillable[T any] struct {
	V *T `json:"value"` // Value
}

func NewNillable

func NewNillable[T any](v *T) *Nillable[T]

type PageReader

type PageReader[TItem any, TRq any] interface {
	// GetPage retrieves one page
	GetPage(ctx context.Context, rq TRq) chan PagingResponseG[TItem]
}

PageReader is a generic reader allowing read from remote repository

func NewPageReader

func NewPageReader[TItem any, TRq any](fn func(context.Context, PagingRequestG[TRq]) (PagingResponseG[TItem], error), pageSize int, logger CLogger) PageReader[TItem, TRq]

type PagingRequest

type PagingRequest struct {
	Size   int            `json:"size"`   // Size page size
	Index  int            `json:"index"`  // Index page index
	SortBy []*SortRequest `json:"sortBy"` // SortBy sort by fields
}

PagingRequest paging request

type PagingRequestG

type PagingRequestG[T any] struct {
	PagingRequest
	Request T `json:"request"` // Request
}

PagingRequestG generic paging request

type PagingResponse

type PagingResponse struct {
	Total int `json:"total"` // Total number of rows
	Limit int `json:"limit"` // Limit applied
}

PagingResponse paging response

type PagingResponseG

type PagingResponseG[T any] struct {
	PagingResponse
	Items []*T `json:"response"` // Items
}

PagingResponseG generic paging response

type PlainType

type PlainType interface {
	constraints.Integer | constraints.Float | ~string | ~bool | time.Time
}

type RequestContext

type RequestContext struct {
	Rid   string       `json:"_ctx.rid,omitempty" mapstructure:"_ctx.rid"`   // Rid request ID
	Sid   string       `json:"_ctx.sid,omitempty" mapstructure:"_ctx.sid"`   // Sid session ID
	Uid   string       `json:"_ctx.uid,omitempty" mapstructure:"_ctx.uid"`   // Uid user ID
	Un    string       `json:"_ctx.un,omitempty" mapstructure:"_ctx.un"`     // Un username
	App   string       `json:"_ctx.app,omitempty" mapstructure:"_ctx.app"`   // App application
	ClIp  string       `json:"_ctx.clIp,omitempty" mapstructure:"_ctx.clIp"` // ClIp client IP
	Roles []string     `json:"_ctx.rl,omitempty" mapstructure:"_ctx.rl"`     // Roles list of roles
	Lang  language.Tag `json:"_ctx.lang,omitempty" mapstructure:"_ctx.lang"` // Lang client language
	Kv    KV           `json:"_ctx.kv,omitempty" mapstructure:"_ctx.kv"`     // Kv arbitrary key-value
}
Example
package main

import (
	"context"
	"fmt"

	"github.com/zloevil/jet"
)

func main() {
	ctx := jet.NewRequestCtx().WithRequestId("req-1").WithUser("u-1", "alice").ToContext(context.Background())

	rc, _ := jet.Request(ctx)
	fmt.Println(rc.GetRequestId(), rc.GetUserId(), rc.GetUsername())
}
Output:
req-1 u-1 alice

func MustRequest

func MustRequest(context context.Context) (*RequestContext, error)

func NewRequestCtx

func NewRequestCtx() *RequestContext

func Request

func Request(context context.Context) (*RequestContext, bool)

func (*RequestContext) EN

func (r *RequestContext) EN() *RequestContext

func (*RequestContext) Empty

func (r *RequestContext) Empty() *RequestContext

func (*RequestContext) GetApp

func (r *RequestContext) GetApp() string

func (*RequestContext) GetClientIp

func (r *RequestContext) GetClientIp() string

func (*RequestContext) GetKv

func (r *RequestContext) GetKv() KV

func (*RequestContext) GetLang

func (r *RequestContext) GetLang() language.Tag

func (*RequestContext) GetRequestId

func (r *RequestContext) GetRequestId() string

func (*RequestContext) GetRoles

func (r *RequestContext) GetRoles() []string

func (*RequestContext) GetSessionId

func (r *RequestContext) GetSessionId() string

func (*RequestContext) GetUserId

func (r *RequestContext) GetUserId() string

func (*RequestContext) GetUsername

func (r *RequestContext) GetUsername() string

func (*RequestContext) TestApp

func (r *RequestContext) TestApp() *RequestContext

func (*RequestContext) ToContext

func (r *RequestContext) ToContext(parent context.Context) context.Context

func (*RequestContext) ToMap

func (r *RequestContext) ToMap() map[string]interface{}

func (*RequestContext) WithApp

func (r *RequestContext) WithApp(app string) *RequestContext

func (*RequestContext) WithClientIp

func (r *RequestContext) WithClientIp(ip string) *RequestContext

func (*RequestContext) WithKv

func (r *RequestContext) WithKv(key string, val interface{}) *RequestContext

func (*RequestContext) WithLang

func (r *RequestContext) WithLang(lang language.Tag) *RequestContext

func (*RequestContext) WithNewRequestId

func (r *RequestContext) WithNewRequestId() *RequestContext

func (*RequestContext) WithRequestId

func (r *RequestContext) WithRequestId(requestId string) *RequestContext

func (*RequestContext) WithRoles

func (r *RequestContext) WithRoles(roles ...string) *RequestContext

func (*RequestContext) WithSessionId

func (r *RequestContext) WithSessionId(sessionId string) *RequestContext

func (*RequestContext) WithUser

func (r *RequestContext) WithUser(userId, username string) *RequestContext

type RetryCfg

type RetryCfg struct {
	NextAttemptFn func(curAttemptTime time.Time, curAttempt int) time.Time
	MaxAttempts   int
}

type SafeMap

type SafeMap[TK comparable, TV any] struct {
	sync.RWMutex
	// contains filtered or unexported fields
}

func NewSafeMap

func NewSafeMap[TK comparable, TV any]() *SafeMap[TK, TV]

func (*SafeMap[TK, TV]) Delete

func (m *SafeMap[TK, TV]) Delete(key TK)

func (*SafeMap[TK, TV]) Get

func (m *SafeMap[TK, TV]) Get(key TK) TV

func (*SafeMap[TK, TV]) Map

func (m *SafeMap[TK, TV]) Map() map[TK]TV

Map returns a copy of the map (it doesn't deep copy)

func (*SafeMap[TK, TV]) Set

func (m *SafeMap[TK, TV]) Set(key TK, val TV)

func (*SafeMap[TK, TV]) TryGet

func (m *SafeMap[TK, TV]) TryGet(key TK) (TV, bool)

type Searchable

type Searchable[TItem any, Rq any] interface {
	// Search searches items by criteria in a pageable manner
	Search(ctx context.Context, rq PagingRequestG[Rq]) (PagingResponseG[TItem], error)
}

Searchable interface provides a search abilities

type SortRequest

type SortRequest struct {
	Field     string `json:"field"`     // Field which is sorted
	Desc      bool   `json:"desc"`      // Desc if true order by desc
	NullsLast bool   `json:"nullsLast"` // NullsLast if true nulls go last
}

SortRequest request to sort data

type String

type String string

func (String) RemoveNewlines

func (s String) RemoveNewlines() String

func (String) TrimCodeEnd

func (s String) TrimCodeEnd() String

func (String) TrimCodeStart

func (s String) TrimCodeStart(code string) String

type Strings

type Strings []string

Strings represents slice of strings

func (Strings) Contains

func (s Strings) Contains(str string) bool

Contains check if a strings is in slice

func (Strings) Distinct

func (s Strings) Distinct() Strings

Distinct returns distinct slice

func (Strings) Equal

func (s Strings) Equal(r Strings) bool

func (Strings) Intersect

func (s Strings) Intersect(r Strings) Strings

func (Strings) Subtract

func (s Strings) Subtract(r Strings) Strings

Subtract returns distinct values from 's' which are not located in 'r'.

func (Strings) ToMap

func (s Strings) ToMap() map[string]struct{}

func (Strings) ToSliceAny

func (s Strings) ToSliceAny() []any

type Suite

type Suite struct {
	suite.Suite

	Ctx context.Context
	// contains filtered or unexported fields
}

func (*Suite) AfterTest

func (s *Suite) AfterTest(suiteName, testName string)

func (*Suite) AssertAppErr

func (s *Suite) AssertAppErr(err error, code string)

func (*Suite) AssertCalled

func (s *Suite) AssertCalled(mock *mock.Mock, methodName string, arguments ...interface{})

AssertCalled asserts that the method was called. It can produce a false result when an argument is a pointer type and the underlying value changed after calling the mocked method.

func (*Suite) AssertNotCalled

func (s *Suite) AssertNotCalled(mock *mock.Mock, methodName string, arguments ...interface{})

AssertNotCalled asserts that the method was not called. It can produce a false result when an argument is a pointer type and the underlying value changed after calling the mocked method.

func (*Suite) AssertNumberOfCalls

func (s *Suite) AssertNumberOfCalls(mock *mock.Mock, methodName string, expectedCalls int)

AssertNumberOfCalls asserts that the method was called expectedCalls times.

func (*Suite) BeforeTest

func (s *Suite) BeforeTest(suiteName, testName string)

func (*Suite) Condition

func (s *Suite) Condition(comp assert.Comparison, msgAndArgs ...interface{})

Condition uses a Comparison to assert a complex condition.

func (*Suite) Contains

func (s *Suite) Contains(el, contains interface{}, msgAndArgs ...interface{})

Contains asserts that the specified string, list(array, slice...) or map contains the specified substring or element.

s.Contains(t, "Hello World", "World")
s.Contains(t, ["Hello", "World"], "World")
s.Contains(t, {"Hello": "World"}, "Hello")

func (*Suite) DefaultLogger

func (s *Suite) DefaultLogger()

func (*Suite) DirExists

func (s *Suite) DirExists(dir string, msgAndArgs ...interface{})

DirExists checks whether a directory exists in the given path. It also fails if the path is a file rather a directory or there is an error checking whether it exists.

func (*Suite) ElementsMatch

func (s *Suite) ElementsMatch(listA, listB interface{}, msgAndArgs ...interface{})

ElementsMatch asserts that the specified listA(array, slice...) is equal to specified listB(array, slice...) ignoring the order of the elements. If there are duplicate elements, the number of appearances of each of them in both lists should match.

s.ElementsMatch(t, [1, 3, 2, 3], [1, 3, 3, 2])

func (*Suite) Empty

func (s *Suite) Empty(object interface{}, msgAndArgs ...interface{})

Empty asserts that the specified object is empty. I.e. nil, "", false, 0 or either a slice or a channel with len == 0.

s.Empty(t, obj)

func (*Suite) Equal

func (s *Suite) Equal(expected interface{}, actual interface{}, msgAndArgs ...interface{})

Equal asserts that two objects are equal.

s.Equal(t, 123, 123)

Pointer variable equality is determined based on the equality of the referenced values (as opposed to the memory addresses). Function equality cannot be determined and will always fail.

func (*Suite) EqualError

func (s *Suite) EqualError(theError error, errString string, msgAndArgs ...interface{})

EqualError asserts that a function returned an error (i.e. not `nil`) and that it is equal to the provided error.

actualObj, err := SomeFunction()
s.EqualError(t, err,  expectedErrorString)

func (*Suite) EqualValues

func (s *Suite) EqualValues(expected interface{}, actual interface{}, msgAndArgs ...interface{})

EqualValues asserts that two objects are equal or convertable to the same types and equal.

s.EqualValues(t, uint32(123), int32(123))

func (*Suite) Error

func (s *Suite) Error(err error, msgAndArgs ...interface{})

Error asserts that a function returned an error (i.e. not `nil`).

  actualObj, err := SomeFunction()
  if s.Error(t, err) {
	   s.Equal(t, expectedError, err)
  }

func (*Suite) ErrorAs

func (s *Suite) ErrorAs(err, target error, msgAndArgs ...interface{})

ErrorAs asserts that at least one of the errors in err's chain matches target, and if so, sets target to that error value. This is a wrapper for errors.As.

func (*Suite) ErrorIs

func (s *Suite) ErrorIs(err, target error, msgAndArgs ...interface{})

ErrorIs asserts that at least one of the errors in err's chain matches target. This is a wrapper for errors.IsAppErr.

func (*Suite) Eventually

func (s *Suite) Eventually(condition func() bool, waitFor time.Duration, tick time.Duration, msgAndArgs ...interface{})

Eventually asserts that given condition will be met in waitFor time, periodically checking target function each tick.

s.Eventually(t, func() bool { return true; }, time.Second, 10*time.Millisecond)

func (*Suite) Exactly

func (s *Suite) Exactly(expected interface{}, actual interface{}, msgAndArgs ...interface{})

Exactly asserts that two objects are equal in value and type.

s.Exactly(t, int32(123), int64(123))

func (*Suite) False

func (s *Suite) False(value bool, msgAndArgs ...interface{})

False asserts that the specified value is false.

s.False(t, myBool)

func (*Suite) Fatal

func (s *Suite) Fatal(msgAndArgs ...interface{})

func (*Suite) FileExists

func (s *Suite) FileExists(path string, msgAndArgs ...interface{})

FileExists checks whether a file exists in the given path. It also fails if the path points to a directory or there is an error when trying to check the file.

func (*Suite) Implements

func (s *Suite) Implements(interfaceObject interface{}, object interface{}, msgAndArgs ...interface{})

Implements asserts that an object is implemented by the specified interface.

s.Implements(t, (*MyInterface)(nil), new(MyObject))

func (*Suite) InDelta

func (s *Suite) InDelta(expected, actual interface{}, delta float64, msgAndArgs ...interface{})

InDelta asserts that the two numerals are within delta of each other.

s.InDelta(t, math.Pi, 22/7.0, 0.01)

func (*Suite) InDeltaMapValues

func (s *Suite) InDeltaMapValues(expected, actual interface{}, delta float64, msgAndArgs ...interface{})

InDeltaMapValues is the same as InDelta, but it compares all values between two maps. Both maps must have exactly the same keys.

func (*Suite) InDeltaSlice

func (s *Suite) InDeltaSlice(expected, actual interface{}, delta float64, msgAndArgs ...interface{})

InDeltaSlice is the same as InDelta, except it compares two slices.

func (*Suite) InEpsilon

func (s *Suite) InEpsilon(expected, actual interface{}, epsilon float64, msgAndArgs ...interface{})

InEpsilon asserts that expected and actual have a relative error less than epsilon

func (*Suite) InEpsilonSlice

func (s *Suite) InEpsilonSlice(expected, actual interface{}, epsilon float64, msgAndArgs ...interface{})

InEpsilonSlice is the same as InEpsilon, except it compares each value from two slices.

func (*Suite) Init

func (s *Suite) Init(logger CLoggerFunc)

func (*Suite) IsType

func (s *Suite) IsType(expectedType interface{}, object interface{}, msgAndArgs ...interface{})

IsType asserts that the specified objects are of the same type.

func (*Suite) JSONEq

func (s *Suite) JSONEq(expected string, actual string, msgAndArgs ...interface{})

JSONEq asserts that two JSON strings are equivalent.

s.JSONEq(t, `{"hello": "world", "foo": "bar"}`, `{"foo": "bar", "hello": "world"}`)

func (*Suite) L

func (s *Suite) L() CLogger

func (*Suite) Len

func (s *Suite) Len(object interface{}, length int, msgAndArgs ...interface{})

Len asserts that the specified object has specific length. Len also fails if the object has a type that len() not accept.

s.Len(t, mySlice, 3)

func (*Suite) Never

func (s *Suite) Never(condition func() bool, waitFor time.Duration, tick time.Duration, msgAndArgs ...interface{})

Never asserts that the given condition doesn't satisfy in waitFor time, periodically checking the target function each tick.

s.Never(t, func() bool { return false; }, time.Second, 10*time.Millisecond)

func (*Suite) Nil

func (s *Suite) Nil(object interface{}, msgAndArgs ...interface{})

Exactly asserts that two objects are equal in value and type.

s.Exactly(t, int32(123), int64(123))

func (*Suite) NoDirExists

func (s *Suite) NoDirExists(dir string, msgAndArgs ...interface{})

NoDirExists checks whether a directory does not exist in the given path. It fails if the path points to an existing _directory_ only.

func (*Suite) NoError

func (s *Suite) NoError(err error, msgAndArgs ...interface{})

NoError asserts that a function returned no error (i.e. `nil`).

  actualObj, err := SomeFunction()
  if s.NoError(t, err) {
	   s.Equal(t, expectedObj, actualObj)
  }

func (*Suite) NoFileExists

func (s *Suite) NoFileExists(path string, msgAndArgs ...interface{})

NoFileExists checks whether a file does not exist in a given path. It fails if the path points to an existing _file_ only.

func (*Suite) NotContains

func (s *Suite) NotContains(el, contains interface{}, msgAndArgs ...interface{})

NotContains asserts that the specified string, list(array, slice...) or map does NOT contain the specified substring or element.

s.NotContains(t, "Hello World", "Earth")
s.NotContains(t, ["Hello", "World"], "Earth")
s.NotContains(t, {"Hello": "World"}, "Earth")

func (*Suite) NotEmpty

func (s *Suite) NotEmpty(object interface{}, msgAndArgs ...interface{})

NotEmpty asserts that the specified object is NOT empty. I.e. not nil, "", false, 0 or either a slice or a channel with len == 0.

if s.NotEmpty(t, obj) {
  s.Equal(t, "two", obj[1])
}

func (*Suite) NotEqual

func (s *Suite) NotEqual(expected interface{}, actual interface{}, msgAndArgs ...interface{})

NotEqual asserts that the specified values are NOT equal.

s.NotEqual(t, obj1, obj2)

Pointer variable equality is determined based on the equality of the referenced values (as opposed to the memory addresses).

func (*Suite) NotEqualValues

func (s *Suite) NotEqualValues(expected interface{}, actual interface{}, msgAndArgs ...interface{})

NotEqualValues asserts that two objects are not equal even when converted to the same type

s.NotEqualValues(t, obj1, obj2)

func (*Suite) NotErrorIs

func (s *Suite) NotErrorIs(err, target error, msgAndArgs ...interface{})

NotErrorIs asserts that at none of the errors in err's chain matches target. This is a wrapper for errors.IsAppErr.

func (*Suite) NotNil

func (s *Suite) NotNil(object interface{}, msgAndArgs ...interface{})

NotNil asserts that the specified object is not nil.

s.NotNil(t, err)

func (*Suite) NotPanics

func (s *Suite) NotPanics(f assert.PanicTestFunc, msgAndArgs ...interface{})

NotPanics asserts that the code inside the specified PanicTestFunc does NOT panic.

s.NotPanics(t, func(){ RemainCalm() })

func (*Suite) NotRegexp

func (s *Suite) NotRegexp(rx interface{}, str interface{}, msgAndArgs ...interface{})

NotRegexp asserts that a specified regexp does not match a string.

s.NotRegexp(t, regexp.MustCompile("starts"), "it's starting")
s.NotRegexp(t, "^start", "it's not starting")

func (*Suite) NotSame

func (s *Suite) NotSame(expected, actual interface{}, msgAndArgs ...interface{})

NotSame asserts that two pointers do not reference the same object.

s.NotSame(t, ptr1, ptr2)

Both arguments must be pointer variables. Pointer variable sameness is determined based on the equality of both type and value.

func (*Suite) NotSubset

func (s *Suite) NotSubset(list, subset interface{}, msgAndArgs ...interface{})

NotSubset asserts that the specified list(array, slice...) contains not all elements given in the specified subset(array, slice...).

s.NotSubset(t, [1, 3, 4], [1, 2], "But [1, 3, 4] does not contain [1, 2]")

func (*Suite) NotZero

func (s *Suite) NotZero(v interface{}, msgAndArgs ...interface{})

NotZero asserts that i is not the zero value for its type.

func (*Suite) Panics

func (s *Suite) Panics(f assert.PanicTestFunc, msgAndArgs ...interface{})

Panics asserts that the code inside the specified PanicTestFunc panics.

s.Panics(t, func(){ GoCrazy() })

func (*Suite) PanicsWithError

func (s *Suite) PanicsWithError(errString string, f assert.PanicTestFunc, msgAndArgs ...interface{})

PanicsWithError asserts that the code inside the specified PanicTestFunc panics, and that the recovered panic value is an error that satisfies the EqualError comparison.

s.PanicsWithError(t, "crazy error", func(){ GoCrazy() })

func (*Suite) PanicsWithValue

func (s *Suite) PanicsWithValue(expected interface{}, f assert.PanicTestFunc, msgAndArgs ...interface{})

PanicsWithValue asserts that the code inside the specified PanicTestFunc panics, and that the recovered panic value equals the expected panic value.

s.PanicsWithValue(t, "crazy error", func(){ GoCrazy() })

func (*Suite) RandPhone

func (s *Suite) RandPhone() string

func (*Suite) Regexp

func (s *Suite) Regexp(rx interface{}, str interface{}, msgAndArgs ...interface{})

Regexp asserts that a specified regexp matches a string.

s.Regexp(t, regexp.MustCompile("start"), "it's starting")
s.Regexp(t, "start...$", "it's not starting")

func (*Suite) Same

func (s *Suite) Same(expected, actual interface{}, msgAndArgs ...interface{})

Same asserts that two pointers reference the same object.

s.Same(t, ptr1, ptr2)

Both arguments must be pointer variables. Pointer variable sameness is determined based on the equality of both type and value.

func (*Suite) Subset

func (s *Suite) Subset(list, subset interface{}, msgAndArgs ...interface{})

Subset asserts that the specified list(array, slice...) contains all elements given in the specified subset(array, slice...).

s.Subset(t, [1, 2, 3], [1, 2], "But [1, 2, 3] does contain [1, 2]")

func (*Suite) True

func (s *Suite) True(value bool, msgAndArgs ...interface{})

True asserts that the specified value is true.

s.True(t, myBool)

func (*Suite) WithinDuration

func (s *Suite) WithinDuration(expected, actual time.Time, delta time.Duration, msgAndArgs ...interface{})

WithinDuration asserts that the two times are within duration delta of each other.

s.WithinDuration(t, time.Now(), time.Now(), 10*time.Second)

func (*Suite) YAMLEq

func (s *Suite) YAMLEq(expected string, actual string, msgAndArgs ...interface{})

YAMLEq asserts that two YAML strings are equivalent.

func (*Suite) Zero

func (s *Suite) Zero(v interface{}, msgAndArgs ...interface{})

Zero asserts that i is the zero value for its type.

type TFlags

type TFlags interface {
	~uint8 | ~uint16 | ~uint32 | ~uint64
}

type TimePeriod

type TimePeriod struct {
	From *time.Time
	To   *time.Time
}

TimePeriod represents period of time

func (TimePeriod) Valid

func (t TimePeriod) Valid() bool

Valid if time period is valid

type TimeRange

type TimeRange [2]HourMinTime

TimeRange represents time interval in format [15:00, 18:00]

func (*TimeRange) EndTime

func (t *TimeRange) EndTime() string

func (TimeRange) MustParse

func (t TimeRange) MustParse(from, to string) TimeRange

func (TimeRange) Parse

func (t TimeRange) Parse(from, to string) (*TimeRange, error)

func (TimeRange) ParseOrEmpty

func (t TimeRange) ParseOrEmpty(from, to string) *TimeRange

func (*TimeRange) StartTime

func (t *TimeRange) StartTime() string

func (TimeRange) Valid

func (t TimeRange) Valid() bool

func (TimeRange) ValidRange

func (t TimeRange) ValidRange() bool

func (TimeRange) Within

func (t TimeRange) Within(tm HourMinTime) bool

func (TimeRange) WithinExcl

func (t TimeRange) WithinExcl(tm HourMinTime) bool

WithinExcl with left inclusive and right exclusive

type Validator

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

func NewValidator

func NewValidator(ctx context.Context) *Validator

func (*Validator) E

func (v *Validator) E() error

func (*Validator) Mth

func (v *Validator) Mth(m string) *Validator

func (*Validator) NotEmptyString

func (v *Validator) NotEmptyString(attr string, val string) *Validator

type WaitGroup

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

WaitGroup wait group with duration timeout

func NewWG

func NewWG() *WaitGroup

func (*WaitGroup) Add

func (w *WaitGroup) Add(delta int)

func (*WaitGroup) Done

func (w *WaitGroup) Done()

func (*WaitGroup) Wait

func (w *WaitGroup) Wait(to time.Duration) bool

type Watchdog

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

Watchdog tracks worker activity. Each worker must call Ping() periodically to confirm it is alive. If a worker does not report for longer than timeout, Check() returns an error.

func NewWatchdog

func NewWatchdog(timeout time.Duration) *Watchdog

NewWatchdog creates a new Watchdog with the given timeout. A worker that does not call Ping() within timeout is considered stuck.

func (*Watchdog) Check

func (w *Watchdog) Check() error

Check inspects all registered workers. Returns an error if at least one worker is stuck (has not reported within timeout).

func (*Watchdog) Disable

func (w *Watchdog) Disable()

Disable turns off the watchdog check. Used during graceful shutdown so liveness does not fail while stopping.

func (*Watchdog) Enable

func (w *Watchdog) Enable()

Enable turns the watchdog check back on.

func (*Watchdog) Ping

func (w *Watchdog) Ping(name string)

Ping updates the worker's last-activity time. A worker should call this on every iteration of its loop.

func (*Watchdog) Register

func (w *Watchdog) Register(name string)

Register starts tracking a worker. After registration the worker must call Ping() periodically.

func (*Watchdog) Unregister

func (w *Watchdog) Unregister(name string)

Unregister stops tracking a worker. Used during a worker's graceful shutdown.

func (*Watchdog) Workers

func (w *Watchdog) Workers() map[string]time.Time

Workers returns the registered workers and their last ping time.

Directories

Path Synopsis
aws
Package aws holds the shared AWS SDK configuration (credentials, region, endpoint) used by the aws sub-packages such as s3 and sqs.
Package aws holds the shared AWS SDK configuration (credentials, region, endpoint) used by the aws sub-packages such as s3 and sqs.
s3
Package s3 provides a client for Amazon S3 (and S3-compatible) object storage.
Package s3 provides a client for Amazon S3 (and S3-compatible) object storage.
sqs
Package sqs provides a client and a message subscriber for Amazon SQS queues.
Package sqs provides a client and a message subscriber for Amazon SQS queues.
Package batch provides a generic worker that accumulates items and flushes them in batches.
Package batch provides a generic worker that accumulates items and flushes them in batches.
Package centrifugo wraps the Centrifugo real-time messaging client, exposing a server-side publisher and a subscriber client.
Package centrifugo wraps the Centrifugo real-time messaging client, exposing a server-side publisher and a subscriber client.
Package cluster wires a service's lifecycle.
Package cluster wires a service's lifecycle.
Package elasticsearch wraps the Elasticsearch client with helpers for building index mappings and settings and for querying.
Package elasticsearch wraps the Elasticsearch client with helpers for building index mappings and settings and for querying.
Package event provides an in-process publish/subscribe event bus.
Package event provides an in-process publish/subscribe event bus.
Package excel reads tabular data (rows) from XLSX spreadsheets.
Package excel reads tabular data (rows) from XLSX spreadsheets.
Package google provides integrations with Google services: OAuth2 token handling and reCAPTCHA verification.
Package google provides integrations with Google services: OAuth2 token handling and reCAPTCHA verification.
Package goroutine provides panic-safe goroutines and error groups.
Package goroutine provides panic-safe goroutines and error groups.
Package grpc provides a gRPC server and client preconfigured with middleware.
Package grpc provides a gRPC server and client preconfigured with middleware.
Package http provides an HTTP server built on gorilla/mux.
Package http provides an HTTP server built on gorilla/mux.
Package kafka provides Kafka producers and subscribers built on segmentio/kafka-go.
Package kafka provides Kafka producers and subscribers built on segmentio/kafka-go.
Package memcache provides a simple in-memory cache with per-item TTL, backed by patrickmn/go-cache.
Package memcache provides a simple in-memory cache with per-item TTL, backed by patrickmn/go-cache.
Package monitoring exposes Prometheus metrics over HTTP.
Package monitoring exposes Prometheus metrics over HTTP.
Package notification builds notification receivers from permission and resource policies.
Package notification builds notification receivers from permission and resource policies.
Package profile exposes the Go net/http/pprof profiling endpoints over a dedicated HTTP server.
Package profile exposes the Go net/http/pprof profiling endpoints over a dedicated HTTP server.
Package retry runs functions with bounded retries using exponential backoff with jitter.
Package retry runs functions with bounded retries using exponential backoff with jitter.
rpc
Package rpc defines a request/response RPC protocol carried over Kafka.
Package rpc defines a request/response RPC protocol carried over Kafka.
client
Package client implements rpc.Client: it sends RPC calls over Kafka and correlates incoming responses back to their pending requests.
Package client implements rpc.Client: it sends RPC calls over Kafka and correlates incoming responses back to their pending requests.
server
Package server implements rpc.Server: it handles incoming RPC requests from Kafka and sends responses back to the calling client.
Package server implements rpc.Server: it handles incoming RPC requests from Kafka and sends responses back to the calling client.
storages
aerospike
Package aerospike provides an Aerospike client connection.
Package aerospike provides an Aerospike client connection.
clickhouse
Package clickhouse provides a ClickHouse connection, both through the native client and the standard database/sql interface.
Package clickhouse provides a ClickHouse connection, both through the native client and the standard database/sql interface.
migration
Package migration runs SQL schema migrations via goose for PostgreSQL and ClickHouse.
Package migration runs SQL schema migrations via goose for PostgreSQL and ClickHouse.
minio
Package minio provides a client for MinIO (S3-compatible) object storage.
Package minio provides a client for MinIO (S3-compatible) object storage.
mongodb
Package mongodb provides a MongoDB client connection with optional TLS.
Package mongodb provides a MongoDB client connection with optional TLS.
pg
Package pg provides a PostgreSQL connection via GORM.
Package pg provides a PostgreSQL connection via GORM.
redis
Package redis provides a Redis client (built on go-redis) with helpers for distributed locks and priority queues.
Package redis provides a Redis client (built on go-redis) with helpers for distributed locks and priority queues.

Jump to

Keyboard shortcuts

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