Skip to main content

module util::Monitor

rascal-0.40.16

Monitor the progress of a task/job.

Usage

import util::Monitor;

Dependencies

import util::Math;
import IO;

function jobStart

Log the start of a job.

void jobStart(str label, int work=1, int totalWork=100)

Job Start registers a new current job on the job stack with an amount of steps todo and how much work it contributes (when it ends) to its parent job (if any).

  • The label identifies as running task, which could be presented in the UI with a specific progress bar (for example)
  • Using Job Step with the same label, you can advance the amount of work done for the task.
  • All tasks should eventually end with Job End, but most UI's will clean up open left-over tasks at natural intervals as well.
  • Use Job Todo to register additional dynamically discovered work for a task. The totalWork constant for that specific task will be increased by the given amount.

Benefits

  • It is adviced to use the "block" functions job instead of the raw jobStart, jobStep and jobEnd functions because these guarantee each started task is always ended, with and without exceptions. This improves the user experience for your users. Also these functions help by providing the job label in the scope of the task, such that this "magic constant" does not need to be repeated.

Pitfalls

  • The job label is both an identity and a user facing string constant. Future versions of the API may split the identify from the label for better accuracy and better UI.

function jobStep

Log to the user that a certain event has happened under the currently registered Job.

void jobStep(str label, str message, int work = 1)

function jobEnd

Log the end of a job.

int jobEnd(str label, bool success=true)

function jobTodo

Register additional work for the identied job.

void jobTodo(str label, int work=1)

function jobIsCancelled

Poll if the given job has been cancelled by a user interaction.

void jobIsCancelled(str label)

function jobWarning

Register a warning in the same UI that job progress is shown in.

void jobWarning(str message, loc src)

function job

A job block guarantees a start and end, and provides easy access to the stepper interface.

&T job(str label, &T (void (str message, int worked) step) block, int totalWork=100)

The convenience function that is passed to the block can be used inside the block to register steps with a parameterized workload and the same label as the job name.

Benefits

  • the block body does not need to repeat the name parameter when ending the job or making steps
  • the job is always properly ended, even when exceptions are thrown

Pitfalls

  • additional work with Job Todo is still possible, but you have to repeat the right job label.

function job

A job block guarantees a start and end, and provides easy access to the stepper interface.

&T job(str label, &T (void (int worked) step) block, int totalWork=1)

The convenience function that is passed to the block can be used inside the block to register steps with a parameterized workload and the same label as the job name.

Benefits

  • the block body does not need to repeat the name parameter when ending the job or making steps
  • the job is always properly ended, even when exceptions are thrown

Pitfalls

  • additional work with Job Todo is still possible, but you have to repeat the right job label.

function job

A job block guarantees a start and end, and provides easy access to the stepper interface.

&T job(str label, &T (void () step) block, int totalWork=1)

The convenience function that is passed to the block can be used inside the block to register steps with workload 1 and the same label as the job name.

Benefits

  • the block body does not need to repeat the name parameter when ending the job or making steps
  • the job is always properly ended, even when exceptions are thrown

Pitfalls

  • additional work with Job Todo is still possible, but you have to repeat the right job label.

function job

A job block guarantees a start and end, and provides easy access to the stepper interface.

&T job(str label, &T () block, int totalWork=1)

Benefits

  • the block code does not need to remember to end the job with the same job name.
  • the job is always properly ended, even when exceptions are thrown

Tests

test horseRaceTest

Puts the monitor API to work by racing 5 horses against each other.


test bool horseRaceTest() {
distance = 3000000;
stride = 50;
horses = 5;
handicaps = [ arbInt(stride * 15 / 100) | _ <- [0..horses]];
labels = [ "Horse <h> (handicap is <handicaps[h]>)" | h <- [0..horses]];
progress = [ 0 | _ <- [0..horses]];

for (int h <- [0..horses])
jobStart(labels[h], totalWork=distance);

race:while (true)
for(int h <- [0..horses]) {
advance = arbInt(stride - handicaps[h]);
progress[h] += advance;

jobStep(labels[h], "Pacing horse <h> with <advance>...", work=advance);

if (progress[h] >= distance) {
break race;
}
}

for (int h <- [0..horses])
jobEnd(labels[h]);

return true;
}

test simpleAsyncPrintTest

test bool simpleAsyncPrintTest() {
jobStart("job", totalWork=3);
println("a");
jobStep("job", "step 1", work=1);
println("b");
jobStep("job", "step 2", work=1);
println("c");
jobStep("job", "step 3", work=1);
println("d");
jobEnd("job");
return true;
}

test unfinishedInputTest

test bool unfinishedInputTest() {
jobStart("job", totalWork=26);
for (/<l:[a-z]>/ := "abcdefghijklmnopqrstuwvxyz") {
print(l); // no newline!
jobStep("job", "letter <l>", work=1);
if (arbInt(10) == 0) {
println(); // break it
}
}
// println(); // flush it
jobEnd("job");
return true;
}

test unfinishedLinesAtTheEndTest

test bool unfinishedLinesAtTheEndTest() {
jobStart("job", totalWork=3);
print("ab\nc");
jobStep("job", "1.5", work=1);
print("d\ne");
jobStep("job", "2.5", work=1);
print("f\ngh\n");
jobStep("job", "3", work=1);
jobEnd("job");
return true;
}