feat: add AwaitMeasurement, set default urls#174
feat: add AwaitMeasurement, set default urls#174MartinKolarik merged 1 commit intojsdelivr:masterfrom
Conversation
radulucut
commented
Oct 21, 2025
- adds AwaitMeasurement that waits for the measurement to complete.
- set the default urls for the API.
WalkthroughThis pull request refactors URL configuration by introducing three public constants (GlobalpingAPIURL, GlobalpingAuthURL, GlobalpingDashboardURL) in the globalping package and using them as defaults when creating a new client, removing the need to pass these URLs through configuration. A new AwaitMeasurement method is added to the Client interface that polls for measurement completion every 500ms. Related URL fields are removed from utils/config.go, and the mock client is updated to include the new method. A TODO comment flags a future opportunity to replace GetMeasurement with AwaitMeasurement. Poem
Pre-merge checks and finishing touches❌ Failed checks (1 warning)
✅ Passed checks (2 passed)
✨ Finishing touches
🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Actionable comments posted: 1
🧹 Nitpick comments (1)
globalping/measurements.go (1)
165-191: Consider extracting duplicate unmarshal logic.The unmarshal and error-handling logic is duplicated between the initial fetch (lines 166-176) and the polling loop (lines 179-189). Extracting this into a helper function would reduce duplication and improve maintainability.
+func (c *client) fetchAndUnmarshalMeasurement(id string) (*Measurement, error) { + respBytes, err := c.GetMeasurementRaw(id) + if err != nil { + return nil, err + } + m := &Measurement{} + err = json.Unmarshal(respBytes, m) + if err != nil { + return nil, &MeasurementError{ + Message: fmt.Sprintf("invalid get measurement format returned: %v %s", err, string(respBytes)), + } + } + return m, nil +} + func (c *client) AwaitMeasurement(id string) (*Measurement, error) { - respBytes, err := c.GetMeasurementRaw(id) + m, err := c.fetchAndUnmarshalMeasurement(id) if err != nil { return nil, err } - m := &Measurement{} - err = json.Unmarshal(respBytes, m) - if err != nil { - return nil, &MeasurementError{ - Message: fmt.Sprintf("invalid get measurement format returned: %v %s", err, string(respBytes)), - } - } for m.Status == StatusInProgress { time.Sleep(500 * time.Millisecond) - respBytes, err := c.GetMeasurementRaw(id) + m, err = c.fetchAndUnmarshalMeasurement(id) if err != nil { return nil, err } - err = json.Unmarshal(respBytes, m) - if err != nil { - return nil, &MeasurementError{ - Message: fmt.Sprintf("invalid get measurement format returned: %v %s", err, string(respBytes)), - } - } } return m, nil }
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (7)
cmd/root.go(1 hunks)globalping/client.go(2 hunks)globalping/measurements.go(2 hunks)globalping/measurements_test.go(1 hunks)mocks/mock_client.go(1 hunks)utils/config.go(0 hunks)view/output.go(1 hunks)
💤 Files with no reviewable changes (1)
- utils/config.go
🧰 Additional context used
🧬 Code graph analysis (3)
globalping/measurements_test.go (2)
globalping/client.go (2)
NewClient(99-143)Config(58-71)globalping/models.go (1)
StatusFinished(96-96)
globalping/measurements.go (1)
globalping/models.go (3)
Measurement(241-250)MeasurementError(59-64)StatusInProgress(93-93)
mocks/mock_client.go (1)
globalping/models.go (1)
Measurement(241-250)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
- GitHub Check: windows-latest Go 1.23 Tests
🔇 Additional comments (2)
globalping/measurements_test.go (1)
1051-1074: Verify that polling actually occurred and add test timeout.The test validates the final result but doesn't confirm that the polling loop executed as expected. Additionally, without a timeout, this test could hang indefinitely if
AwaitMeasurementfails to complete.Consider these improvements:
func Test_AwaitMeasurement(t *testing.T) { count := 0 server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { w.WriteHeader(http.StatusOK) var err error if count == 3 { _, err = w.Write([]byte(`{"id":"abcd", "status": "finished"}`)) } else { _, err = w.Write([]byte(`{"id":"abcd", "status": "in-progress"}`)) } if err != nil { panic(err) } count++ })) defer server.Close() client := NewClient(Config{APIURL: server.URL}) + + // Add timeout to prevent test hanging + done := make(chan struct{}) + var res *Measurement + var err error + go func() { + res, err = client.AwaitMeasurement("abcd") + close(done) + }() + + select { + case <-done: + // success + case <-time.After(5 * time.Second): + t.Fatal("test timed out - AwaitMeasurement did not complete") + } - res, err := client.AwaitMeasurement("abcd") if err != nil { t.Error(err) } assert.Equal(t, "abcd", res.ID) assert.Equal(t, StatusFinished, res.Status) + assert.Equal(t, 4, count, "Expected 4 polling requests (3 in-progress + 1 finished)") }globalping/client.go (1)
9-13: LGTM!The URL constants, interface extension, default URL assignment, and token initialization logic are all well-structured and correctly implemented. The changes provide sensible defaults while maintaining backward compatibility for users who explicitly set URLs.
Also applies to: 26-29, 61-68, 112-141
|
I'll merge this, but if we're using this as a dependency in other projects, we should consider creating a separate |
|
I am for it |