close
Skip to content

Optimizer: reduce interval to 15min#29137

Merged
andig merged 6 commits into
masterfrom
chore/opt2
Apr 15, 2026
Merged

Optimizer: reduce interval to 15min#29137
andig merged 6 commits into
masterfrom
chore/opt2

Conversation

@andig
Copy link
Copy Markdown
Member

@andig andig commented Apr 15, 2026

Add "Optimize now" button for manual updates. Becomes available again once ui has received new optimizer data.

optimize.now.webm

TODO

  • Add update button to debug view
  • Update every 15min

@andig andig added the experimental Experimental feature label Apr 15, 2026
Copy link
Copy Markdown
Contributor

@sourcery-ai sourcery-ai Bot left a comment

Choose a reason for hiding this comment

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

Hey - I've found 2 issues, and left some high level feedback:

  • Access to the package-level optimizerUpdated timestamp is now happening from multiple goroutines (e.g. in updateMeters, optimizerUpdateAsync, and via Optimize) without synchronization, which will cause a data race; consider guarding it with a mutex or using an atomic.Value/atomic.Int64 to store the time.
  • The new Optimize API endpoint triggers optimizerUpdateAsync without checking optimizerEnabled or the tariff slot interval, which means it can bypass the gating logic in updateMeters; if this is not intentional for debug only, align its preconditions with the existing optimizer trigger.
Prompt for AI Agents
Please address the comments from this code review:

## Overall Comments
- Access to the package-level `optimizerUpdated` timestamp is now happening from multiple goroutines (e.g. in `updateMeters`, `optimizerUpdateAsync`, and via `Optimize`) without synchronization, which will cause a data race; consider guarding it with a mutex or using an `atomic.Value`/`atomic.Int64` to store the time.
- The new `Optimize` API endpoint triggers `optimizerUpdateAsync` without checking `optimizerEnabled` or the tariff slot interval, which means it can bypass the gating logic in `updateMeters`; if this is not intentional for debug only, align its preconditions with the existing optimizer trigger.

## Individual Comments

### Comment 1
<location path="core/site_optimizer.go" line_range="33" />
<code_context>

-	updated time.Time
-	mu      atomic.Uint32
+	optimizerUpdated time.Time
+	mu               atomic.Uint32
 )
</code_context>
<issue_to_address>
**issue (bug_risk):** Access to `optimizerUpdated` is not synchronized, which can cause a data race

`optimizerUpdated` is written in `optimizerUpdateAsync` (in the defer) and read from `optimizerUpdateAsync`, `updateMeters`, and via `Optimize` across multiple goroutines. Because `time.Time` is not safe for concurrent read/write, this introduces a data race. Please store the timestamp in an atomic type (e.g., `atomic.Int64` with `UnixNano`) or guard it with a mutex so all accesses are synchronized.
</issue_to_address>

### Comment 2
<location path="core/site_api.go" line_range="39-40" />
<code_context>
 }

+// Optimize updates the optimizer
+func (site *Site) Optimize() error {
+	go site.optimizerUpdateAsync()
+	return nil
+}
</code_context>
<issue_to_address>
**🚨 issue (security):** Public `Optimize` bypasses existing authorization/feature checks applied in `updateMeters`

`updateMeters` enforces `sponsor.IsAuthorized()` and `optimizerEnabled()` before calling `optimizerUpdateAsync`, but `Optimize` calls it directly and is exposed via HTTP. This allows optimization to run even when the optimizer is disabled or the caller wouldn’t normally be authorized. If that behavior isn’t explicitly desired, please apply the same checks here (or centralize them inside `optimizerUpdateAsync`/a shared helper) so all entry points are consistently guarded.
</issue_to_address>

Sourcery is free for open source - if you like our reviews please consider sharing them ✨
Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.

Comment thread core/site_optimizer.go
Comment thread core/site_api.go
Comment thread core/site_optimizer.go
defer mu.Unlock()

if !mu.CompareAndSwap(0, 1) {
if time.Since(optimizerUpdated) < 2*time.Minute {
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

@andig dont see the 15min interval

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

@andig andig merged commit f69252e into master Apr 15, 2026
8 checks passed
@andig andig deleted the chore/opt2 branch April 15, 2026 15:04
@nmd111956-dot

This comment was marked as low quality.

@nmd111956-dot

This comment was marked as low quality.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

experimental Experimental feature

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants