Project#evaluate#
Scores alternative change sets against the solved baseline of a Project. The project isn't modified. Use it to compare options, such as which resource should take a task, before committing one with apply. Needs a solved project.
Signature#
candidates: Candidate, options?: EvaluateOptions: EvaluateResult
Synchronous. Runs on the calling thread, so a long run blocks the event loop.
Parameters#
| Name | Type | Description |
|---|---|---|
candidates |
Candidate[] |
The change sets to score |
options |
EvaluateOptions |
Optional. Baseline check, leveling stage, focus tasks and clearFirst. Default {} |
Candidate#
One alternative to score.
| Field | Type | Default | Description |
|---|---|---|---|
id |
Id |
required | Echoed in the matching CandidateResult. Uniqueness isn't checked |
changes |
SchedulingChanges |
required | The edits this alternative makes. A changes.baselineId is checked like options.baselineId |
EvaluateOptions#
Options for one evaluate call. Every field is optional.
| Field | Type | Default | Description |
|---|---|---|---|
baselineId |
string |
no check | Expected baseline token, taken from the latest result's baselineId. A mismatch throws ProjectError "stale-baseline" |
level |
LevelingOptions | false |
false |
Levels each candidate after scheduling it, with these options unchanged, and fills leveled in its result. null counts as false; true is invalid |
focus |
Id | Id[] |
none | Tasks to report finish and overload for, in the metrics' finish.tasks and overload.focus |
clearFirst |
boolean |
false |
Scores against a copy of the baseline with leveling_delay and pauses cleared on the tasks in scope: level.scope.tasks when given, otherwise every task. Independent of level.clearFirst |
focus takes one task id or an array of ids.
Behavior#
- The reference state is the accepted baseline as it is, or its cleared copy with
clearFirst.evaluatenever levels the reference state itself. - Each candidate runs on its own disposable copy of the reference state:
apply(changes), thensolve(null)and measure the scheduled stage, then, withlevel,level(options.level)and measure the leveled stage. No candidate sees another candidate's changes. - Both stages are compared against the same baseline metrics.
- A candidate whose changes are rejected, or whose solve or leveling fails on bad input, gets an
errorin its result and doesn't fail the call. - With
clearFirst, all checks run against the accepted state before anything is cleared, and the result'sbaselineIdis still the accepted baseline's token. - The result holds metrics only: no
updatesand no overallocation windows. To commit a candidate, pass itschangestoapplyand follow withsolve(null), or withlevelusing the same options.
For what the metrics measure and how to pick a winner, see Evaluating Alternatives.
Candidates are scored one after another.
Returns#
An EvaluateResult: a fresh object that shares nothing with the project. With dates: "date" on the project, the date fields of every finish are local Date objects.
EvaluateResult#
| Field | Type | Description |
|---|---|---|
baselineId |
string |
The accepted baseline the candidates were scored against |
baseline |
Metrics |
Metrics of the reference state itself. Every delta is 0 |
candidates |
CandidateResult[] |
One entry per candidate, in input order |
CandidateResult#
The score of one candidate. A rejected candidate has id and error only.
| Field | Type | Description |
|---|---|---|
id |
Id |
The candidate's id |
error |
RejectedOperation |
Present when the candidate failed: the first rejected operation, or the input error of its solve or leveling. No other field is present then |
scheduled |
Metrics |
Present unless error is set. Metrics after applying the changes and solving |
leveled |
LeveledMetrics |
Present only with options.level, and absent when the candidate has a cycle. Metrics after leveling |
cost |
number |
Present unless error is set. The cost of the last stage present: leveled when it exists, otherwise scheduled. Lower is better |
Errors#
| Error | When |
|---|---|
ProjectError "no-baseline" |
The project is unsolved, including after apply |
ProjectError "stale-baseline" |
options.baselineId or any candidate's changes.baselineId doesn't name the current baseline |
InputError |
An unknown task in focus (path focus[i]); options.level is invalid for the baseline, including level: true; an unknown option key or a malformed candidate; a non-finite number or an invalid Date in the input |
Error("Project has been disposed") |
The project was disposed |
A failure inside one candidate doesn't throw; it goes into that candidate's error.
Example#
Compare leaving the plan as it is with moving task b to an idle resource.
const = new;
const = ;
const = ;
// stay: cost 2
// dev2: cost 0
Related#
Project- the class and its other methodsMetrics- what each candidate is scored onLevelingOptions- theleveloption- Evaluating alternatives - candidates, metrics and committing the winner
- Run in a worker - keeping long runs off the UI thread