Skip to content

Commit

Permalink
Rewrite to use a structure instead of a channel
Browse files Browse the repository at this point in the history
  • Loading branch information
eikemeier committed Mar 15, 2024
1 parent 975aed6 commit e6f9295
Show file tree
Hide file tree
Showing 25 changed files with 874 additions and 828 deletions.
4 changes: 4 additions & 0 deletions .buildkite/pipeline.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,12 @@ steps:
- test-collector#v1.10.0:
files: test.xml
format: junit
env:
GOEXPERIMENT: rangefunc

- label: ':codecov: + :codeclimate: Coverage'
commands:
- go test -race -coverprofile=cover.out ./...
- sh .buildkite/upload_coverage.sh cover.out
env:
GOEXPERIMENT: rangefunc
4 changes: 4 additions & 0 deletions .codeclimate.yml
Original file line number Diff line number Diff line change
Expand Up @@ -12,3 +12,7 @@ exclude_patterns:
- "go.mod"
- "go.sum"
- "LICENSE"
- "nocopy.go"
engines:
golangci:
enabled: true
2 changes: 1 addition & 1 deletion .github/codecov.yml
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,4 @@ coverage:
project: false
patch: false
ignore:
- internal/mocks
- nocopy.go
13 changes: 11 additions & 2 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,11 @@ name: Test
jobs:
test:
runs-on: ubuntu-latest
env:
GOEXPERIMENT: rangefunc
permissions:
checks: write
contents: read
pull-requests: read
statuses: write
steps:
- name: ✔ Check out
uses: actions/checkout@v4
Expand All @@ -20,5 +23,11 @@ jobs:
with:
go-version: "1.22"
check-latest: true
- name: 🧸 golangci-lint
uses: golangci/golangci-lint-action@v4
with:
version: v1.56.2
- name: 🔨 Test
run: go test -race ./...
env:
GOEXPERIMENT: rangefunc
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -13,3 +13,4 @@
/bin/
/cover.out
/test.xml
/trace.out
48 changes: 12 additions & 36 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,27 +7,14 @@
[![Maintainability](https://api.codeclimate.com/v1/badges/72fe9626fb821fc70251/maintainability)](https://codeclimate.com/github/fillmore-labs/async-exp/maintainability)
[![Go Report Card](https://goreportcard.com/badge/fillmore-labs.com/exp/async)](https://goreportcard.com/report/fillmore-labs.com/exp/async)
[![License](https://img.shields.io/github/license/fillmore-labs/exp-async)](https://www.apache.org/licenses/LICENSE-2.0)
[![FOSSA Status](https://app.fossa.com/api/projects/git%2Bgithub.com%2Ffillmore-labs%2Fasync-exp.svg?type=shield&issueType=license)](https://app.fossa.com/projects/git%2Bgithub.com%2Ffillmore-labs%2Fasync-exp)

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

## Motivation

Futures and promises are constructs used for asynchronous and concurrent programming, allowing developers to work with
values that may not be immediately available and can be evaluated in a different execution context.

Go is known for its built-in concurrency features like goroutines and channels.
The select statement further allows for efficient multiplexing and synchronization of multiple channels, thereby
enabling developers to coordinate and orchestrate asynchronous operations effectively.
Additionally, the context package offers a standardized way to manage cancellation, deadlines, and timeouts within
concurrent and asynchronous code.

On the other hand, Go's error handling mechanism, based on explicit error values returned from functions, provides a
clear and concise way to handle errors.

The purpose of this package is to provide a thin layer over channels which simplifies the integration of concurrent
code while providing a cohesive strategy for handling asynchronous errors.
By adhering to Go's standard conventions for asynchronous and concurrent code, as well as error propagation, this
package aims to enhance developer productivity and code reliability in scenarios requiring asynchronous operations.
This is an experimental package which has a similar API as
[fillmore-labs.com/promise](https://pkg.go.dev/fillmore-labs.com/promise), but is implemented with a structure instead.

## Usage

Expand All @@ -37,18 +24,19 @@ address (see [GetMyIP](#getmyip) for an example).
Now you can do

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

future := async.NewFutureAsync(func() (string, error) {
return getMyIP(ctx)
})
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

```go
if ip, err := future.Wait(ctx); err == nil {
if ip, err := future.Await(ctx); err == nil {
slog.Info("Found IP", "ip", ip)
} else {
slog.Error("Failed to fetch IP", "error", err)
Expand Down Expand Up @@ -77,27 +65,15 @@ func getMyIP(ctx context.Context) (string, error) {
}
defer func() { _ = resp.Body.Close() }()

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

if err := json.NewDecoder(resp.Body).Decode(ipResponse); err != nil {
return "", err
}

return ipResponse.Origin, nil
return ipResponse.Origin, err
}
```

## Concurrency Correctness

When utilizing plain Go channels for concurrency, reasoning over the correctness of concurrent code becomes simpler
compared to some other implementations of futures and promises.
Channels provide a clear and explicit means of communication and synchronization between concurrent goroutines, making
it easier to understand and reason about the flow of data and control in a concurrent program.

Therefore, this library provides a straightforward and idiomatic approach to achieving concurrency correctness.

## Links

- [Futures and Promises](https://en.wikipedia.org/wiki/Futures_and_promises) in the English Wikipedia
112 changes: 0 additions & 112 deletions async_test.go

This file was deleted.

Loading

0 comments on commit e6f9295

Please sign in to comment.