We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
Update Example Launcher Plugin mention restoring the singletons
The singletons should be restored when performing multi-process launching.
something 

```python
# In the launcher's launch:
state = Singleton.get_state()

# In the remote process
Singleton.set_state(state)
```

--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `plugins/examples/example_launcher_plugin/hydra_plugins/example_launcher_plugin/example_launcher.py`
Content:
```
1 # Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved
2 import logging
3 from pathlib import Path
4 from typing import Optional, Sequence
5 
6 from hydra.core.config_loader import ConfigLoader
7 from hydra.core.config_search_path import ConfigSearchPath
8 from hydra.core.hydra_config import HydraConfig
9 from hydra.core.utils import (
10     JobReturn,
11     configure_log,
12     filter_overrides,
13     run_job,
14     setup_globals,
15 )
16 from hydra.plugins.launcher import Launcher
17 from hydra.plugins.search_path_plugin import SearchPathPlugin
18 from hydra.types import TaskFunction
19 from omegaconf import DictConfig, open_dict
20 
21 # IMPORTANT:
22 # If your plugin imports any module that takes more than a fraction of a second to import,
23 # Import the module lazily (typically inside launch()).
24 # Installed plugins are imported during Hydra initialization and plugins that are slow to import plugins will slow
25 # the startup of ALL hydra applications.
26 # Another approach is to place heavy includes in a file prefixed by _, such as _core.py:
27 # Hydra will not look for plugin in such files and will not import them during plugin discovery.
28 
29 
30 log = logging.getLogger(__name__)
31 
32 
33 class ExampleLauncherSearchPathPlugin(SearchPathPlugin):
34     """
35     This plugin is allowing configuration files provided by the ExampleLauncher plugin to be discovered
36     and used once the ExampleLauncher plugin is installed
37     """
38 
39     def manipulate_search_path(self, search_path: ConfigSearchPath) -> None:
40         # Appends the search path for this plugin to the end of the search path
41         search_path.append(
42             "hydra-example-launcher", "pkg://hydra_plugins.example_launcher_plugin.conf"
43         )
44 
45 
46 class ExampleLauncher(Launcher):
47     def __init__(self, foo: str, bar: str) -> None:
48         self.config: Optional[DictConfig] = None
49         self.config_loader: Optional[ConfigLoader] = None
50         self.task_function: Optional[TaskFunction] = None
51 
52         # foo and var are coming from the the plugin's configuration
53         self.foo = foo
54         self.bar = bar
55 
56     def setup(
57         self,
58         config: DictConfig,
59         config_loader: ConfigLoader,
60         task_function: TaskFunction,
61     ) -> None:
62         self.config = config
63         self.config_loader = config_loader
64         self.task_function = task_function
65 
66     def launch(
67         self, job_overrides: Sequence[Sequence[str]], initial_job_idx: int
68     ) -> Sequence[JobReturn]:
69         """
70         :param job_overrides: a List of List<String>, where each inner list is the arguments for one job run.
71         :param initial_job_idx: Initial job idx in batch.
72         :return: an array of return values from run_job with indexes corresponding to the input list indexes.
73         """
74         setup_globals()
75         assert self.config is not None
76         assert self.config_loader is not None
77         assert self.task_function is not None
78 
79         configure_log(self.config.hydra.hydra_logging, self.config.hydra.verbose)
80         sweep_dir = Path(str(self.config.hydra.sweep.dir))
81         sweep_dir.mkdir(parents=True, exist_ok=True)
82         log.info(
83             f"Example Launcher(foo={self.foo}, bar={self.bar}) is launching {len(job_overrides)} jobs locally"
84         )
85         log.info(f"Sweep output dir : {sweep_dir}")
86         runs = []
87 
88         for idx, overrides in enumerate(job_overrides):
89             idx = initial_job_idx + idx
90             lst = " ".join(filter_overrides(overrides))
91             log.info(f"\t#{idx} : {lst}")
92             sweep_config = self.config_loader.load_sweep_config(
93                 self.config, list(overrides)
94             )
95             with open_dict(sweep_config):
96                 # This typically coming from the underlying scheduler (SLURM_JOB_ID for instance)
97                 # In that case, it will not be available here because we are still in the main process.
98                 # but instead should be populated remotely before calling the task_function.
99                 sweep_config.hydra.job.id = f"job_id_for_{idx}"
100                 sweep_config.hydra.job.num = idx
101             HydraConfig.instance().set_config(sweep_config)
102 
103             ret = run_job(
104                 config=sweep_config,
105                 task_function=self.task_function,
106                 job_dir_key="hydra.sweep.dir",
107                 job_subdir_key="hydra.sweep.subdir",
108             )
109             runs.append(ret)
110             # reconfigure the logging subsystem for Hydra as the run_job call configured it for the Job.
111             # This is needed for launchers that calls run_job in the same process and not spawn a new one.
112             configure_log(self.config.hydra.hydra_logging, self.config.hydra.verbose)
113         return runs
114
```
--- END FILES ---

