Skip to content

v1.7.0 — Drop subsystem rewrite (channel-pool selector)

Choose a tag to compare

@MiwiDots MiwiDots released this 28 Apr 16:37
· 137 commits to main since this release

Major: Drop subsystem rewrite

Replaces ~1500 LoC of parallel multi-drop coordination (drops.go + farmer.go failover/stall machinery) with a ~250 LoC single channel-pool selector. Inspired by TwitchDropsMiner.

Why

v1.5.x → v1.6.5 produced a chain of fixes (exclusive dedup → failover state transfer → drops-enabled filter → stall failover → "pick yourself as replacement" bug) where each fix exposed the next sync bug between per-campaign and per-channel state machines. Collapsing to one channel pick per cycle removes the synchronization surface entirely.

What's new

  • Channel-pool selector (internal/farmer/dropselector.go): pure pipeline filter → buildPool → sort → pick. Channels serving multiple campaigns are deduped — Twitch credits whichever can_earn while we watch. 17 table-driven unit tests.
  • Pin a campaign to override the closest-expiry sort. New PinnedCampaignID config field, PUT /api/drops/{id}/pin endpoint, web-UI pin button, TUI i keybind.
  • Demote-on-stall (minimal recovery): if Twitch fails to credit drop minutes for a picked channel for one cycle, the channel goes into a 30 min cooldown and the selector picks the next-best candidate. Recovers automatically when credit returns.
  • TUI campaign management — new keybinds: t toggle disabled state, i pin/unpin (partial-name match against current campaigns). Web UI is no longer required for these actions.
  • Web UI drops table gains pin button, Status column (ACTIVE / QUEUED / IDLE / DISABLED / COMPLETED), QueueIndex, ETA columns.

What got removed

handleDropFailover, transferDrop, verifyTempChannelHealth (stale-detection part), checkDropProgressStalls, pickExclusiveCampaigns, findAllowedChannelViaDirectory, findLiveFromAllowedChannels, findLiveFromGameDirectory, findLiveFromGameDirectoryExcluding, spadeSlotsSaturated, matchCampaignChannels. Every cycle now picks fresh from the live drops-enabled pool, so failover is implicit (next cycle, next pick). StreamDown and Raid handlers no longer trigger inline failover.

Compatibility

  • Config is backward compatible — old configs load with empty pin
  • Channel-points farming unaffected
  • Spade slot allocation unchanged: P0 (HasActiveDrop) wins slot 1, slot 2 follows existing P1 always-watch / P2 rotate rotation

Net delta

~600 LoC removed, fully unit-tested. Live-verified on first restart cycle: selector picked correctly, stall-cooldown rotated through stalled channels.