channelcheck

package module
v0.0.0-...-2de956b Latest Latest
Warning

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

Go to latest
Published: Aug 27, 2026 License: Apache-2.0 Imports: 10 Imported by: 0

README

Channel Check

Channels are a great feature of Golang but have several footguns that can lead to deadlocks. In particular, if the receiving channel stops processing the messages, a non-blocking channel send would fail to continue. In certain mission-critical sections of code, this could lead to a complete deadlock.

This linter currently has three features:

  • Identify blocking sends
  • Identify non-buffered channel creation
  • Identify buffered channel size exceeds maximum size checks

Many of these will lead to false positives or situations where we want a blocking channel send. In these cases, nolint:channelcheck is easy to add (assuming this is integrated directly with golangci-lint). Regardless, having this issue pointed out automatically is a good way to fix bugs.

Configuration

Each option can be set two ways: as a golangci-lint module setting (under settings.custom.channelcheck.settings:, using the Setting name) or as a standalone analyzer flag (when running the wormhole-lint binary, using the Flag name).

Setting Flag Type Default Description
CheckBlockingSends blocking bool true Flag blocking sends that lack a default/timeout/ticker escape in their enclosing select.
CheckUnbufferedChannels unbuffered bool false Flag creation of unbuffered channels (make(chan T)).
CheckBufferAmount bufferMax uint64 0 Flag buffered channels whose size exceeds this max. 0 disables the check.
IgnoreChannelsByName (none) []string [] Channel/field names whose direct sends are exempt from the blocking-send check (e.g. errC). Settings-only; no standalone flag.

Documentation

Index

Constants

This section is empty.

Variables

View Source
var Analyzer = &analysis.Analyzer{
	Name:  "channelcheck",
	Doc:   "reports channel blocking issues",
	Run:   run,
	Flags: flagSet,
}

Functions

func New

func New(settingsNew any) (register.LinterPlugin, error)

Types

type ChannelCheckPlugin

type ChannelCheckPlugin struct{}

ChannelCheckPlugin is the golangci-lint module-plugin entry point. Its configuration lives in the package-level settings var (populated by New), which is the single source of truth — shared with the standalone cmd/wormhole-lint multichecker, which populates the same var via flags.

func (*ChannelCheckPlugin) BuildAnalyzers

func (f *ChannelCheckPlugin) BuildAnalyzers() ([]*analysis.Analyzer, error)

func (*ChannelCheckPlugin) GetLoadMode

func (f *ChannelCheckPlugin) GetLoadMode() string

type EscapeKind

type EscapeKind int

EscapeKind classifies a non-send CommClause in a select, describing what kind of escape valve (if any) it provides for a sibling send.

const (
	EscapeNone            EscapeKind = iota
	EscapeTimer                      // receive on <-chan time.Time
	EscapeDefaultWithCode            // default: with non-empty body
	EscapeEmptyDefault               // default: with empty body
	EscapeContextDone                // receive on a call to (context.Context).Done()
	EscapeOther                      // any other clause in the statement
)

type SelectAnalysis

type SelectAnalysis struct {
	Sends           []*ast.SendStmt // SendStmts that are direct CommClause heads
	Escapes         []EscapeKind    // one entry per non-send clause (excludes EscapeNone)
	EmptyDefaultPos token.Pos       // position of an empty default clause, or NoPos if none
	ContextDonePos  token.Pos       // position of a <-ctx.Done() clause, or NoPos if none
}

SelectAnalysis is the result of inspecting a select statement.

type Settings

type Settings struct {
	CheckUnbufferedChannels bool     // Enable/disable checking for unbuffered channel creation.
	CheckBufferAmount       uint64   // The amount that can be in a buffer. 0 means don't do this check.
	CheckBlockingSends      bool     // Enable/disable checking for blocking sends without default/timeout.
	CheckEmptyDefault       bool     // Enable/disable the (advisory) empty-default-drops-the-send check.
	IgnoreChannelsByName    []string // Channel/field names whose direct sends are exempt from the blocking-send check.
	// contains filtered or unexported fields
}

Settings holds the configuration for the channelcheck linter.

Jump to

Keyboard shortcuts

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