package octez-smart-rollup-node-lib
Small wrapper around the Progress
library to easily create progress bars for use in the rollup node.
include module type of Progress
Preliminaries
Some basic types used throughout the rest of the library:
module Color = Terminal_ansi.Color
module Duration : sig ... end
module Printer : sig ... end
module Units : sig ... end
Pretty-printing utilities for common units used in progress bars.
Description
Describing a progress line is done via the Line
DSL. Individual lines can be stacked vertically via Multi
.
module Line : sig ... end
module Multi : sig ... end
Pre-provided lines
val counter :
?style:[ `ASCII | `UTF8 | `Custom of Line.Bar_style.t ] ->
?message:string ->
?pp:int64 Printer.t ->
int64 ->
int64 Line.t
counter total
is a progress bar of the form:
<message?> <count?> MM:SS [########..............................] XX%
where each reported value contributes cumulatively towards an eventual total of total
. ?style
specifies the Bar_style.t
to use for rendering the bar, and ?pp
is used to pretty-print the <count>
segment, if passed. (For example, Units.Bytes.of_int64
can be used for totals measured in bytes.)
Rendering
Once you have a description of the progress bar to be rendered (either a Line.t
or a Multi.t
), begin rendering it by using with_reporter
or with_reporters
respectively.
A reporter for values of type 'a
. In this library, each progress line has its own reporting function.
module Config : sig ... end
Configuration for progress bar rendering.
with_reporters bars f
begins rendering bars
and passes the corresponding reporting functions to f
. Once f
returns, the display is finalised.
Examples
- Reading a file into memory and displaying a single progress bar:
let read_file path buffer =
let total = file_size path and in_channel = open_in path in
try
with_reporter (counter ~total ()) @@ fun report ->
let rec aux offset =
let bytes_read = really_read buffer offset in
report bytes_read;
aux (offset + bytes_read)
in
aux 0
with End_of_file -> close_in in_channel
- Sending data to multiple clients, with one progress bar each:
let multi_bar_rendering () =
with_reporters
Multi.(line bar_a ++ line bar_b ++ line bar_c)
(fun report_a report_b report_c ->
for i = 1 to 1000 do
report_a (transfer_bytes client_a);
report_b (transfer_bytes client_b);
report_c (transfer_bytes client_c)
done)
Logging during rendering
interject_with f
executes the function f
while temporarily suspending the rendering of any active progress bar display. This can be useful when printing to stdout
/ stderr
, to avoid any interference from the rendering of progress bars. If using the Logs
library, consider using reporter
and instrument_reporter
instead.
Note: the caller must ensure that the terminal cursor is left in an appropriate position to resume rendering. In practice, this means that any printing to the terminal should be terminated with a newline character and flushed.
Extensions to the Logs
library designed to cooperate with progress bar rendering:
val logs_reporter :
?pp_header:(Logs.level * string option) Fmt.t ->
?app:Format.formatter ->
?dst:Format.formatter ->
unit ->
Logs.reporter
reporter
is like Logs_fmt.reporter
but produces a reporter that suspends any ongoing progress bar rendering while displaying log entries, ensuring that log entries in the terminal are never overwritten by the renderer.
val instrument_logs_reporter : Logs.reporter -> Logs.reporter
instrument_reporter r
wraps the synchronous reporter r
to ensure that any progress bar rendering is suspended while messages are being constructed for r
.
Note: to ensure that log entries are not overwritten by the Progress
renderer, r
must flush any log entries to the terminal synchronously: as soon as they are reported. This is true of the Logs
reporters built by Logs.format_reporter
and reporter
. An asynchronous reporter should use interject_with
to delimit its flushing action instead.
Manual lifecycle management
Functions for explicitly starting and stopping the process of rendering a bar; useful when the code doing the progress reporting cannot be conveniently delimited inside with_reporter
. All Display
s must be properly finalised, and it is not possible to interleave rendering of displays.
module Reporter : sig ... end
module Display : sig ... end
Simple wrappers for progress bars
val progress_bar :
message:string ->
counter:[ `Bytes | `Int ] ->
?color:Terminal.Color.t ->
int ->
int line
progress_bar ~message ~counter ~color total
creates a progress bar with a message
of the specified color
to count until total
. If counter is `Bytes
, the progress bar represents bytes amounts and if `Int
, it counts integer units.
val spinner : message:string -> 'a line
spinner ~message
creates a spinner that can be used to indicate progress for an unknown quantity.
val with_reporter : 'a line -> (('a -> unit) -> 'b) -> 'b
Same as Progress.with_reporter
but for non tty outputs, only displays the message without animation.
Lwt compatible progress bars
module Lwt : sig ... end