The github.com/maniartech/async
is a tiny go library that aims to simplify the goroutine orchestration using easy to handle Async/Await pattern. This library provides a super-easy way to orchestrate the Goroutines using easily readable declarative syntax.
Run the following command in your project to get the async
.
go get github.com/maniartech/async
A simple async/await!
package main
import "github.com/maniartech/async"
func main() {
// Executes the async function in a new goroutine and
// awaits for the result.
result, err := async.Go(Process).Await()
if err != nil {
panic("An error occured while executing Process")
}
// Pass the result of previous goroutine to the next one!
result, err = async.Go(Process2, result).Await()
if err != nil {
panic("An error occured while executing Process2")
}
println(p1.Result.Value, p2.Result.value)
}
-
async.Go(ChoreographyHandler, ...interfaces{}) *Promsie
Executes the function in a new goroutine and returns a future. The future can be awaited until the execution is finished and results are returned.
Example:
// Return the pointer to Choreography future := async.Go(complexFunction) future.Await() // Awaits here! fmt.Printf("Result: %+v", future.Result) // Use await to return the results and error result, err := async.Go(complexFunction).Await() if err == nil { fmt.Printf("Result: %+v", future.Result) }
-
async.GoC(futures ...*Choreography) *Choreography
Executes the specified futures in the concurrent manner. Returns the future which can be used to await
-
async.GoQ(futures ...*Choreography) *Choreography
Executes the specified futures in the sequencial manner. Returns the future which can be used to await
The following hypothetical example shows how a complex goroutines pipeline can be orchestrated using a simple structure!
import "github.com/maniartech/async"
// HandleResource processes the various activities
// on the specified resource. All these activities
// are executed using their goroutines and
// in an orchestrated manner.
//
// This orchestration provides the concurrent, faster yet
// controlled execution of various activities.
//
// |-----Go---------------------| |-----Go----|
// | | | |
// ----GoQ----GoC----GoQ->>-Go->>-Go->>-Go--|----GoC----Go----|----Await----
// | | | |
// | |-----Go----| | |-----Go----|
// | | | |
// |-----GoC----Go----|---------|
// | |
// |-----Go----|
//
func HandleResource(resourceId int) {
async.GoQ(
async.GoC( // GoC: Concurrent execution
async.Go(keepInfraReady),
async.GoQ( // GoQ: Sequential execution
async.Go(fetchResource, resourceId),
async.Go(processResource),
async.Go(submitResource),
),
async.GoC(
async.Go(prepareDependencyA)
async.Go(prepareDependencyB)
async.Go(prepareDependencyC)
)
),
async.GoC(
async.Go(postToSocialMedia),
async.Go(sendNotifications),
async.Go(submitReport),
)
).Await()
}
import "github.com/maniartech/conductor"
func HandleResource(resourceId int) {
choreographer.Async(
choreographer.Sync(
choreographer.Func(keepInfraReady),
choreographer.Func(fetchResource, resourceId),
choreographer.Async(
choreographer.Sync(
choreographer.Func(processA),
choreographer.Func(submitA),
).Name("Process A"),
choreographer.Sync(
choreographer.Func(processB),
choreographer.Func(submitB),
).Name("ProcessB"),
choreographer.Sync(
choreographer.Func(processC).OnError(handleError).Retry(3, 5*time.Second).Timeout(10*time.Second),
choreographer.Func(submitC).Delay(5*time.Second),
).Name("ProcessC"),
),
).Name("Update Resource"),
choreographer.Async(
choreographer.Func(sendEmails),
choreographer.Func(sendMessages),
).Name("Send Notification")
).Await()
}