Skip to content
/ gofuncy Public

Stop using go func(), start using gofuncy.Go()

License

Notifications You must be signed in to change notification settings

foomo/gofuncy

Repository files navigation

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
Loading

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
Loading

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
Loading

How to Contribute

Make a pull request...

License

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

About

Stop using go func(), start using gofuncy.Go()

Resources

License

Code of conduct

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published