Conversation
Remove all deprecated globals, replace mutable validator vars with plain functions, drop WithAdaptiveThrottle[T] in favour of the generic Throttle[T], and set per-instance defaults at construction time so v2 callers never rely on package-level mutable state.
Direct type assertion after errors.Is panics when errRejected is nested inside a wrapping error. Replace with errors.As, which safely traverses the chain. As a side effect, AdaptiveThrottle.Throttle now delegates to Throttle[T] so the classification logic lives in one place.
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes and found 1 potential issue.
Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.

What changed and why
v1 accumulated several mutable package-level globals (
IsRejectedError,ClientSideRejectionError,Now) that made it impossible to configure two throttle instances differently and caused subtle races in tests. This PR introducesgithub.com/deixis/bulwark/v2as a clean break: all configuration lives on the instance, there are no globals left to mutate, and the API surface is trimmed to remove the pieces that didn't pull their weight.Breaking changes from v1
bulwark.IsRejectedError = func(...) {...}WithRejectedErrorFunc(fn)option on each instancebulwark.ClientSideRejectionError(var)bulwark.ErrClientSideRejection(sentinel, compare witherrors.Is)bulwark.Now = func() time.Time {...}WithNow(fn)option on each instanceOnInvalidPriorityClamp/OnInvalidPriorityError/OnInvalidPriorityPanic(vars)ClampInvalidPriority/RejectInvalidPriority/AssertValidPriority(plain functions)WithAdaptiveThrottle[T](...)Throttle[T](ctx, at, priority, fn)— single generic entry pointWithAcceptedErrors(fn)WithRejectedErrorFuncEverything else (
WithRejectedErrorFunc,WithClientSideRejectionError,WithNow,WithRandomSource,WithPriorityValidator, priority constants,RejectedError, fallback signatures) carries over from v1 unchanged.Files
v2/adaptive.go— core throttle, defaults set at construction time, no global fallbacksv2/validator.go— validators as plain functions instead of mutable varsv2/priority.go,v2/context.go,v2/counter.go— carried over from v1, unchangedv2/adaptive_test.go,v2/context_test.go— full test suite targeting the v2 import pathREADME.md— updated to v2 import path,errors.Ischecks, and new classifier APINote
Medium Risk
Introduces a new
v2Go module with a largely new public API surface and behavior around error classification/configuration, plus a dependency upgrade; while v1 remains, consumers migrating to v2 will need careful review and testing.Overview
Adds a new
github.com/deixis/bulwark/v2module (Go 1.26) that removes mutable package-level configuration by making rejection classification, client-side rejection error, time source, RNG, and priority validation per-throttle options, and provides a single genericThrottle[T]entry point alongsideAdaptiveThrottle.Throttle.Updates docs to the
v2import path and new APIs (errors.Is(err, bulwark.ErrClientSideRejection),WithRejectedErrorFunc,DefaultRejectedErrorFunc), adds a comprehensivev2test suite, upgradesgithub.com/deixis/faultstov1.0.1, and updates GitHub Actions to run tests for both modules with different Go versions.Written by Cursor Bugbot for commit a1ad1e3. This will update automatically on new commits. Configure here.