Skip to content

Commit cc73092

Browse files
committed
Rewrite to use a structure instead of a channel
1 parent 975aed6 commit cc73092

22 files changed

+853
-828
lines changed

.buildkite/pipeline.yaml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,12 @@ steps:
1111
- test-collector#v1.10.0:
1212
files: test.xml
1313
format: junit
14+
env:
15+
GOEXPERIMENT: rangefunc
1416

1517
- label: ':codecov: + :codeclimate: Coverage'
1618
commands:
1719
- go test -race -coverprofile=cover.out ./...
1820
- sh .buildkite/upload_coverage.sh cover.out
21+
env:
22+
GOEXPERIMENT: rangefunc

.github/workflows/test.yml

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,11 @@ name: Test
1010
jobs:
1111
test:
1212
runs-on: ubuntu-latest
13-
env:
14-
GOEXPERIMENT: rangefunc
13+
permissions:
14+
checks: write
15+
contents: read
16+
pull-requests: read
17+
statuses: write
1518
steps:
1619
- name: ✔ Check out
1720
uses: actions/checkout@v4
@@ -20,5 +23,12 @@ jobs:
2023
with:
2124
go-version: "1.22"
2225
check-latest: true
26+
- name: 🧸 golangci-lint
27+
uses: golangci/golangci-lint-action@v4
28+
with:
29+
version: v1.56.2
2330
- name: 🔨 Test
2431
run: go test -race ./...
32+
env:
33+
GOEXPERIMENT: rangefunc
34+

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,3 +13,4 @@
1313
/bin/
1414
/cover.out
1515
/test.xml
16+
/trace.out

README.md

Lines changed: 11 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -12,22 +12,8 @@ The `async` package provides interfaces and utilities for writing asynchronous c
1212

1313
## Motivation
1414

15-
Futures and promises are constructs used for asynchronous and concurrent programming, allowing developers to work with
16-
values that may not be immediately available and can be evaluated in a different execution context.
17-
18-
Go is known for its built-in concurrency features like goroutines and channels.
19-
The select statement further allows for efficient multiplexing and synchronization of multiple channels, thereby
20-
enabling developers to coordinate and orchestrate asynchronous operations effectively.
21-
Additionally, the context package offers a standardized way to manage cancellation, deadlines, and timeouts within
22-
concurrent and asynchronous code.
23-
24-
On the other hand, Go's error handling mechanism, based on explicit error values returned from functions, provides a
25-
clear and concise way to handle errors.
26-
27-
The purpose of this package is to provide a thin layer over channels which simplifies the integration of concurrent
28-
code while providing a cohesive strategy for handling asynchronous errors.
29-
By adhering to Go's standard conventions for asynchronous and concurrent code, as well as error propagation, this
30-
package aims to enhance developer productivity and code reliability in scenarios requiring asynchronous operations.
15+
This is an experimental package which has a similar API as
16+
[fillmore-labs.com/promise](https://pkg.go.dev/fillmore-labs.com/promise), but is implemented with a structure instead.
3117

3218
## Usage
3319

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

3925
```go
40-
ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
26+
ctx, cancel := context.WithTimeout(context.Background(), 2*time.Second)
4127
defer cancel()
4228

43-
future := async.NewFutureAsync(func() (string, error) {
44-
return getMyIP(ctx)
45-
})
29+
query := func() (string, error) {
30+
return getMyIP(ctx) // Capture context with timeout
31+
}
32+
future := async.NewAsync(query)
4633
```
4734

4835
and elsewhere in your program, even in a different goroutine
4936

5037
```go
51-
if ip, err := future.Wait(ctx); err == nil {
38+
if ip, err := future.Await(ctx); err == nil {
5239
slog.Info("Found IP", "ip", ip)
5340
} else {
5441
slog.Error("Failed to fetch IP", "error", err)
@@ -77,27 +64,15 @@ func getMyIP(ctx context.Context) (string, error) {
7764
}
7865
defer func() { _ = resp.Body.Close() }()
7966

80-
ipResponse := &struct {
67+
ipResponse := struct {
8168
Origin string `json:"origin"`
8269
}{}
70+
err = json.NewDecoder(resp.Body).Decode(&ipResponse)
8371

84-
if err := json.NewDecoder(resp.Body).Decode(ipResponse); err != nil {
85-
return "", err
86-
}
87-
88-
return ipResponse.Origin, nil
72+
return ipResponse.Origin, err
8973
}
9074
```
9175

92-
## Concurrency Correctness
93-
94-
When utilizing plain Go channels for concurrency, reasoning over the correctness of concurrent code becomes simpler
95-
compared to some other implementations of futures and promises.
96-
Channels provide a clear and explicit means of communication and synchronization between concurrent goroutines, making
97-
it easier to understand and reason about the flow of data and control in a concurrent program.
98-
99-
Therefore, this library provides a straightforward and idiomatic approach to achieving concurrency correctness.
100-
10176
## Links
10277

10378
- [Futures and Promises](https://en.wikipedia.org/wiki/Futures_and_promises) in the English Wikipedia

async_test.go

Lines changed: 0 additions & 112 deletions
This file was deleted.

0 commit comments

Comments
 (0)