Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Pre restart probe fixup #25243

Open
wants to merge 3 commits into
base: dev
Choose a base branch
from

Conversation

bashtanov
Copy link
Contributor

Following post-merge comment from @dotnwat on #24928

Backports Required

  • none - not a bug fix
  • none - this is a backport
  • none - issue does not exist in previous branches
  • none - papercut/not impactful enough to backport
  • v24.3.x
  • v24.2.x
  • v24.1.x

Release Notes

  • none

Pre-restart probe is a lengthy operation with scheduling points, report
cache refresh may change the data it iterates over. Use lw_shared_ptr to
hold 2 copies if pre-restart probe calculation and refresh work
concurrently.
@vbotbuildovich
Copy link
Collaborator

CI test results

test results on build#62600
test_id test_kind job_url test_status passed
rptest.tests.datalake.cluster_restore_test.DatalakeClusterRestoreTest.test_slow_tiered_storage_dlq.cloud_storage_type=CloudStorageType.S3.catalog_type=CatalogType.REST_HADOOP ducktape https://buildkite.com/redpanda/redpanda/builds/62600#01956202-54e8-4a1a-ade7-f33bb276410f FLAKY 1/3
rptest.tests.multi_restarts_with_archival_test.MultiRestartTest.test_recovery_after_multiple_restarts.cloud_storage_type=CloudStorageType.ABS ducktape https://buildkite.com/redpanda/redpanda/builds/62600#01956202-54e9-4b77-91af-87de5d095068 FLAKY 1/2
rptest.tests.timequery_test.TimeQueryTest.test_timequery_below_start_offset.spillover=False ducktape https://buildkite.com/redpanda/redpanda/builds/62600#019561ff-9685-4519-b998-4188089f5822 FLAKY 1/2
storage_e2e_single_thread_rpunit.storage_e2e_single_thread_rpunit unit https://buildkite.com/redpanda/redpanda/builds/62600#019561a4-0e7a-43e1-969e-7fbf1fbfa055 FLAKY 1/2

Copy link
Contributor

@bharathv bharathv left a comment

Choose a reason for hiding this comment

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

lgtm, there are a ton loops in health_monitor_backend, would be great to get another pair of 👀 incase I missed something.

absl::erase_if(_status, not_in_members_table);

_reports = new_reports;
Copy link
Contributor

Choose a reason for hiding this comment

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

nit: _reports = std::move(new_reports);

// local report
auto local_report_it = std::as_const(_reports).find(_self);
if (local_report_it == _reports.cend()) {
auto local_report_it = reports->find(_self);
Copy link
Member

Choose a reason for hiding this comment

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

It's not clear to me how using a shared pointer solves the concurrency problem. It looks like the we're still iterating over this structure with (presumably) shared access where iterators e.g. are held across scheduling points?

Copy link
Contributor

Choose a reason for hiding this comment

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

(my understanding)

all the loops with scheduling points operate on the (shared_ptr) copy of the report. The only modification to _report is in collect_cluster_health() which makes a new shared_ptr (report) and eventually moves it into _report while the original loop iteration can safely operate on a copy until it is alive.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yes, we only change data stored under _reports in collect_cluster_health where we construct a new object and replace the shared pointer to it. At this point the old object ceases to be referred by _reports. If it is being iterated over in walk_local_and_remote_reports it is kept alive by reports shared pointer (or multiple copies thereof if there are multiple iterations in flight), otherwise it gets destructed immediately. When all iterations are over it eventually gets destructed.

Copy link
Member

Choose a reason for hiding this comment

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

so if we are making a copy for local concurrent-free iteration, what's the point of the shared pointer?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

We never make a copy of the data explicitly, we only copy a shared pointer thus creating one more handle to the same dataset.

Also reports collection is never modified, we should change _reports type to lw_shard_ptr<const report_cache_t> (I will do this). The collection is only replaced as a whole. When it is replaced, this function still holds a shared pointer to the old version thus keeping it from being destroyed.

Does it shed any light?

Copy link
Member

Choose a reason for hiding this comment

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

I think it's a bit clearer now, thanks. If ya'll think it's safe then I'm good. It's pretty hard to analyze this stuff as a reviewer without seeing the big picture.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I actually tried to make it const and found a place where it is mutated! Thanks for the heads up.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants