Go: poll a Sume job with a context deadline, next_poll_after_seconds

A Go net/http poller for Sume jobs: 20-minute context deadline, sleeps set by next_poll_after_seconds, stops on data.terminal. Standard library only.

4 min readSume
All posts

Let the server set the pace

The Sume status envelope tells a poller what to do next. Under data it carries status, terminal, result_ready and next_poll_after_seconds, which is null once the job is terminal. A loop that sleeps for that many seconds, and stops the moment terminal is true, is both polite to your read budget and short.

Add a hard deadline with a context so a stuck job cannot hold a goroutine forever. Twenty minutes is a reasonable ceiling for a video job; pick your own.

The program

Run it with SUME_API_KEY and a job id as the first argument: go run poll.go JOB_ID. It uses only the standard library and falls back to a 5-second sleep if the field is missing.

package main

import (
	"context"; "encoding/json"; "fmt"; "net/http"; "os"; "time"
)

type env struct{ Data struct {
	Status string `json:"status"`
	Terminal bool `json:"terminal"`
	Next *float64 `json:"next_poll_after_seconds"`
} `json:"data"` }

func main() {
	ctx, cancel := context.WithTimeout(context.Background(), 20*time.Minute)
	defer cancel()
	url := "https://api.sume.com/v1/jobs/" + os.Args[1] + "/status"
	for {
		req, _ := http.NewRequestWithContext(ctx, "GET", url, nil)
		req.Header.Set("Authorization", "Bearer "+os.Getenv("SUME_API_KEY"))
		res, err := http.DefaultClient.Do(req)
		if err != nil { fmt.Println("stopped:", err); return }
		var e env
		json.NewDecoder(res.Body).Decode(&e); res.Body.Close()
		fmt.Println(e.Data.Status)
		if e.Data.Terminal { return }
		wait := 5.0
		if e.Data.Next != nil { wait = *e.Data.Next }
		time.Sleep(time.Duration(wait * float64(time.Second)))
	}
}

What it leaves out on purpose

  • Retries for 429 and 5xx: add them with the retry-after header if the poller is long-lived.
  • The result fetch: when status is completed, call GET /v1/jobs/{id}/result, which returns 409 job_not_completed before then.
  • Cancel on timeout: a context deadline stops your wait, not the job. Cancel with POST /v1/jobs/{id}/cancel only before generation has started; later it returns 409 job_generation_already_started.

Sources

Related posts

More in Developers

All Developers posts

Written by Sume