fabianoflorentino/golang-agent-skills

golang-samber-ro

Reactive streams and event-driven programming in Golang using samber/ro — ReactiveX implementation with 150+ type-safe operators, cold/hot observables, 5 subject types (Publish, Behavior, Replay, Async, Unicast), declarative pipelines via Pipe, 40+ plugins…

소스 보기
원본 Skill 문서

원본 저장소의 제목, 예시, 코드, 표, 링크, 이미지를 유지해 표시합니다.

Persona: You are a Go engineer who reaches for reactive streams when data arrives asynchronously or without end. You build pipelines with operators instead of raw goroutine/channel plumbing, and you know when a slice plus lo is the simpler answer.

Modes:

  • Build — expressing an event pipeline as an observable graph.
  • Review — auditing pipelines for unhandled errors, unbounded streams, and hot/cold confusion.
  • Debug — tracing a missed event or a leaked subscription.

When to use: any task centered on samber/ro. For finite collection transforms use samber/lo; for bounded goroutine fan-out the stdlib errgroup may be all you need. Load golang-concurrency and golang-observability alongside when lifecycle and monitoring matter.

Streams vs slices

NeedTool
Transform a slice oncesamber/lo — eager, synchronous
Bounded fan-out with error handlingerrgroup
Infinite event streams (websocket, ticks, fsnotify)samber/ro
Combine several async sources with timingsamber/ro (combine/zip operators)
One source, many consumerssamber/ro hot observables / subjects

The four building blocks

  1. Observable — emits values over time; cold by default (each subscriber triggers its own execution).
  2. Observer — consumes the stream through onNext, onError, onComplete.
  3. Operator — transforms an observable into another, composed by Pipe.
  4. Subscription — the wiring between them; Wait blocks, Unsubscribe cancels.
go
odds := ro.Pipe2(
    ro.FromChannel(rawCh),
    ro.Filter(func(n int) bool { return n%2 != 0 }),
    ro.Map(func(n int) string { return fmt.Sprintf("odd-%d", n) }),
)
odds.Subscribe(ro.NewObserver(
    func(s string) { out <- s },
    func(err error) { log.Printf("stream: %v", err) },
    func() { close(out) },
))

Typed vs untyped pipelines

Use the typed Pipe2Pipe25 family for compile-time chain checking. The bare Pipe takes any and drops type safety — reach for it only when composing operators dynamically.

Cold and hot sources

Cold (the default) re-runs per subscriber: safe, deterministic, but wasteful when the source is expensive. Hot sources share one execution among all subscribers — the natural shape for websockets, DB polls, and any single event source with many consumers.

ConversionBehavior
Share()cold → hot, reference-counted teardown
ShareReplay(n)hot + replays last n values to late joiners
Connectable()hot, but waits for an explicit Connect()
Subjectsnatively hot; you push with Send/Error/Complete
SubjectReplay to late subscribers
PublishSubjectnone
BehaviorSubjectlast value
ReplaySubjectlast N values
AsyncSubjectlast value, and only after completion
UnicastSubjectonly the single subscriber

Subject details and hot-source patterns are in subjects guide.

Operators at a glance

FamilyKey operators
CreationJust, FromSlice, FromChannel, Range, Interval, Defer, Future
TransformMap, MapErr, FlatMap, Scan, Reduce, GroupBy
FilterFilter, Take, Skip, Distinct, First, Last, Find
CombineMerge, Concat, Zip2…Zip6, CombineLatest2…5, Race
ErrorCatch, OnErrorReturn, Retry, RetryWithConfig
TimingDelay, Timeout, ThrottleTime, SampleTime, BufferWithTime
Side effectTap, TapOnNext, TapOnError, TapOnComplete
TerminalCollect, ToSlice, ToChannel, ToMap

The full catalog lives in operators guide.

Common mistakes

MistakeWhy it failsFix
Subscribing without an error callbackerrors vanish silentlyNewObserver(onNext, onError, onComplete)
Bare Pipetype mismatches surface at runtimetyped Pipe2Pipe25
No unsubscribe on infinite streamsgoroutine leak for lifeTakeUntil, context cancellation, explicit Unsubscribe
Share() when cold sufficeslifecycle complexity for no consumershot only when many need the same source
Streams for slice workgoroutine + subscription overhead for a sync opsamber/lo
Not wiring contextstreams ignore shutdown signalsContextWithTimeout / ThrowOnContextCancel

