Skip to content

Add utask waiting time metric - #5545

Open
brun0-matheus wants to merge 4 commits into
masterfrom
bruno.add-utask-waiting-time-metric
Open

brun0-matheus wants to merge 4 commits into
masterfrom
bruno.add-utask-waiting-time-metric

Conversation

@brun0-matheus

@brun0-matheus brun0-matheus commented Oct 19, 2026 •

Copy link
Copy Markdown
Contributor

Bug: b/573118558

Overview

Creates a new metric called UTASK_SUBTASK_WAIT_DURATION_SECS, which keeps track of time spent between one subtask finishing and the next one starting. This PR only implements it for the main subtask (so it tracks time between preprocess and main).

Changes

  • Add the metric UTASK_SUBTASK_WAIT_DURATION_SECS and instrument the code to emit it in the main subtask.
  • Add preprocess_end_time to uworker_msg.Input protobuf.
  • Split serialize_and_upload_uworker_input in two parts, moving all URLs generation/signing to prepare_uworker_io_urls in order to precisely track the time preprocess finishes.
  • Change unit tests related to serialize_and_upload_uworker_input: now they actually test the underlying behavior of the function instead of how its code is written.
  • Add the time_ns method to helpers.MockTime.

Tests

Add additional checks in UworkerMainTest and TworkerPreprocessTest to check if preprocess_end_time is set correctly and if UTASK_SUBTASK_WAIT_DURATION_SECS is emitted.

I deployed in the dev environment and it's working as intended. Evidence in the bug comments.

Define the metric in `monitoring_metrics.py` and instrument the code to
emmit it.
Improve unittests that used serialize_and_upload_uworker_input, now they
actually test the behaviour and not how the code is written.

Add some tests to check for preprocess_end_time being set and for the
metric emmission.
@brun0-matheus brun0-matheus self-assigned this Oct 19, 2026
@brun0-matheus
brun0-matheus requested a review from a team as a code owner October 19, 2026 12:22
if self._previous_subtask_end_time_ns is not None:
wait_duration_secs = max(
0, (self.start_time_ns - self._previous_subtask_end_time_ns) / 10**9)
monitoring_metrics.UTASK_SUBTASK_WAIT_DURATION_SECS.add(

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What was the rationale for choosing UTASK_SUB_TASK_WAIT_DURATION as the name? I am not sure if the metric's purpose is easily understood from this name. I would go with something more explicit.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is the best name I thought of. If I choose to be more explicit the metric name will become giant, but I'm open to suggestions.

Comment on lines +381 to +382
uworker_input.preprocess_start_time,
previous_subtask_end_time=uworker_input.preprocess_end_time)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since we have preprocess_start_time and preprocess_end_time, why create the new previous_subtask_end_time field? Is this because for other subtasks we do not have analogous fields?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

preprocess_start_time and preprocess_end_time are defined in the proto, and previous_subtask_end_time is a parameter of the method set_task_details, so it isn't a "new field".

Comment thread src/clusterfuzz/_internal/bot/tasks/utasks/uworker_io.py

if self._previous_subtask_end_time_ns is not None:
wait_duration_secs = max(
0, (self.start_time_ns - self._previous_subtask_end_time_ns) / 10**9)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why emitting this on exit?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Because other metrics are emitted there as well.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also, I see no problem in emitting on exit.


if previous_subtask_end_time is not None:
end_time = previous_subtask_end_time.ToNanoseconds()
if end_time > 0:

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can it be less or equal zero?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It can't be negative, but it can be zero if previous_subtask_end_time is not set. It's more of a safety precaution in case you parse an old protobuf that didn't have this field set.

Comment thread src/clusterfuzz/_internal/bot/tasks/utasks/uworker_io.py
import time
import unittest
from unittest import mock
import zlib

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: Jetski suggested adding tests for:

  • The no-I/O path: tworker_preprocess_no_io sets the timestamp and uworker_main_no_io records it.
  • Backward compatibility: an input without preprocess_end_time should record nothing.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants