Skip to content

docs: clarify config zero-value and clamp semantics#67

Open
MasterOfBinary wants to merge 2 commits into
masterfrom
fix/config-semantics-docs
Open

docs: clarify config zero-value and clamp semantics#67
MasterOfBinary wants to merge 2 commits into
masterfrom
fix/config-semantics-docs

Conversation

@MasterOfBinary

Copy link
Copy Markdown
Owner

Summary

Documentation and contract-locking tests for ConfigValues / Config semantics that were previously unstated or misstated. No behavioral code change.

Changes

  • Config.Get godoc: the min→max clamp applies only when the corresponding max is > 0 (matching the engine's fixConfig); a zero max means "unset", no clamp. The previous wording implied the clamp was unconditional.
  • MaxTime == 0 / MaxItems == 0: documented as "unset / disabled" (no time or count trigger). Previously counter-intuitive (zero reads like "immediately") and undocumented.
  • MinTime == 0 (no minimum wait) and MinItems == 0 (engine treats as 1) documented.
  • Contract-locking tests added: zero-value Get() round-trips, mutators accept zero/extreme values without panic, concurrent Get/Update under -race.

Testing

go test -race ./... green · go vet / gofmt clean. The new tests assert existing behavior to guard against future regressions of the now-corrected contract.

Backwards compatibility

Documentation plus additive tests only. No exported signature changed; no validation added that could reject existing inputs.


Part of a 5-PR set from a full-repo review; file-disjoint and independently mergeable in any order.

🤖 Generated with Claude Code

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request updates the batch configuration documentation to clarify how zero and conflicting values are handled by the engine. It also introduces several contract-locking tests to verify zero-value round-tripping, extreme value handling in mutators, and concurrent read/write safety. The review feedback suggests improving the robustness of the mutator tests by initializing the configurations with non-zero dummy values, ensuring that the mutators can successfully overwrite existing non-zero values with zero.

Comment thread batch/config_test.go
Comment on lines +212 to +226
// Update: replaces all values at once.
cfgUpdate := NewDynamicConfig(nil)
cfgUpdate.Update(tc.values)
if got := cfgUpdate.Get(); got != tc.values {
t.Errorf("Update round-trip mismatch: expected %+v, got %+v", tc.values, got)
}

// UpdateBatchSize + UpdateTiming: the split setters must reach the
// same state, with no clamping or rejection at the config layer.
cfgSplit := NewDynamicConfig(nil)
cfgSplit.UpdateBatchSize(tc.values.MinItems, tc.values.MaxItems)
cfgSplit.UpdateTiming(tc.values.MinTime, tc.values.MaxTime)
if got := cfgSplit.Get(); got != tc.values {
t.Errorf("UpdateBatchSize/UpdateTiming round-trip mismatch: expected %+v, got %+v", tc.values, got)
}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

The test currently initializes cfgUpdate and cfgSplit with nil (which defaults to all zero values). When testing with tc.values that contain zero values (like the "all zero" case), this doesn't actually verify that the mutators can overwrite existing non-zero values with zero. To make this contract-locking test robust, we should initialize the configs with non-zero dummy values first, ensuring that the update to zero is actually applied and verified.

			dummy := ConfigValues{
				MinItems: 99,
				MaxItems: 99,
				MinTime:  99 * time.Second,
				MaxTime:  99 * time.Second,
			}

			// Update: replaces all values at once.
			cfgUpdate := NewDynamicConfig(&dummy)
			cfgUpdate.Update(tc.values)
			if got := cfgUpdate.Get(); got != tc.values {
				t.Errorf("Update round-trip mismatch: expected %+v, got %+v", tc.values, got)
			}

			// UpdateBatchSize + UpdateTiming: the split setters must reach the
			// same state, with no clamping or rejection at the config layer.
			cfgSplit := NewDynamicConfig(&dummy)
			cfgSplit.UpdateBatchSize(tc.values.MinItems, tc.values.MaxItems)
			cfgSplit.UpdateTiming(tc.values.MinTime, tc.values.MaxTime)
			if got := cfgSplit.Get(); got != tc.values {
				t.Errorf("UpdateBatchSize/UpdateTiming round-trip mismatch: expected %+v, got %+v", tc.values, got)
			}

@codecov

codecov Bot commented May 29, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 96.73%. Comparing base (ba2a756) to head (1705ef2).

Additional details and impacted files
@@           Coverage Diff           @@
##           master      #67   +/-   ##
=======================================
  Coverage   96.73%   96.73%           
=======================================
  Files          12       12           
  Lines         368      368           
=======================================
  Hits          356      356           
  Misses          9        9           
  Partials        3        3           

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

MasterOfBinary and others added 2 commits May 30, 2026 00:32
Correct and complete the ConfigValues / Config godoc to match the engine's
actual behavior (batch.go fixConfig + waitForItems):

- Config.Get: the min/max clamp applies only when the corresponding max is
  greater than zero (non-zero); a zero max is unset, so no clamping occurs.
- MaxTime == 0 and MaxItems == 0 mean unset/disabled (no max-time flush, no
  max-count trigger) -- documented explicitly since zero is counter-intuitive.
- MinTime == 0 means no minimum-time wait; MinItems == 0 is treated as 1 by
  the engine (at least one item per batch).

Documentation only; no behavioral change.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Add contract-locking tests at the config-type level that assert existing
behavior, so future regressions against the documented contract are caught:

- ConstantConfig/DynamicConfig Get faithfully round-trips zero values
  (zero carries documented unset/disabled meaning; the config holder must
  not rewrite it -- that is the engine's job).
- Update/UpdateBatchSize/UpdateTiming accept zero and extreme (max-uint64,
  max-duration, min>max) values without panicking or rejecting them
  (backwards-compat guard: no validation at the config layer).
- DynamicConfig concurrent Get/Update/UpdateBatchSize/UpdateTiming under
  -race to lock thread-safety across every exported mutator.

These pass immediately by design; no behavior changed. Tests stay at the
config-type level and assert no batch-flush/engine behavior.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant