Skip to content

feat: add AwaitMeasurement, set default urls#174

Merged
MartinKolarik merged 1 commit intojsdelivr:masterfrom
radulucut:await-m
Oct 21, 2025
Merged

feat: add AwaitMeasurement, set default urls#174
MartinKolarik merged 1 commit intojsdelivr:masterfrom
radulucut:await-m

Conversation

@radulucut
Copy link
Collaborator

  • adds AwaitMeasurement that waits for the measurement to complete.
  • set the default urls for the API.

@coderabbitai
Copy link

coderabbitai bot commented Oct 21, 2025

Walkthrough

This 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

✨ Constants bloom where URLs once scattered,
AwaitMeasurement polls with patient grace,
Five hundred milliseconds, gently tethered—
No more explicit paths cluttering the place! 🎯

Pre-merge checks and finishing touches

❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 40.00% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
✅ Passed checks (2 passed)
Check name Status Explanation
Title Check ✅ Passed The title "feat: add AwaitMeasurement, set default urls" directly corresponds to the two primary changes in this pull request: the introduction of the AwaitMeasurement method in globalping/measurements.go and the addition of public URL constants (GlobalpingAPIURL, GlobalpingAuthURL, GlobalpingDashboardURL) in globalping/client.go with default URL assignment logic. The title is concise, clear, and specific enough to immediately communicate the main changes without being vague or overly broad.
Description Check ✅ Passed The pull request description is related to the changeset and describes the two key modifications: the addition of AwaitMeasurement to handle measurement polling and the implementation of default URLs for the API. While the description is brief, it conveys meaningful information about the primary changes and aligns with the actual modifications present across the relevant files (globalping/measurements.go, globalping/client.go, and associated test and mock files).
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment

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.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

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

📥 Commits

Reviewing files that changed from the base of the PR and between 0cbf943 and 3a64470.

📒 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 AwaitMeasurement fails 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

@MartinKolarik
Copy link
Member

I'll merge this, but if we're using this as a dependency in other projects, we should consider creating a separate globalping-go package similar to https://github.com/jsdelivr/globalping-typescript

@MartinKolarik MartinKolarik merged commit e3a634e into jsdelivr:master Oct 21, 2025
4 checks passed
@radulucut
Copy link
Collaborator Author

I am for it

@radulucut radulucut deleted the await-m branch October 21, 2025 13:03
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.

2 participants