gofuncy

package module
v0.0.0-...-e316fab Latest Latest
Warning

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

Go to latest
Published: Aug 22, 2024 License: MIT Imports: 16 Imported by: 0

README

gofuncy

Build Status Go Report Card godoc goreleaser

Stop using go func, start using gofuncy!

  • ctx as a first class citizen
  • error return as a first class citizen
  • optional: enable telemetry (metrics & traces)
    • gofuncy.routine.count counter
    • gofuncy.routine.duration histogram
    • gofuncy.channel.sent.count counter
    • gofuncy.channel.sent.duration histogram

Configuration

Environment variables:

  • OTEL_ENABLED: enable telemetry
  • GOFUNCY_CHANNEL_VALUE_EVENTS_ENABLED: creates a span event for every value sent into the channel
  • GOFUNCY_CHANNEL_VALUE_ATTRIBUTE_ENABLED: adds the json dump of the data to the span event

Usage

From:

package main

func main() {
  go func() {
    numbers, err := GenerateNumbers(5)
    if err != nil {
      panic(err)
    }
  }()
}

To:

package main

import (
  "github.com/foomo/gofuncy"
)

func main() {
  errChan := gofuncy.Go(func(ctx context.Context) error {
    numbers, err := GenerateNumbers(5)
    return err
  })
  if err := <-errChan; err != nil {
    panic(err)
  }
}

Concept

Routines
Error

Each routine can return an error that is being returned through an error channel:

errChan := gofuncy.Go(func (ctx context.Context) error {
return nil
})

if err := <- errChan; err != nil {
panic(err)
}
Context

Each routine will receive its own base context, which can be set:

errChan := gofuncy.Go(send(msg), gofuncy.WithContext(context.Background()))
flowchart TB
  subgraph root
    channel[Channel]
    subgraph "Routine A"
      ctxA[ctx] --> senderA
      senderA[Sender]
    end
    subgraph "Routine B"
      ctxB[ctx] --> senderB
      senderB[Sender]
    end
    senderA --> channel
    senderB --> channel
    channel --> receiverC
    subgraph "Routine C"
      ctxC[ctx] --> receiverC
      receiverC[Receiver]
    end
  end
Names

Using the context we will inject a name for the process so that it can always be identified:

flowchart TB
  subgraph root
    channel[Channel]
    subgraph "Routine A"
      ctxA[ctx] -- ctx: sender - a --> senderA
      senderA[Sender]
    end
    subgraph "Routine B"
      ctxB[ctx] -- ctx: sender - b --> senderB
      senderB[Sender]
    end
    senderA --> channel
    senderB --> channel
    channel --> receiverC
    subgraph "Routine C"
      ctxC[ctx] -- ctx: receiver - b --> receiverC
      receiverC[Receiver]
    end
  end
Telemetry

Metrics:

Name Type
gofuncy.routine.count UpDownCounter
gofuncy.routine.duration Histogram
flowchart TB
  subgraph root
    subgraph rA ["Routine A"]
      handler[Handler]
    end
    rA -- gofuncy . routine . count --> Metrics
    rA -- gofuncy . routine . duration --> Metrics
    rA -- span: routine - a --> Trace
  end

How to Contribute

Make a pull request...

License

Distributed under MIT License, please see license file within the code for more details.

Documentation

Index

Constants

This section is empty.

Variables

View Source
var ErrChannelClosed = errors.New("channel is closed")

Functions

func Go

func Go(fn Func, opts ...Option) <-chan error

func ParentRoutineFromContext

func ParentRoutineFromContext(ctx context.Context) string

func RoutineFromContext

func RoutineFromContext(ctx context.Context) string

func SenderFromContext

func SenderFromContext(ctx context.Context) string

Types

type Channel

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

func NewChannel

func NewChannel[T any](opts ...ChannelOption[T]) *Channel[T]

func (*Channel[T]) Close

func (g *Channel[T]) Close()

Close closes the GoChannel Pub/Sub.

func (*Channel[T]) Receive

func (g *Channel[T]) Receive() <-chan *Value[T]

func (*Channel[T]) Send

func (g *Channel[T]) Send(ctx context.Context, values ...T) error

type ChannelOption

type ChannelOption[T any] func(channel *Channel[T])

func ChannelWithBufferSize

func ChannelWithBufferSize[T any](size int) ChannelOption[T]

func ChannelWithCounterName

func ChannelWithCounterName[T any](name string) ChannelOption[T]

func ChannelWithLogger

func ChannelWithLogger[T any](logger *slog.Logger) ChannelOption[T]

func ChannelWithMeter

func ChannelWithMeter[T any](meter metric.Meter) ChannelOption[T]

func ChannelWithTelemetryEnabled

func ChannelWithTelemetryEnabled[T any](enabled bool) ChannelOption[T]

func ChannelWithTracer

func ChannelWithTracer[T any](tracer trace.Tracer) ChannelOption[T]

func ChannelWithValueAttributeEnabled

func ChannelWithValueAttributeEnabled[T any](enabled bool) ChannelOption[T]

func ChannelWithValueEventsEnabled

func ChannelWithValueEventsEnabled[T any](enabled bool) ChannelOption[T]

type Func

type Func func(ctx context.Context) error

type Option

type Option func(*Options)

func ChannelWithHistogramName

func ChannelWithHistogramName(name string) Option

func WithContext

func WithContext(ctx context.Context) Option

func WithCounterName

func WithCounterName(name string) Option

func WithHistogramName

func WithHistogramName(name string) Option

func WithMeter

func WithMeter(meter metric.Meter) Option

func WithName

func WithName(name string) Option

func WithTelemetryEnabled

func WithTelemetryEnabled(enabled bool) Option

type Options

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

type Value

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

func (*Value[T]) Context

func (m *Value[T]) Context() context.Context

Jump to

Keyboard shortcuts

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