Skip to content

Instantly share code, notes, and snippets.

@thetooth
Last active February 21, 2017 08:30
Show Gist options
  • Save thetooth/06f6952345dd357b3ca22c3327f57e87 to your computer and use it in GitHub Desktop.
Save thetooth/06f6952345dd357b3ca22c3327f57e87 to your computer and use it in GitHub Desktop.
package main
import (
"context"
"fmt"
"io/ioutil"
"net/http"
"os"
"os/signal"
"syscall"
"time"
)
var urlStr = "https://script.google.com/macros/s/AKfycbyd5AcbAnWi2Yn0xhFRbyzS4qMq1VucMVgVvhul5XqS9HkAyJY/exec"
func pollSource(ctx context.Context) error {
errChan := make(chan error, 1)
tick := time.Tick(5 * time.Second)
for {
select {
// Parent canceled this job
case <-ctx.Done():
return fmt.Errorf("canceled")
// Got a tick, we should do something
case <-tick:
go func() {
if res, err := fetch(ctx, urlStr); err != nil {
errChan <- err
} else {
// Heres where you persist the result
fmt.Println(res)
}
}()
// Last tick caused an error, log it, apply hold off to tick?
case err := <-errChan:
fmt.Println(err)
}
}
}
func fetch(ctx context.Context, url string) (string, error) {
var value string
done := make(chan error)
timeout, _ := context.WithTimeout(ctx, 2*time.Second)
// Do something with latency
go func() {
client := &http.Client{}
req, _ := http.NewRequest("GET", url, nil)
req.WithContext(ctx)
resp, err := client.Do(req)
if err != nil {
done <- err
return
}
defer resp.Body.Close()
body, err := ioutil.ReadAll(resp.Body)
if err != nil {
done <- err
return
}
value = string(body)
done <- nil
}()
// Got a timeout! fail with a timeout error
select {
case <-timeout.Done():
return "", fmt.Errorf("timed out")
case err := <-done:
return value, err
}
}
func main() {
ctx, cancel := context.WithCancel(context.Background())
defer cancel()
go func() { fmt.Println(pollSource(ctx)) }()
exitSignal := make(chan os.Signal, 1)
signal.Notify(exitSignal, syscall.SIGINT, syscall.SIGTERM)
<-exitSignal
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment