MissingH-1.0.0: Large utility librarySource codeContentsIndex
Data.Progress.Tracker
Portabilityportable
Stabilityprovisional
MaintainerJohn Goerzen <jgoerzen@complete.org>
Contents
Introduction
Updating
Reading and Processing
Types
Utilities
Description

Tools for tracking the status of a long operation.

Written by John Goerzen, jgoerzen@complete.org

See also Data.Progress.Meter

Synopsis
newProgress :: String -> Integer -> IO Progress
newProgress' :: ProgressStatus -> [ProgressCallback] -> IO Progress
addCallback :: Progress -> ProgressCallback -> IO ()
addParent :: Progress -> Progress -> IO ()
incrP :: Progress -> Integer -> IO ()
incrP' :: Progress -> Integer -> IO ()
setP :: Progress -> Integer -> IO ()
setP' :: Progress -> Integer -> IO ()
incrTotal :: Progress -> Integer -> IO ()
setTotal :: Progress -> Integer -> IO ()
finishP :: Progress -> IO ()
getSpeed :: (ProgressStatuses a (IO b), Fractional b) => a -> IO b
getETR :: (ProgressStatuses a (IO Integer), ProgressStatuses a (IO Rational)) => a -> IO Integer
getETA :: (ProgressStatuses a (IO Integer), ProgressStatuses a (IO Rational)) => a -> IO Integer
data ProgressStatus = ProgressStatus {
completedUnits :: Integer
totalUnits :: Integer
startTime :: Integer
trackerName :: String
timeSource :: ProgressTimeSource
}
data Progress
type ProgressTimeSource = IO Integer
type ProgressCallback = ProgressStatus -> ProgressStatus -> IO ()
class ProgressStatuses a b where
withStatus :: a -> (ProgressStatus -> b) -> b
defaultTimeSource :: ProgressTimeSource
Introduction

ProgressTracker is a module for tracking the progress on long-running operations. It can be thought of as the back end engine behind a status bar. ProgressTracker can do things such as track how far along a task is, provide an estimated time of completion, estimated time remaining, current speed, etc. It is designed to be as generic as possible; it can even base its speed calculations on something other than the system clock.

ProgressTracker also supports a notion of a parent tracker. This is used when a large task is composed of several individual tasks which may also be long-running. Downloading many large files over the Internet is a common example of this.

Any given ProgressTracker can be told about one or more parent trackers. When the child tracker's status is updated, the parent tracker's status is also updated in the same manner. Therefore, the progress on each individual component, as well as the overall progress, can all be kept in sync automatically.

Finally, you can register callbacks. Callbacks are functions that are called whenever the status of a tracker changes. They'll be passed the old and new status and are intended to do things like update on-screen status displays.

The cousin module Data.Progress.Meter can be used to nicely render these trackers on a console.

newProgressSource
:: StringName of this tracker
-> IntegerTotal units expected
-> IO Progress

Create a new Progress object with the given name and number of total units initialized as given. The start time will be initialized with the current time at the present moment according to the system clock. The units completed will be set to 0, the time source will be set to the system clock, and the parents and callbacks will be empty.

If you need more control, see 'newProgress\''.

Example:

 prog <- newProgress "mytracker" 1024
newProgress' :: ProgressStatus -> [ProgressCallback] -> IO ProgressSource
Create a new Progress object initialized with the given status and callbacks. No adjustment to the startTime will be made. If you want to use the system clock, you can initialize startTime with the return value of defaultTimeSource and also pass defaultTimeSource as the timing source.
addCallback :: Progress -> ProgressCallback -> IO ()Source

Adds an new callback to an existing Progress. The callback will be called whenever the object's status is updated, except by the call to finishP.

Please note that the Progress object will be locked while the callback is running, so the callback will not be able to make any modifications to it.

addParentSource
:: ProgressThe child object
-> ProgressThe parent to add to this child
-> IO ()
Adds a new parent to an existing Progress. The parent will automatically have its completed and total counters incremented by the value of those counters in the existing Progress.
Updating
incrP :: Progress -> Integer -> IO ()Source

Increment the completed unit count in the Progress object by the amount given. If the value as given exceeds the total, then the total will also be raised to match this value so that the completed count never exceeds the total.

You can decrease the completed unit count by supplying a negative number here.

incrP' :: Progress -> Integer -> IO ()Source
Like incrP, but never modify the total.
setP :: Progress -> Integer -> IO ()Source
Set the completed unit count in the Progress object to the specified value. Unlike incrP, this function sets the count to a specific value, rather than adding to the existing value. If this value exceeds the total, then the total will also be raised to match this value so that the completed count never exceeds teh total.
setP' :: Progress -> Integer -> IO ()Source
Like setP, but never modify the total.
incrTotal :: Progress -> Integer -> IO ()Source
Increment the total unit count in the Progress object by the amount given. This would rarely be needed, but could be needed in some special cases when the total number of units is not known in advance.
setTotal :: Progress -> Integer -> IO ()Source
Set the total unit count in the Progress object to the specified value. Like incrTotal, this would rarely be needed.
finishP :: Progress -> IO ()Source

Call this when you are finished with the object. It is especially important to do this when parent objects are involved.

This will simply set the totalUnits to the current completedUnits count, but will not call the callbacks. It will additionally propogate any adjustment in totalUnits to the parents, whose callbacks will be called.

This ensures that the total expected counts on the parent are always correct. Without doing this, if, say, a transfer ended earlier than expected, ETA values on the parent would be off since it would be expecting more data than actually arrived.

Reading and Processing
getSpeed :: (ProgressStatuses a (IO b), Fractional b) => a -> IO bSource

Returns the speed in units processed per time unit. (If you are using the default time source, this would be units processed per second). This obtains the current speed solely from analyzing the Progress object.

If no time has elapsed yet, returns 0.

You can use this against either a Progress object or a ProgressStatus object. This is in the IO monad because the speed is based on the current time.

Example:

 getSpeed progressobj >>= print

Don't let the type of this function confuse you. It is a fancy way of saying that it can take either a Progress or a ProgressStatus object, and returns a number that is valid as any Fractional type, such as a Double, Float, or Rational.

getETR :: (ProgressStatuses a (IO Integer), ProgressStatuses a (IO Rational)) => a -> IO IntegerSource

Returns the estimated time remaining, in standard time units.

Returns 0 whenever getSpeed would return 0.

See the comments under getSpeed for information about this function's type and result.

getETA :: (ProgressStatuses a (IO Integer), ProgressStatuses a (IO Rational)) => a -> IO IntegerSource

Returns the estimated system clock time of completion, in standard time units. Returns the current time whenever getETR would return 0.

See the comments under getSpeed for information about this function's type and result.

Types
data ProgressStatus Source
The main progress status record.
Constructors
ProgressStatus
completedUnits :: Integer
totalUnits :: Integer
startTime :: Integer
trackerName :: StringAn identifying string
timeSource :: ProgressTimeSource
show/hide Instances
data Progress Source
The main Progress object.
show/hide Instances
ProgressRecords Progress (IO b)
ProgressStatuses Progress (IO b)
type ProgressTimeSource = IO IntegerSource
A function that, when called, yields the current time. The default is defaultTimeSource.
type ProgressCallback = ProgressStatus -> ProgressStatus -> IO ()Source

The type for a callback function for the progress tracker. When given at creation time to 'newProgress\'' or when added via addCallback, these functions get called every time the status of the tracker changes.

This function is passed two ProgressStatus records: the first reflects the status prior to the update, and the second reflects the status after the update.

Please note that the owning Progress object will be locked while the callback is running, so the callback will not be able to make changes to it.

class ProgressStatuses a b whereSource
Methods
withStatus :: a -> (ProgressStatus -> b) -> bSource
Lets you examine the ProgressStatus that is contained within a Progress object. You can simply pass a Progress object and a function to withStatus, and withStatus will lock the Progress object (blocking any modifications while you are reading it), then pass the object to your function. If you happen to already have a ProgressStatus object, withStatus will also accept it and simply pass it unmodified to the function.
show/hide Instances
Utilities
defaultTimeSource :: ProgressTimeSourceSource

The default time source for the system. This is defined as:

getClockTime >>= (return . clockTimeToEpoch)
Produced by Haddock version 2.6.0