Please first localize the bug based on the issue statement, and then generate a patch according to the `git diff` format fenced by three backticks.

Here is an example:

```diff
diff --git a/examples/server_async.py b/examples/server_async.py
--- a/examples/server_async.py
+++ b/examples/server_async.py
@@ -313,4 +313,4 @@
 
 
 if __name__ == "__main__":
-    asyncio.run(run_async_server("."), debug=True)
+    asyncio.run(run_async_server(), debug=True)
diff --git a/examples/server_sync.py b/examples/server_sync.py
--- a/examples/server_sync.py
+++ b/examples/server_sync.py
@@ -313,5 +313,5 @@
 
 
 if __name__ == "__main__":
-    server = run_sync_server(".")
+    server = run_sync_server()
     server.shutdown()

```

diff --git a/plugins/examples/example_launcher_plugin/hydra_plugins/example_launcher_plugin/example_launcher.py b/plugins/examples/example_launcher_plugin/hydra_plugins/example_launcher_plugin/example_launcher.py
--- a/plugins/examples/example_launcher_plugin/hydra_plugins/example_launcher_plugin/example_launcher.py
+++ b/plugins/examples/example_launcher_plugin/hydra_plugins/example_launcher_plugin/example_launcher.py
@@ -6,6 +6,7 @@
 from hydra.core.config_loader import ConfigLoader
 from hydra.core.config_search_path import ConfigSearchPath
 from hydra.core.hydra_config import HydraConfig