Plugins

30–40+ plugins fold domain operators into pipelines — encoding (JSON, CSV), network (plugins/http, plugins/fsnotify), scheduling (plugins/cron), observability (slog, zap, zerolog), rate limiting, and string/data helpers. Browse plugin ecosystem and real-world recipes in patterns.

Best practices

  1. Always pass all three callbacks; silent stream errors are production time-bombs.
  2. Favor typed Pipe families; reserve Pipe for dynamic chains.
  3. Bound every infinite stream — Take(n), TakeUntil(signal), Timeout(d), or context.
  4. Use Collect for finite streams you want as []T.
  5. lo for data you already hold; ro for data that arrives over time.
  6. Report upstream bugs at samber/ro issues.

Cross-references

  • golang-samber-lo — eager transforms of finite slices.
  • golang-samber-mo — monadic values that thread through pipeline operators.
  • golang-samber-hot — in-memory caching, also shipped as an ro plugin.
  • golang-concurrency — goroutine/channel patterns when streams are overkill.
  • golang-observability — tracing and metrics for reactive pipelines.
  • golang-pkg-go-dev / golang-gopls — package facts and call-site navigation.
같은 저장소의 Skills

더 많은 Skills

모든 Skills
fabianoflorentino
커뮤니티

golang-design-patterns

Idiomatic Golang design patterns — functional options, constructor APIs, init() and global-state avoidance, enums, panic vs error decisions, resource management and lifecycle, graceful shutdown, timeouts and retries, streaming and iterators, and architecture styles (clean, hexagonal, DDD, flat). Apply when choosing between architectural patterns, implementing functional options, designing constructor APIs, setting up graceful shutdown, applying resilience patterns, or asking which idiomatic Go pattern fits a specific problem. Not for wiring a DI container or comparing DI libraries (→ See fabianoflorentino/golang-agent-skills@golang-dependency-injection skill), nor for error wrapping, errors.Is/As, or logging mechanics (→ See fabianoflorentino/golang-agent-skills@golang-error-handling skill).

설치 수
1
GitHub Stars
0
업데이트
9월 14일
fabianoflorentino
커뮤니티

golang-google-wire

Compile-time dependency injection in Golang using google/wire — wire.NewSet, wire.Build, wire.Bind (interface→concrete), wire.Struct, wire.Value, wire.InterfaceValue, wire.FieldsOf, cleanup functions, //go:build wireinject injector files, and generated wiregen.go. Apply when using or adopting google/wire, when the codebase imports github.com/google/wire, or when wiring an application graph at compile time via wire.Build. For runtime DI with reflection, see fabianoflorentino/golang-agent-skills@golang-uber-dig skill.

설치 수
1
GitHub Stars
0
업데이트
9월 14일
fabianoflorentino
커뮤니티

golang-lint

Linting best practices and golangci-lint configuration for Golang projects — running linters, configuring .golangci.yml, suppressing warnings with nolint directives, interpreting lint output, and selecting linters. Use when configuring golangci-lint, asking about lint warnings or nolint suppressions, setting up code quality tooling, or choosing linters. Also use when the user mentions golangci-lint, go vet, staticcheck, or revive. Not for wiring a lint step into a GitHub Actions pipeline (→ See fabianoflorentino/golang-agent-skills@golang-continuous-integration skill).

설치 수
1
GitHub Stars
0
업데이트
9월 14일
fabianoflorentino
커뮤니티

golang-modernize

Modernize Golang code to use recent language features, standard library improvements, and idiomatic patterns. Use when reviewing Go code with old-style patterns, when encountering a deprecation warning, or when the user asks for modernization, a Go version upgrade (e.g. to Go 1.27), or a CI/tooling refresh. Not for structural refactors, extracting functions, or moving code between packages (→ See fabianoflorentino/golang-agent-skills@golang-refactoring skill).

설치 수
1
GitHub Stars
0
업데이트
9월 14일