progress

package module
v0.1.0-beta Latest Latest
Warning

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

Go to latest
Published: May 28, 2023 License: MIT Imports: 3 Imported by: 0

README

⏱️ the progress.Reader interface

The io.Reader of reporting progress.


Go Reference Run unit tests

Progress monitoring is a crucial part of many applications, and deserves a simple, standardized interface.

The progress.Reader interface aims to be just that.

progress.Reader interface
    DoneChan() (done chan struct{}, completed bool)
    Count() (finished uint64, total uint64)

To drive adoption and provide practical utility, we've also included handy tools right out of the box! 📦

progress.NewLongRunningJob

🤩 If you like the idea, here's the fastest way to expose a progress.Reader.

This concurrency-safe utility makes instrumenting your long-running functions with a Reader implementation absolutely painless. Support progress and make your library consumers extremely happy!

progress.Extend(Reader)

This simple wrapper adds helpful functions to a Reader, such as estimating the remaining time:

PerSecond() float64
Remaining() time.Duration
Percentage() float64
InProgress() bool

progress.Logger(Reader)

Instantly start a goroutine that keeps an eye on a Reader and logs informative updates! 👀 Here's what it looks like today:

searching:  49% (20.69/s, 1.256483582s remaining)
searching:  56% (18.01/s, 1.221804358s remaining)
searching:  80% (20.37/s, 490.981158ms remaining)
searching: 100% (21.98/s, 0s remaining)

progress.WaitGroup

Drop in replacement for sync.WaitGroup that satisfies the Reader interface.


📝 Todo List

Here's some simple ideas for those looking to contribute.

  • Satisfy progress.Reader with just a count.
  • Return a progress.Reader from a slice or channel.
  • Create a pretty terminal progress bar.
  • Experiment with passing return types through.

Documentation

Overview

Package progress offers a simple, standardized interface for monitoring progress in your applications.

This package exposes the progress.Reader interface, designed to be similar in spirit to io.Reader but for progress reporting. This interface makes tracking long-running tasks and their progress a breeze.

The interface defines two key methods:

- DoneChan() returns a channel that signals when the task is done, and a boolean indicating if the task is completed. - Count() provides the current count of finished tasks and the total number of tasks.

In addition to the interface, the package provides several useful tools:

- progress.NewLongRunningJob: A concurrency-safe utility for instrumenting long-running functions with a progress.Reader. - progress.Extend(Reader): A simple wrapper that adds useful methods to a Reader, such as estimating remaining time. - progress.Logger(Reader): Starts a goroutine to log updates from a Reader. - progress.WaitGroup: A drop-in replacement for sync.WaitGroup that implements the Reader interface.

By using this package, you can make your long-running tasks and functions more informative and user-friendly, improving the overall experience for your library consumers.

For those interested in contributing, there are several areas where the functionality of this package could be extended, such as satisfying progress.Reader with just a count, returning a progress.Reader from a slice or channel, creating a pretty terminal progress bar, or experimenting with passing return types through.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func Logger

func Logger(to func(format string, v ...any), prefix string, r Reader)

func NewReaderFromCount

func NewReaderFromCount(count func() (uint64, uint64)) countPoller

NewReaderFromCount returns an implementation of Reader from just a count callback. It will regularly call the count function to determine the latest progress count. Note that `count` must be safe to call at any time. It will be considered complete when the callback returns equal numbers.

Types

type LongRunningJob

type LongRunningJob struct {
	ReaderWrapper
	// contains filtered or unexported fields
}

func NewLongRunningJob

func NewLongRunningJob() LongRunningJob

NewLongRunningJob returns a basic task tracker. All methods are safe to call concurrently. It already uses Extend to provide utility methods.

func (LongRunningJob) AddWork

func (t LongRunningJob) AddWork(items uint64)

AddWork adds to the total work.

func (LongRunningJob) Complete

func (t LongRunningJob) Complete()

func (LongRunningJob) Count

func (t LongRunningJob) Count() (uint64, uint64)

Count returns the finished work and total work. Note that the task itself counts as 1 piece of work.

func (LongRunningJob) DoneChan

func (t LongRunningJob) DoneChan() (chan struct{}, bool)

func (LongRunningJob) FinishWork

func (t LongRunningJob) FinishWork(items uint64)

FinishWork progresses the job. When the amount of finished work equals or exceed the total work, the job is marked as completed.

type Reader

type Reader interface {
	// DoneChan returns a channel that will be closed upon completion.
	// The boolean return specifies whether the channel is already closed.
	DoneChan() (chan struct{}, bool)

	// Count returns the amount of items processed and the total amount.
	// The amount of items is guaranteed to be less than or equal to the total.
	// The total amount is guaranteed to be at least 1.
	// If they are equal, it is guaranteed that InProgress will return false.
	// Both values may increase at any time and are guaranteed never to decrease.
	// Count must be safe to be called concurrently.
	Count() (uint64, uint64)
}

Reader is an interface that all progress trackers should satisfy. This allows for other libraries to work with progress trackers generally, and for library developers to create compatible progress trackers.

type ReaderWrapper

type ReaderWrapper struct {
	Reader
	// contains filtered or unexported fields
}

func Extend

func Extend(t Reader) ReaderWrapper

Extend adds some nice utility methods to a Reader. Reader implementations can just embed this.

func (ReaderWrapper) InProgress

func (s ReaderWrapper) InProgress() bool

InProgress will return false when the tracker is complete. It is debounced to try and return false for 200ms. After 200ms it will finally return true.

func (ReaderWrapper) PerSecond

func (s ReaderWrapper) PerSecond() float64

PerSecond returns the throughput since this tracker began.

func (ReaderWrapper) Percentage

func (s ReaderWrapper) Percentage() float64

Percentage returns the current progress as a percentage between 0 and 1.

func (ReaderWrapper) Remaining

func (s ReaderWrapper) Remaining() time.Duration

Remaining estimates the time remaining until completion.

type WaitGroup

type WaitGroup struct {
	LongRunningJob
	// contains filtered or unexported fields
}

WaitGroup is a dropin replacement for sync.WaitGroup that provides progress tracking.

func (*WaitGroup) Add

func (wg *WaitGroup) Add(delta int)

func (*WaitGroup) Done

func (wg *WaitGroup) Done()

func (*WaitGroup) Wait

func (wg *WaitGroup) Wait()

Jump to

Keyboard shortcuts

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