Skip to content

fillmore-labs/async

Repository files navigation

Fillmore Labs Async

Go Reference Build status GitHub Workflow Test Coverage Maintainability Go Report Card License FOSSA Status

The async package provides interfaces and utilities for writing asynchronous code in Go.

Motivation

...

Usage

Assuming you have a synchronous function func getMyIP(ctx context.Context) (string, error) returning your external IP address (see GetMyIP for an example).

Now you can do

package main

import (
	"context"
	"log/slog"
	"time"

	"fillmore-labs.com/async"
)

func main() {
	const timeout = 2 * time.Second

	ctx, cancel := context.WithTimeout(context.Background(), timeout)
	defer cancel()

	future := async.NewAsync(func() (string, error) { return getMyIP(ctx) })

	// other queries

	if ip, err := future.Await(ctx); err == nil {
		slog.Info("Found IP", "ip", ip)
	} else {
		slog.Error("Failed to fetch IP", "error", err)
	}
}

decoupling query construction from result processing.

GetMyIP

Sample code to retrieve your IP address:

package main

import (
	"context"
	"encoding/json"
	"net/http"
)

const serverURL = "https://httpbin.org/ip"

func getMyIP(ctx context.Context) (string, error) {
	req, err := http.NewRequestWithContext(ctx, http.MethodGet, serverURL, nil)
	if err != nil {
		return "", err
	}
	req.Header.Set("Accept", "application/json")

	resp, err := http.DefaultClient.Do(req)
	if err != nil {
		return "", err
	}
	defer func() { _ = resp.Body.Close() }()

	ipResponse := struct {
		Origin string `json:"origin"`
	}{}
	err = json.NewDecoder(resp.Body).Decode(&ipResponse)

	return ipResponse.Origin, err
}

Links