Skip to content

fillmore-labs/async-exp

Repository files navigation

Fillmore Labs Async (Experimental)

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

This is an experimental package which has a similar API as fillmore-labs.com/promise, but is implemented with a structure instead.

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

	ctx, cancel := context.WithTimeout(context.Background(), 2*time.Second)
	defer cancel()

	query := func() (string, error) {
		return getMyIP(ctx) // Capture context with timeout
	}
	future := async.NewAsync(query)

and elsewhere in your program, even in a different goroutine

	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:

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