async

package
v0.0.1-alpha Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Feb 28, 2022 License: Apache-2.0 Imports: 0 Imported by: 0

Documentation

Overview

Async provides tools for asynchronous callback processing using Goroutines

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type AsyncError

type AsyncError struct {
	// contains filtered or unexported fields
}

AsyncError is an async value that will eventually return an error It is similar to a Promise/Future which returns an error The value is supplied by calling SetValue. Once the value is supplied AsyncError is considered completed The value can be retrieved once AsyncError is completed via TryGetValue

func (*AsyncError) SetValue

func (e *AsyncError) SetValue(err error)

Sets the value for the AsyncError. Marks AsyncError as Completed or Fulfilled. This method should only ever be called once per AsyncError instance. Calling this method more than once will panic

func (*AsyncError) TryGetValue

func (e *AsyncError) TryGetValue() (bool, error)

Returns the Status of this AsyncError: Completed(true) or Pending(false) and the value of the AsyncError if it is Completed.

The returned bool is true if Completed, false if Pending If Completed the returned error is the Value of this AsyncError If AsyncError is not completed the returned error is nil.

type AsyncErrorResponseHandler

type AsyncErrorResponseHandler func(error)

The function type of the callback invoked when an AsyncError is Completed

type Mailbox

type Mailbox struct {
	// contains filtered or unexported fields
}

An AsyncMailbox stores AsyncErrors and their associated callbacks and invokes them once the AsyncError is completed

Often times we may spawn go routines in an event loop to do some concurrent work, go routines provide no way to return a response, however we may want to be notified if the work the go routine was doing completed successfully or unsuccessfully, and then take some action based on that result. AsyncMailbox provides a construct to do this.

The below example is a storeValue function, which tries to store A value durably. A value is considered durably stored if it successfully writes to two of three replicas. We want to write to all replicas in parallel and return as soon as two writes succeed. We return an error if < 2 writes succeed

func storeValue(num int) error {
  successfulWrites := 0
  returnedWrites := 0
  mailbox := NewAsyncMailbox()

  writeCallback := func (err error) {
    if err != nil {
      successfulWrites++
    }
    returnedWrites++
  }

  // Send to Replica One
  go func(rsp *AsyncError){
    rsp.SetValue(write(num, "replicaOne"))
  }(mailbox.NewAsyncError(writeCallback))

  // Send to Replica Two
  go func(rsp *AsyncError){
    rsp.SetValue(write(num, "replicaTwo"))
  }(mailbox.NewAsyncError(writeCallback))

  // Send to Replica Three
  go func(rsp *AsyncError){
    rsp.SetValue(write(num, "replicaThree"))
  }(mailbox.NewAsyncError(writeCallback))

  // Value is Considered Durably Stored if at least two write calls succeeded
  for sucessfullWrites < 2 && returnedWrites < 3 {
     mailbox.ProcessMessages()
  }

  if successfulWrites >= 2 {
    return nil
  } else {
    return errors.New("Could Not Durably Store Value")
  }

// a function which makes a call to a durable register
// which is accessed via the network
func write (num int, address string) error { ... }

A Mailbox is not a concurrent structure and should only ever be accessed from a single go routine. This ensures that the callbacks are always executed within the same context and only one at a time. A Mailbox for keeping track of in progress AsyncMessages. This structure is not thread-safe.

func NewMailbox

func NewMailbox() *Mailbox

func (*Mailbox) Count

func (bx *Mailbox) Count() int

func (*Mailbox) NewAsyncError

func (bx *Mailbox) NewAsyncError(cb AsyncErrorResponseHandler) *AsyncError

Creates a NewAsyncError and associates the supplied callback with it. Once the AsyncError has been completed, SetValue called, the callback will be invoked on the next execution of ProcessMessages

func (*Mailbox) ProcessMessages

func (bx *Mailbox) ProcessMessages()

Processes the mailbox. For all messages with completed AsyncErrors the callback function and removes the message from the mailbox

type Runner

type Runner struct {
	// contains filtered or unexported fields
}

An AsyncRunner is a helper class to spawn Go Routines to run AsyncFunctions and to associate callbacks with them. This builds ontop of AsyncMailbox to make simplify the code that needs to be written.

The below example is a storeValue function, which tries to store A value durably. A value is considered durably stored if it successfully writes to two of three replicas. We want to write to all replicas in parallel and return as soon as two writes succeed. We return an error if < 2 writes succeed

func storeValue(num int) error {
  successfulWrites := 0
  returnedWrites := 0

  runner := NewAsyncRunner()

  writeCb := func(err error) {
    if err != nil {
      successfulWrites++
    }
    returnedWrites++
  }

  runner.RunAsync(func() error { return write(num, "replicatOne") }, writeCb)
  runner.RunAsync(func() error { return write(num, "replicatTwo") }, writeCb)
  runner.RunAsync(func() error { return write(num, "replicaThree") }, writeCb)

  for successfulWrites < 2 && returnedWrites < 3 {
    runner.ProcessMessages()
  }

  if successfulWrites >= 2 {
    return nil
  } else {
    return errors.New("Could Not Durably Store Value")
  }
}
// a function which makes a call to a durable register
// which is accessed via the network
func write (num int, address string) error { ... }

func NewRunner

func NewRunner() Runner

func (*Runner) NumRunning

func (r *Runner) NumRunning() int

func (*Runner) ProcessMessages

func (r *Runner) ProcessMessages()

Invokes all callbacks of completed asyncfunctions. Callbacks are ran synchronously and by the calling go routine

func (*Runner) RunAsync

func (r *Runner) RunAsync(f func() error, cb AsyncErrorResponseHandler)

RunAsync creates a go routine to run the specified function f. The callback, cb, is invoked once f is completed by calling ProcessMessages.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL