Skip to content
This repository has been archived by the owner on Apr 26, 2024. It is now read-only.

Allow modules to run only on specific worker(s) #10701

Closed
anoadragon453 opened this issue Aug 26, 2021 · 4 comments · Fixed by #11868
Closed

Allow modules to run only on specific worker(s) #10701

anoadragon453 opened this issue Aug 26, 2021 · 4 comments · Fixed by #11868
Labels
T-Enhancement New features, changes in functionality, improvements in performance, or user-facing enhancements.

Comments

@anoadragon453
Copy link
Member

There are some usecases for wanting a Synapse module to execute functionality once when it is running on a specific worker. Usecases include:

  • A module that auto-accepts invites for certain users. Accepting the invite should only be done by a single instance of the module - not all of them at once.
  • A module that wishes to send presence to other modules. This should only be done by one instance of a module (to avoid sending duplicate presence), and should only be done on workers that support sending federation traffic.

To achieve this, it is sometimes suggested to add worker-specific config for a module, in order to tell a module running on one worker to carry out a task, but to not do the same for the module config on other workers.

This method is fragile though - not least because you may wish to share module config between all worker instances, and having to have separate config per-worker is overhead to manage. Additionally, because homeserver config keys are overwritten when specifying multiple homeserver config files (as is commonly done with workers), you can't really configure a worker in one way on the main process, and in a subtly different way on the worker. The worker's config will need to be entirely duplicated.

As a proposed solution, we simply make the worker's name (None if the main process) available to modules. That way, we could simply state in the module's config that certain functionality should only run if the name of the worker that the module is running on matches against some configured value(s).

@anoadragon453 anoadragon453 added the T-Enhancement New features, changes in functionality, improvements in performance, or user-facing enhancements. label Aug 26, 2021
@dklimpel
Copy link
Contributor

dklimpel commented Jan 27, 2022

There is a workaround for disable modules in workers, you can set workers configuration:

modules: []

This disables the modules on workers. But it only helps if you disable modules on all workers and run the module on main process.

@babolivier
Copy link
Contributor

babolivier commented Jan 27, 2022

As a proposed solution, we simply make the worker's name (None if the main process) available to modules.

For some reason I was sure this was already something we do, but apparently it isn't. So I think this is the right solution.

That way, we could simply state in the module's config that certain functionality should only run if the name of the worker that the module is running on matches against some configured value(s).

To clarify, the module would be the one responsible for figuring out whether something can run based on the worker name, right? This sentence can be read in a way that implies we add some sort of special-cased config key to module configs to have Synapse automatically run the module on a specific worker.

@anoadragon453
Copy link
Member Author

To clarify, the module would be the one responsible for figuring out whether something can run based on the worker name, right? This sentence can be read in a way that implies we add some sort of special-cased config key to module configs to have Synapse automatically run the module on a specific worker.

What I'm thinking is that you would have a supported field in your worker config that's something along the lines of:

config:
    do_flarb_if_worker_name: flarb_runner

And then in your module code, have a condition similar to:

 def flarb():
    if self.module_api.worker_name != self.config.do_flarb_if_worker_name:
        # No flarb today
        return

@babolivier
Copy link
Contributor

To clarify, the module would be the one responsible for figuring out whether something can run based on the worker name, right? This sentence can be read in a way that implies we add some sort of special-cased config key to module configs to have Synapse automatically run the module on a specific worker.

What I'm thinking is that you would have a supported field in your worker config that's something along the lines of:

config:
    do_flarb_if_worker_name: flarb_runner

And then in your module code, have a condition similar to:

 def flarb():
    if self.module_api.worker_name != self.config.do_flarb_if_worker_name:
        # No flarb today
        return

Right, that's also what I had in mind, thanks.

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
T-Enhancement New features, changes in functionality, improvements in performance, or user-facing enhancements.
Projects
None yet
3 participants