Skip to content

Conversation

jayavenkatesh19
Copy link

Closes #9106

  • Tests added / passed
  • Passes pre-commit run --all-files

Adds a client side function to check if a plugin is registered on either the scheduler, worker or nanny registries. The plugin names seem to be unique enough to ignore the edge case where two different plugin types such as a WorkerPlugin and a SchedulerPlugin have the same name. The scheduler has separate functions added for this use case but will need to add extra client functions to separate the has_plugin function into has_worker_plugin etc.

Apart from checking if a plugin is registered by passing its name, also added the functionality of passing the plugin object itself with name extraction handled by the function. This is especially useful while using built-in plugins for users who do not know about the plugin.name attribute. Also added an error check for plugins whose name is not set.

CC: @jacobtomlinson

@jayavenkatesh19 jayavenkatesh19 changed the title Plugin registration status Check plugin registration status Sep 24, 2025
Copy link
Contributor

github-actions bot commented Sep 24, 2025

Unit Test Results

See test report for an extended history of previous test failures. This is useful for diagnosing flaky tests.

    27 files  ±  0      27 suites  ±0   9h 53m 26s ⏱️ + 16m 50s
 4 126 tests + 15   4 018 ✅ + 16    104 💤 ±0  4 ❌ ±0 
51 698 runs  +194  49 510 ✅ +195  2 184 💤 ±0  4 ❌ ±0 

For more details on these failures, see this check.

Results for commit e5cf633. ± Comparison against base commit 8e604a0.

♻️ This comment has been updated with latest results.

Copy link
Member

@jacobtomlinson jacobtomlinson left a comment

Choose a reason for hiding this comment

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

Overall this looks good to me!

If you have a look in distributed/distributed/diagnostics/tests/ you'll find test_scheduler_plugin.py, test_worker_plugin.py and test_nanny_plugin.py. Could you go through those and add/update some tests that exercise the new code here?

Copy link
Member

@TomAugspurger TomAugspurger left a comment

Choose a reason for hiding this comment

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

Looks good.

I wonder if it'd be more useful to have separate methods has_worker_plugin, has_scheduler_plugin, has_nanny_plugin. Are people interested whether some plugin is somewhere on the cluster? Or whether it's specifically on the scheduler or specifically on the worker?

In my experience, you typically don't have plugins of different types with the same name, so perhaps it's not worth worrying about.

Comment on lines +5492 to +5494
elif isinstance(plugin, (WorkerPlugin, SchedulerPlugin, NannyPlugin)):
plugin_name = getattr(plugin, "name", None)
if plugin_name is None:
Copy link
Member

Choose a reason for hiding this comment

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

Possible simplification: if we detect a single plugin here, we can assign it to

plugin = [plugin]

and then fall through to the list case.

Copy link
Member

Choose a reason for hiding this comment

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

Ah, I see that the return type is different in that case (bool vs. dict[str, bool]). We could add a local unbox variable to handle this, but perhaps not worth it.

)
return result[plugin_name]

elif isinstance(plugin, list):
Copy link
Member

Choose a reason for hiding this comment

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

Maybe Sequence here (and in the type signature)?

f"Plugin {funcname(type(p))} has no 'name' attribute"
)
names_to_check.append(plugin_name)
return self.sync(self._get_plugin_registration_status, names=names_to_check)
Copy link
Member

Choose a reason for hiding this comment

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

We should have an else case that raises rather than silently returning None.

Signed-off-by: Jaya Venkatesh <[email protected]>
Copy link
Member

@jacobtomlinson jacobtomlinson left a comment

Choose a reason for hiding this comment

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

Thanks for adding the tests. There's a bit of an AI code smell in here that I want to dig a little into. Totally fine with using AI assistants, but things might need a little more cleaning up before we can merge it.

There is a lot of duplication, but there are also lots of tests that exist already that check registration, has plugin and unregistration. The check for "has plugin" in the existing tests involves poking the objects directly, it feels like a great opportunity to exercise this new method instead. It would also mean we could remove a bunch of these new tests in favour of small tweaks to existing ones.

Comment on lines +226 to +233
class DuckPlugin(NannyPlugin):
name = "duck-plugin"

def setup(self, nanny):
nanny.foo = 123

def teardown(self, nanny):
pass
Copy link
Member

Choose a reason for hiding this comment

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

This gets redefined quite a few times in here, can we move it outside the test and define it once to DRY this out a little?

async def test_has_nanny_plugin_list_check(c, s, a):
"""Test checking multiple nanny plugins at once"""

class IdempotentPlugin(NannyPlugin):
Copy link
Member

Choose a reason for hiding this comment

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

I'm curious about the naming here. Why Idempotent and NonIdempotent?

self.expected_notifications = expected_notifications

# Check non-existent plugin
assert not await c.has_plugin("MyPlugin") # ← await
Copy link
Member

Choose a reason for hiding this comment

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

What's with these comments?

Suggested change
assert not await c.has_plugin("MyPlugin") # ← await
assert not await c.has_plugin("MyPlugin")

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.

check if a Plugin is present

3 participants