All Projects → AaronJan → Hunch

AaronJan / Hunch

Licence: Apache-2.0 license
Hunch provides functions like: All, First, Retry, Waterfall etc., that makes asynchronous flow control more intuitive.

Programming Languages

go
31211 projects - #10 most used programming language
Makefile
30231 projects

Projects that are alternatives of or similar to Hunch

Tascalate Concurrent
Implementation of blocking (IO-Bound) cancellable java.util.concurrent.CompletionStage and related extensions to java.util.concurrent.ExecutorService-s
Stars: ✭ 144 (+53.19%)
Mutual labels:  asynchronous, concurrency, concurrent
Rxgo
Reactive Extensions for the Go language.
Stars: ✭ 3,907 (+4056.38%)
Mutual labels:  reactivex, asynchronous, concurrency
Zio
ZIO — A type-safe, composable library for async and concurrent programming in Scala
Stars: ✭ 3,167 (+3269.15%)
Mutual labels:  asynchronous, concurrency, concurrent
Lear
Linux Engine for Asset Retrieval - speed-profiled C HTTP server
Stars: ✭ 165 (+75.53%)
Mutual labels:  asynchronous, concurrency
YACLib
Yet Another Concurrency Library
Stars: ✭ 193 (+105.32%)
Mutual labels:  concurrency, concurrent
Qtpromise
Promises/A+ implementation for Qt/C++
Stars: ✭ 137 (+45.74%)
Mutual labels:  asynchronous, concurrent
Ea Async
EA Async implements async-await methods in the JVM.
Stars: ✭ 1,085 (+1054.26%)
Mutual labels:  asynchronous, concurrency
Threadly
A library of tools to assist with safe concurrent java development. Providing unique priority based thread pools, and ways to distrbute threaded work safely.
Stars: ✭ 196 (+108.51%)
Mutual labels:  asynchronous, concurrency
Bastion
Highly-available Distributed Fault-tolerant Runtime
Stars: ✭ 2,333 (+2381.91%)
Mutual labels:  asynchronous, concurrency
Rxphp
Reactive extensions for PHP
Stars: ✭ 1,580 (+1580.85%)
Mutual labels:  reactivex, asynchronous
ring-channel
Bounded MPMC channel abstraction on top of a ring buffer
Stars: ✭ 24 (-74.47%)
Mutual labels:  channel, asynchronous
Rubico
[a]synchronous functional programming
Stars: ✭ 133 (+41.49%)
Mutual labels:  asynchronous, concurrent
Drone
CLI utility for Drone, an Embedded Operating System.
Stars: ✭ 114 (+21.28%)
Mutual labels:  asynchronous, concurrency
channel
Go-like channels for JavaScript
Stars: ✭ 49 (-47.87%)
Mutual labels:  channel, concurrency
drone-stm32-map
STM32 peripheral mappings for Drone, an Embedded Operating System.
Stars: ✭ 16 (-82.98%)
Mutual labels:  asynchronous, concurrency
Vibe Core
Repository for the next generation of vibe.d's core package.
Stars: ✭ 56 (-40.43%)
Mutual labels:  asynchronous, concurrency
gbp
Golang Best Practices (GBP™)
Stars: ✭ 25 (-73.4%)
Mutual labels:  channel, concurrency
Jdonframework
Domain-Driven-Design Pub/Sub Domain-Events framework
Stars: ✭ 978 (+940.43%)
Mutual labels:  asynchronous, concurrency
Scala Async
An asynchronous programming facility for Scala
Stars: ✭ 1,077 (+1045.74%)
Mutual labels:  asynchronous, concurrency
Rxjava2 Extras
Utilities for use with RxJava 2
Stars: ✭ 167 (+77.66%)
Mutual labels:  reactivex, concurrency
Housekeeper

GitHub tag (latest SemVer) Build status codecov Go Report Card GitHub GoDoc

Hunch

Hunch provides functions like: All, First, Retry, Waterfall etc., that makes asynchronous flow control more intuitive.

About Hunch

Go have several concurrency patterns, here're some articles:

But nowadays, using the context package is the most powerful pattern.

So base on context, Hunch provides functions that can help you deal with complex asynchronous logics with ease.

Usage

Installation

go get

$ go get -u -v github.com/aaronjan/hunch

go mod (Recommended)

import "github.com/aaronjan/hunch"
$ go mod tidy

Types

type Executable func(context.Context) (interface{}, error)

type ExecutableInSequence func(context.Context, interface{}) (interface{}, error)

API

All

func All(parentCtx context.Context, execs ...Executable) ([]interface{}, error) 

All returns all the outputs from all Executables, order guaranteed.

Examples
ctx := context.Background()
r, err := hunch.All(
    ctx,
    func(ctx context.Context) (interface{}, error) {
        time.Sleep(300 * time.Millisecond)
        return 1, nil
    },
    func(ctx context.Context) (interface{}, error) {
        time.Sleep(200 * time.Millisecond)
        return 2, nil
    },
    func(ctx context.Context) (interface{}, error) {
        time.Sleep(100 * time.Millisecond)
        return 3, nil
    },
)

fmt.Println(r, err)
// Output:
// [1 2 3] <nil>

Take

func Take(parentCtx context.Context, num int, execs ...Executable) ([]interface{}, error)

Take returns the first num values outputted by the Executables.

Examples
ctx := context.Background()
r, err := hunch.Take(
    ctx,
    // Only need the first 2 values.
    2,
    func(ctx context.Context) (interface{}, error) {
        time.Sleep(300 * time.Millisecond)
        return 1, nil
    },
    func(ctx context.Context) (interface{}, error) {
        time.Sleep(200 * time.Millisecond)
        return 2, nil
    },
    func(ctx context.Context) (interface{}, error) {
        time.Sleep(100 * time.Millisecond)
        return 3, nil
    },
)

fmt.Println(r, err)
// Output:
// [3 2] <nil>

Last

func Last(parentCtx context.Context, num int, execs ...Executable) ([]interface{}, error)

Last returns the last num values outputted by the Executables.

Examples
ctx := context.Background()
r, err := hunch.Last(
    ctx,
    // Only need the last 2 values.
    2,
    func(ctx context.Context) (interface{}, error) {
        time.Sleep(300 * time.Millisecond)
        return 1, nil
    },
    func(ctx context.Context) (interface{}, error) {
        time.Sleep(200 * time.Millisecond)
        return 2, nil
    },
    func(ctx context.Context) (interface{}, error) {
        time.Sleep(100 * time.Millisecond)
        return 3, nil
    },
)

fmt.Println(r, err)
// Output:
// [2 1] <nil>

Waterfall

func Waterfall(parentCtx context.Context, execs ...ExecutableInSequence) (interface{}, error)

Waterfall runs ExecutableInSequences one by one, passing previous result to next Executable as input. When an error occurred, it stop the process then returns the error. When the parent Context canceled, it returns the Err() of it immediately.

Examples
ctx := context.Background()
r, err := hunch.Waterfall(
    ctx,
    func(ctx context.Context, n interface{}) (interface{}, error) {
        return 1, nil
    },
    func(ctx context.Context, n interface{}) (interface{}, error) {
        return n.(int) + 1, nil
    },
    func(ctx context.Context, n interface{}) (interface{}, error) {
        return n.(int) + 1, nil
    },
)

fmt.Println(r, err)
// Output:
// 3 <nil>

Retry

func Retry(parentCtx context.Context, retries int, fn Executable) (interface{}, error)

Retry attempts to get a value from an Executable instead of an Error. It will keeps re-running the Executable when failed no more than retries times. Also, when the parent Context canceled, it returns the Err() of it immediately.

Examples
count := 0
getStuffFromAPI := func() (int, error) {
    if count == 5 {
        return 1, nil
    }
    count++

    return 0, fmt.Errorf("timeout")
}

ctx := context.Background()
r, err := hunch.Retry(
    ctx,
    10,
    func(ctx context.Context) (interface{}, error) {
        rs, err := getStuffFromAPI()

        return rs, err
    },
)

fmt.Println(r, err, count)
// Output:
// 1 <nil> 5

Credits

Heavily inspired by Async and ReactiveX.

Licence

Apache 2.0

Note that the project description data, including the texts, logos, images, and/or trademarks, for each open source project belongs to its rightful owner. If you wish to add or remove any projects, please contact us at [email protected].