Documentation ¶
Overview ¶
Package future provides tools for scheduling asynchronous work and collecting the results synchronously from an event loop.
Deprecated: This package should be avoided in favor of the approach implemented by package stream.
The main advantage of using this package over invoking goroutines manually is the structured approach this package provides to joining the results of async work to your application event loop.
Applications that are already using a bus.Connection for each window need only invoke future.TryResults on each event coming from the bus and honor the return value (invalidating the window if true) to start taking advantage of this capablility.
An example:
func eventLoop(w *app.Window, conn bus.Connection) error { for { select { case e := <- w.Events(): switch e := e.(type) { case system.DestroyEvent: return e.Err case system.FrameEvent: // Draw your UI } case e := <- conn.Output(): var changed bool // Do your application-specific event processing here, setting // changed appropriately. changed = future.TryResults(e) || changed if changed { w.Invalidate() } } } }
So elsewhere in your UI, you can now (for example) load data from a database easily:
type UI struct { DB *sql.DB Todos []string } func (ui *UI) loadTodos() { future.Run(func() ([]string, error) { // This closure will execute asynchronously from the UI. rows, err := ui.DB.Query(`SELECT * FROM todos;`) if err != nil { return nil, err } defer rows.Close() var todos []string for rows.Next() { var todo string if err := rows.Scan(&todo); err != nil { return todos, err } todos=append(todos, todo) } return todos, err }, func(todos []string, err error) bool { // This closure will execute synchronously, and can safely modify UI // state. if err != nil { log.Println(err) return false } ui.Todos=todos return true }) }
Index ¶
- func Run[T any](conn bus.Connection, work WorkFunc[T], andThen ThenFunc[T])
- func RunCtx[T any](ctx context.Context, conn bus.Connection, work WorkFuncCtx[T], ...)
- func RunSingle[T any](task *Single, conn bus.Connection, work WorkFuncCtx[T], andThen ThenFuncCtx[T])
- func RunSingleCtx[T any](ctx context.Context, task *Single, conn bus.Connection, work WorkFuncCtx[T], ...)
- func TryResults(event any) bool
- func Update(conn bus.Connection, fn func() bool)
- type Results
- type Single
- type ThenFunc
- type ThenFuncCtx
- type WorkFunc
- type WorkFuncCtx
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func Run ¶
func Run[T any](conn bus.Connection, work WorkFunc[T], andThen ThenFunc[T])
Run schedules work asynchronously and then invokes andThen synchronously on the event loop (when RunSync is invoked). This enables andThen to safely modify UI state because it cannot race against layout code. The most common use for this is to execute a query to a persistent storage API in work, then attach the results to the UI in andThen.
func RunCtx ¶
func RunCtx[T any](ctx context.Context, conn bus.Connection, work WorkFuncCtx[T], andThen ThenFuncCtx[T])
RunCtx schedules work asynchronously and then invokes andThen synchronously on the event loop (when RunSync is invoked). This enables andThen to safely modify UI state because it cannot race against layout code. The most common use for this is to execute a query to a persistent storage API in work, then attach the results to the UI in andThen.
If the provided context is cancelled before the asynchronous work function starts, it will not be executed at all, and zero values will be provided to andThen.
func RunSingle ¶
func RunSingle[T any](task *Single, conn bus.Connection, work WorkFuncCtx[T], andThen ThenFuncCtx[T])
RunSingle acts like RunSingleCtx except that it uses a default context.
func RunSingleCtx ¶
func RunSingleCtx[T any](ctx context.Context, task *Single, conn bus.Connection, work WorkFuncCtx[T], andThen ThenFuncCtx[T])
RunSingleCtx acts like RunCtx except that it accepts a Single. Each time it is invoked, it cancels the context of any future invoked with the same Single parameter. In this way, it implements a sort of queueing, though without any guarantee about the futures not running concurrently. It is safe to invoke RunSingleCtx on the same Single from different goroutines.
func TryResults ¶
TryResults checks if the event is a Results and invokes it synchronously if so. It returns the return value of Results.Run() if event is Results, and false otherwise.
func Update ¶
func Update(conn bus.Connection, fn func() bool)
Update executes a closure synchronous to the event loop. This allows the caller to safely update a ui state for a given window from any goroutine.
Types ¶
type Results ¶
type Results struct {
// contains filtered or unexported fields
}
Results holds the results of async work completed by a future.
type Single ¶
type Single struct {
// contains filtered or unexported fields
}
Single holds cancellation state for a running future, allowing old copies of the future to be cancelled in favor of new ones.
type ThenFunc ¶
ThenFunc is a synchronous handler designed to process the return values of WorkFunc. It should return false if it makes no external state modifications, and true otherwise.
type ThenFuncCtx ¶
ThenFuncCtx is a cancellable synchronous handler designed to process the return values of WorkFuncCtx. It should return false if it makes no external state modifications, and true otherwise.