+from hydra.core.singleton import Singleton
 from hydra.core.utils import (
     JobReturn,
     configure_log,
@@ -100,6 +101,17 @@
                 sweep_config.hydra.job.num = idx
             HydraConfig.instance().set_config(sweep_config)
 
+            # If your launcher is executing code in a different process, it is important to restore
+            # the singleton state in the new process.
+            # To do this, you will likely need to serialize the singleton state along with the other
+            # parameters passed to the child process.
+
+            # happening on launcher process
+            state = Singleton.get_state()
+
+            # happening on the spawned process
+            Singleton.set_state(state)
+
             ret = run_job(
                 config=sweep_config,
                 task_function=self.task_function,

{"golden_diff": "diff --git a/plugins/examples/example_launcher_plugin/hydra_plugins/example_launcher_plugin/example_launcher.py b/plugins/examples/example_launcher_plugin/hydra_plugins/example_launcher_plugin/example_launcher.py\n--- a/plugins/examples/example_launcher_plugin/hydra_plugins/example_launcher_plugin/example_launcher.py\n+++ b/plugins/examples/example_launcher_plugin/hydra_plugins/example_launcher_plugin/example_launcher.py\n@@ -6,6 +6,7 @@\n from hydra.core.config_loader import ConfigLoader\n from hydra.core.config_search_path import ConfigSearchPath\n from hydra.core.hydra_config import HydraConfig\n+from hydra.core.singleton import Singleton\n from hydra.core.utils import (\n     JobReturn,\n     configure_log,\n@@ -100,6 +101,17 @@\n                 sweep_config.hydra.job.num = idx\n             HydraConfig.instance().set_config(sweep_config)\n \n+            # If your launcher is executing code in a different process, it is important to restore\n+            # the singleton state in the new process.\n+            # To do this, you will likely need to serialize the singleton state along with the other\n+            # parameters passed to the child process.\n+\n+            # happening on launcher process\n+            state = Singleton.get_state()\n+\n+            # happening on the spawned process\n+            Singleton.set_state(state)\n+\n             ret = run_job(\n                 config=sweep_config,\n                 task_function=self.task_function,\n", "issue": "Update Example Launcher Plugin mention restoring the singletons\nThe singletons should be restored when performing multi-process launching.\r\nsomething \r\n\r\n```python\r\n# In the launcher's launch:\r\nstate = Singleton.get_state()\r\n\r\n# In the remote process\r\nSingleton.set_state(state)\r\n```\n", "before_files": [{"content": "# Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved\nimport logging\nfrom pathlib import Path\nfrom typing import Optional, Sequence\n\nfrom hydra.core.config_loader import ConfigLoader\nfrom hydra.core.config_search_path import ConfigSearchPath\nfrom hydra.core.hydra_config import HydraConfig\nfrom hydra.core.utils import (\n    JobReturn,\n    configure_log,\n    filter_overrides,\n    run_job,\n    setup_globals,\n)\nfrom hydra.plugins.launcher import Launcher\nfrom hydra.plugins.search_path_plugin import SearchPathPlugin\nfrom hydra.types import TaskFunction\nfrom omegaconf import DictConfig, open_dict\n\n# IMPORTANT:\n# If your plugin imports any module that takes more than a fraction of a second to import,\n# Import the module lazily (typically inside launch()).\n# Installed plugins are imported during Hydra initialization and plugins that are slow to import plugins will slow\n# the startup of ALL hydra applications.\n# Another approach is to place heavy includes in a file prefixed by _, such as _core.py:\n# Hydra will not look for plugin in such files and will not import them during plugin discovery.\n\n\nlog = logging.getLogger(__name__)\n\n\nclass ExampleLauncherSearchPathPlugin(SearchPathPlugin):\n    \"\"\"\n    This plugin is allowing configuration files provided by the ExampleLauncher plugin to be discovered\n    and used once the ExampleLauncher plugin is installed\n    \"\"\"\n\n    def manipulate_search_path(self, search_path: ConfigSearchPath) -> None:\n        # Appends the search path for this plugin to the end of the search path\n        search_path.append(\n            \"hydra-example-launcher\", \"pkg://hydra_plugins.example_launcher_plugin.conf\"\n        )\n\n\nclass ExampleLauncher(Launcher):\n    def __init__(self, foo: str, bar: str) -> None:\n        self.config: Optional[DictConfig] = None\n        self.config_loader: Optional[ConfigLoader] = None\n        self.task_function: Optional[TaskFunction] = None\n\n        # foo and var are coming from the the plugin's configuration\n        self.foo = foo\n        self.bar = bar\n\n    def setup(\n        self,\n        config: DictConfig,\n        config_loader: ConfigLoader,\n        task_function: TaskFunction,\n    ) -> None:\n        self.config = config\n        self.config_loader = config_loader\n        self.task_function = task_function\n\n    def launch(\n        self, job_overrides: Sequence[Sequence[str]], initial_job_idx: int\n    ) -> Sequence[JobReturn]:\n        \"\"\"\n        :param job_overrides: a List of List<String>, where each inner list is the arguments for one job run.\n        :param initial_job_idx: Initial job idx in batch.\n        :return: an array of return values from run_job with indexes corresponding to the input list indexes.\n        \"\"\"\n        setup_globals()\n        assert self.config is not None\n        assert self.config_loader is not None\n        assert self.task_function is not None\n\n        configure_log(self.config.hydra.hydra_logging, self.config.hydra.verbose)\n        sweep_dir = Path(str(self.config.hydra.sweep.dir))\n        sweep_dir.mkdir(parents=True, exist_ok=True)\n        log.info(\n            f\"Example Launcher(foo={self.foo}, bar={self.bar}) is launching {len(job_overrides)} jobs locally\"\n        )\n        log.info(f\"Sweep output dir : {sweep_dir}\")\n        runs = []\n\n        for idx, overrides in enumerate(job_overrides):\n            idx = initial_job_idx + idx\n            lst = \" \".join(filter_overrides(overrides))\n            log.info(f\"\\t#{idx} : {lst}\")\n            sweep_config = self.config_loader.load_sweep_config(\n                self.config, list(overrides)\n            )\n            with open_dict(sweep_config):\n                # This typically coming from the underlying scheduler (SLURM_JOB_ID for instance)\n                # In that case, it will not be available here because we are still in the main process.\n                # but instead should be populated remotely before calling the task_function.\n                sweep_config.hydra.job.id = f\"job_id_for_{idx}\"\n                sweep_config.hydra.job.num = idx\n            HydraConfig.instance().set_config(sweep_config)\n\n            ret = run_job(\n                config=sweep_config,\n                task_function=self.task_function,\n                job_dir_key=\"hydra.sweep.dir\",\n                job_subdir_key=\"hydra.sweep.subdir\",\n            )\n            runs.append(ret)\n            # reconfigure the logging subsystem for Hydra as the run_job call configured it for the Job.\n            # This is needed for launchers that calls run_job in the same process and not spawn a new one.\n            configure_log(self.config.hydra.hydra_logging, self.config.hydra.verbose)\n        return runs\n", "path": "plugins/examples/example_launcher_plugin/hydra_plugins/example_launcher_plugin/example_launcher.py"}], "after_files": [{"content": "# Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved\nimport logging\nfrom pathlib import Path\nfrom typing import Optional, Sequence\n\nfrom hydra.core.config_loader import ConfigLoader\nfrom hydra.core.config_search_path import ConfigSearchPath\nfrom hydra.core.hydra_config import HydraConfig\nfrom hydra.core.singleton import Singleton\nfrom hydra.core.utils import (\n    JobReturn,\n    configure_log,\n    filter_overrides,\n    run_job,\n    setup_globals,\n)\nfrom hydra.plugins.launcher import Launcher\nfrom hydra.plugins.search_path_plugin import SearchPathPlugin\nfrom hydra.types import TaskFunction\nfrom omegaconf import DictConfig, open_dict\n\n# IMPORTANT:\n# If your plugin imports any module that takes more than a fraction of a second to import,\n# Import the module lazily (typically inside launch()).\n# Installed plugins are imported during Hydra initialization and plugins that are slow to import plugins will slow\n# the startup of ALL hydra applications.\n# Another approach is to place heavy includes in a file prefixed by _, such as _core.py:\n# Hydra will not look for plugin in such files and will not import them during plugin discovery.\n\n\nlog = logging.getLogger(__name__)\n\n\nclass ExampleLauncherSearchPathPlugin(SearchPathPlugin):\n    \"\"\"\n    This plugin is allowing configuration files provided by the ExampleLauncher plugin to be discovered\n    and used once the ExampleLauncher plugin is installed\n    \"\"\"\n\n    def manipulate_search_path(self, search_path: ConfigSearchPath) -> None:\n        # Appends the search path for this plugin to the end of the search path\n        search_path.append(\n            \"hydra-example-launcher\", \"pkg://hydra_plugins.example_launcher_plugin.conf\"\n        )\n\n\nclass ExampleLauncher(Launcher):\n    def __init__(self, foo: str, bar: str) -> None:\n        self.config: Optional[DictConfig] = None\n        self.config_loader: Optional[ConfigLoader] = None\n        self.task_function: Optional[TaskFunction] = None\n\n        # foo and var are coming from the the plugin's configuration\n        self.foo = foo\n        self.bar = bar\n\n    def setup(\n        self,\n        config: DictConfig,\n        config_loader: ConfigLoader,\n        task_function: TaskFunction,\n    ) -> None:\n        self.config = config\n        self.config_loader = config_loader\n        self.task_function = task_function\n\n    def launch(\n        self, job_overrides: Sequence[Sequence[str]], initial_job_idx: int\n    ) -> Sequence[JobReturn]:\n        \"\"\"\n        :param job_overrides: a List of List<String>, where each inner list is the arguments for one job run.\n        :param initial_job_idx: Initial job idx in batch.\n        :return: an array of return values from run_job with indexes corresponding to the input list indexes.\n        \"\"\"\n        setup_globals()\n        assert self.config is not None\n        assert self.config_loader is not None\n        assert self.task_function is not None\n\n        configure_log(self.config.hydra.hydra_logging, self.config.hydra.verbose)\n        sweep_dir = Path(str(self.config.hydra.sweep.dir))\n        sweep_dir.mkdir(parents=True, exist_ok=True)\n        log.info(\n            f\"Example Launcher(foo={self.foo}, bar={self.bar}) is launching {len(job_overrides)} jobs locally\"\n        )\n        log.info(f\"Sweep output dir : {sweep_dir}\")\n        runs = []\n\n        for idx, overrides in enumerate(job_overrides):\n            idx = initial_job_idx + idx\n            lst = \" \".join(filter_overrides(overrides))\n            log.info(f\"\\t#{idx} : {lst}\")\n            sweep_config = self.config_loader.load_sweep_config(\n                self.config, list(overrides)\n            )\n            with open_dict(sweep_config):\n                # This typically coming from the underlying scheduler (SLURM_JOB_ID for instance)\n                # In that case, it will not be available here because we are still in the main process.\n                # but instead should be populated remotely before calling the task_function.\n                sweep_config.hydra.job.id = f\"job_id_for_{idx}\"\n                sweep_config.hydra.job.num = idx\n            HydraConfig.instance().set_config(sweep_config)\n\n            # If your launcher is executing code in a different process, it is important to restore\n            # the singleton state in the new process.\n            # To do this, you will likely need to serialize the singleton state along with the other\n            # parameters passed to the child process.\n\n            # happening on launcher process\n            state = Singleton.get_state()\n\n            # happening on the spawned process\n            Singleton.set_state(state)\n\n            ret = run_job(\n                config=sweep_config,\n                task_function=self.task_function,\n                job_dir_key=\"hydra.sweep.dir\",\n                job_subdir_key=\"hydra.sweep.subdir\",\n            )\n            runs.append(ret)\n            # reconfigure the logging subsystem for Hydra as the run_job call configured it for the Job.\n            # This is needed for launchers that calls run_job in the same process and not spawn a new one.\n            configure_log(self.config.hydra.hydra_logging, self.config.hydra.verbose)\n        return runs\n", "path": "plugins/examples/example_launcher_plugin/hydra_plugins/example_launcher_plugin/example_launcher.py"}]}