|
7 | 7 | import getProjectQuery from '$queries/get_project';
|
8 | 8 | import getDryRunPhaseResultsQuery from '$queries/get_dry_run_phase_results';
|
9 | 9 | import getDryRunQuery from '$queries/get_selected_project';
|
| 10 | + import getCarbontrackerDataQuery from '$queries/get_carbontracker_metrics'; |
10 | 11 | import { requestGraphQLClient } from '$lib/graphqlUtils';
|
11 | 12 | import { goto } from '$app/navigation';
|
12 | 13 | import Plot from './plot.svelte';
|
|
23 | 24 | // import { displayAlert } from '$utils/alerts-utils';
|
24 | 25 | import type { DryRunMetrics, DryRun, MetricsWithTimeStamps } from '$typesdefinitions';
|
25 | 26 |
|
| 27 | + // Extended type to include carbontracker data |
| 28 | + interface ExtendedDryRunMetrics extends DryRunMetrics { |
| 29 | + carbontracker?: { |
| 30 | + fetchCarbontrackerData?: { |
| 31 | + co2eq: number; |
| 32 | + energy: number; |
| 33 | + }; |
| 34 | + }; |
| 35 | + } |
| 36 | +
|
26 | 37 | export let data;
|
27 | 38 |
|
28 | 39 | let loadingFinished = false;
|
|
49 | 60 | let allStepNames: string[] = [];
|
50 | 61 |
|
51 | 62 | $: selectedStep = 'Total';
|
52 |
| - $: reactiveStepsList = $stepsList; |
| 63 | + let reactiveStepsList: ExtendedDryRunMetrics[]; |
| 64 | + $: reactiveStepsList = ($stepsList as ExtendedDryRunMetrics[]) || []; |
53 | 65 |
|
54 | 66 | function gotoOverview(): void {
|
55 | 67 | selectedStep = 'Total';
|
|
72 | 84 | let networkTotalReceived = 'N/A';
|
73 | 85 | let networkTotalTransmitted = 'N/A';
|
74 | 86 | let pipelineDuration = 'N/A';
|
| 87 | + let totalCO2 = 'N/A'; |
| 88 | + let totalEnergy = 'N/A'; |
75 | 89 |
|
76 | 90 | function formatDuration(seconds: number): string {
|
77 | 91 | const hours = Math.floor(seconds / 3600);
|
|
107 | 121 | pipelineDuration = formatDuration(totalDuration);
|
108 | 122 | }
|
109 | 123 |
|
| 124 | + function computeTotalCarbonMetrics(): void { |
| 125 | + let co2Sum = 0; |
| 126 | + let energySum = 0; |
| 127 | +
|
| 128 | + if (reactiveStepsList) { |
| 129 | + reactiveStepsList.forEach((step) => { |
| 130 | + if (step.carbontracker?.fetchCarbontrackerData) { |
| 131 | + if (step.carbontracker.fetchCarbontrackerData.co2eq) { |
| 132 | + co2Sum += step.carbontracker.fetchCarbontrackerData.co2eq; |
| 133 | + } |
| 134 | + if (step.carbontracker.fetchCarbontrackerData.energy) { |
| 135 | + energySum += step.carbontracker.fetchCarbontrackerData.energy; |
| 136 | + } |
| 137 | + } |
| 138 | + }); |
| 139 | + } |
| 140 | +
|
| 141 | + totalCO2 = co2Sum > 0 ? co2Sum.toFixed(3) : 'N/A'; |
| 142 | + totalEnergy = energySum > 0 ? energySum.toFixed(6) : 'N/A'; |
| 143 | + } |
| 144 | +
|
| 145 | + // Reactive statement to compute carbon metrics when reactiveStepsList changes |
| 146 | + $: if (reactiveStepsList && reactiveStepsList.length > 0) { |
| 147 | + computeTotalCarbonMetrics(); |
| 148 | + } |
| 149 | +
|
110 | 150 | let dryRunPhaseMessage: string | null;
|
111 | 151 | // eslint-disable-next-line @typescript-eslint/explicit-function-return-type, consistent-return
|
112 |
| - const getMetricsResponse = async () => { |
| 152 | + const getMetricsResponse = async (): Promise<DryRunMetrics[]> => { |
113 | 153 | const dryrunVariables = {
|
114 | 154 | // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
|
115 | 155 | dryRunId: data.resource
|
|
124 | 164 | const body = `${(error as Error).message}`;
|
125 | 165 | // await displayAlert(title, body, 10_000);
|
126 | 166 | console.log(title, body);
|
| 167 | + return []; |
127 | 168 | }
|
128 | 169 | };
|
129 | 170 |
|
| 171 | + async function getCarbontrackerDataResponse(input: any): Promise< |
| 172 | + | { |
| 173 | + fetchCarbontrackerData?: { |
| 174 | + co2eq: number; |
| 175 | + energy: number; |
| 176 | + }; |
| 177 | + } |
| 178 | + | undefined |
| 179 | + > { |
| 180 | + const inputData = { |
| 181 | + input: { |
| 182 | + data: { |
| 183 | + dryRun: { |
| 184 | + node: { |
| 185 | + metrics: { |
| 186 | + cpuUsageSecondsTotal: input |
| 187 | + } |
| 188 | + } |
| 189 | + } |
| 190 | + } |
| 191 | + } |
| 192 | + }; |
| 193 | + console.log('inputData:', inputData); |
| 194 | + try { |
| 195 | + const response = await requestGraphQLClient(getCarbontrackerDataQuery, inputData); |
| 196 | + return response as { |
| 197 | + fetchCarbontrackerData?: { |
| 198 | + co2eq: number; |
| 199 | + energy: number; |
| 200 | + }; |
| 201 | + }; |
| 202 | + } catch (error) { |
| 203 | + const title = 'Internal error!'; |
| 204 | + const body = `${(error as Error).message}`; |
| 205 | + // await displayAlert(title, body, 10_000); |
| 206 | + console.log(title, body); |
| 207 | + return undefined; |
| 208 | + } |
| 209 | + } |
| 210 | +
|
130 | 211 | const getData = async (): Promise<{
|
131 | 212 | workflow: any;
|
132 | 213 | dryrun: any;
|
|
180 | 261 | cumulativeNetworkData = result.cumulativeNetworkData;
|
181 | 262 | currentNetworkData = result.currentNetworkData;
|
182 | 263 | logs = result.logs;
|
| 264 | + const carbontrackerData: Array<{ |
| 265 | + nodeId: string; |
| 266 | + stepName: string; |
| 267 | + carbonData: { fetchCarbontrackerData?: { co2eq: number; energy: number } } | undefined; |
| 268 | + }> = []; |
| 269 | + for (const step of metricsResponse) { |
| 270 | + if (step.type === 'Pod') { |
| 271 | + const carbonResponse = await getCarbontrackerDataResponse( |
| 272 | + step.metrics.cpuUsageSecondsTotal |
| 273 | + ); |
| 274 | + carbontrackerData.push({ |
| 275 | + nodeId: step.id, |
| 276 | + stepName: step.displayName, |
| 277 | + carbonData: carbonResponse |
| 278 | + }); |
| 279 | + } |
| 280 | + } |
| 281 | +
|
| 282 | + // Merge carbontracker data with stepsList |
| 283 | + $stepsList = $stepsList.map((step) => { |
| 284 | + const carbonData = carbontrackerData.find((carbon) => carbon.nodeId === step.id); |
| 285 | + return { |
| 286 | + ...step, |
| 287 | + carbontracker: carbonData ? carbonData.carbonData : undefined |
| 288 | + }; |
| 289 | + }); |
| 290 | +
|
183 | 291 | const responses = {
|
184 | 292 | workflow: workflowResponse.project,
|
185 | 293 | dryrun: dryrunResponse,
|
186 | 294 | metrics: metricsResponse,
|
187 |
| - allstepnames: allStepNames |
| 295 | + allstepnames: allStepNames, |
| 296 | + selectedDryRunName: $selectedDryRunName, |
| 297 | + carbontrackerData |
188 | 298 | };
|
| 299 | +
|
| 300 | + console.log('responses:', responses); |
189 | 301 | return responses;
|
190 | 302 | };
|
191 | 303 |
|
|
496 | 608 | <th>Started</th>
|
497 | 609 | <th>Finished</th>
|
498 | 610 | <th>Duration</th>
|
| 611 | + <th>CO2 [<span class="lowercase">g</span>]</th> |
| 612 | + <th>Energy [<span class="lowercase">k</span>Wh]</th> |
499 | 613 | <th>Status</th>
|
500 | 614 | <th>Output</th>
|
501 | 615 | </tr>
|
|
505 | 619 | <!-- eslint-disable-next-line @typescript-eslint/explicit-function-return-type -->
|
506 | 620 | <tr on:click={() => stepOnClick(step.displayName)}>
|
507 | 621 | <td style="width:15%">{step.displayName}</td>
|
508 |
| - <td style="width:20%"> |
| 622 | + <td style="width:15%"> |
509 | 623 | {step.startedAt ?? '-'}
|
510 | 624 | </td>
|
511 |
| - <td style="width:20%"> |
| 625 | + <td style="width:15%"> |
512 | 626 | {step.finishedAt ?? '-'}
|
513 | 627 | </td>
|
514 |
| - <td style="width:15%">{displayStepDuration(step)}</td> |
515 |
| - <td style="width:15%">{step.phase}</td> |
| 628 | + <td style="width:10%">{displayStepDuration(step)}</td> |
| 629 | + <td style="width:10%"> |
| 630 | + {#if step.carbontracker?.fetchCarbontrackerData?.co2eq} |
| 631 | + {step.carbontracker.fetchCarbontrackerData.co2eq.toFixed(3)} |
| 632 | + {:else} |
| 633 | + - |
| 634 | + {/if} |
| 635 | + </td> |
| 636 | + <td style="width:10%"> |
| 637 | + {#if step.carbontracker?.fetchCarbontrackerData?.energy} |
| 638 | + {step.carbontracker.fetchCarbontrackerData.energy.toFixed(6)} |
| 639 | + {:else} |
| 640 | + - |
| 641 | + {/if} |
| 642 | + </td> |
| 643 | + <td style="width:10%">{step.phase}</td> |
516 | 644 | <td style="width:15%">
|
517 | 645 | {#if step.outputArtifacts?.length > 1}
|
518 | 646 | {#each step.outputArtifacts as artifact}
|
|
600 | 728 | <tr>
|
601 | 729 | <td>Duration</td>
|
602 | 730 | <td> {pipelineDuration} </td>
|
603 |
| - </tr></tbody |
604 |
| - > |
| 731 | + </tr> |
| 732 | + <tr> |
| 733 | + <td>Total CO2</td> |
| 734 | + <td> {totalCO2} g </td> |
| 735 | + </tr> |
| 736 | + <tr> |
| 737 | + <td>Total Energy</td> |
| 738 | + <td> {totalEnergy} kWh </td> |
| 739 | + </tr> |
| 740 | + </tbody> |
605 | 741 | </table>
|
606 | 742 | </div>
|
607 | 743 |
|
|
0 commit comments