diff options
| -rw-r--r-- | bitbake/lib/bb/asyncrpc/client.py | 10 | ||||
| -rw-r--r-- | bitbake/lib/bb/asyncrpc/serv.py | 24 |
2 files changed, 30 insertions, 4 deletions
diff --git a/bitbake/lib/bb/asyncrpc/client.py b/bitbake/lib/bb/asyncrpc/client.py index 3eb4fdde8a..50e60d5c31 100644 --- a/bitbake/lib/bb/asyncrpc/client.py +++ b/bitbake/lib/bb/asyncrpc/client.py | |||
| @@ -119,6 +119,16 @@ class Client(object): | |||
| 119 | self.client = self._get_async_client() | 119 | self.client = self._get_async_client() |
| 120 | self.loop = asyncio.new_event_loop() | 120 | self.loop = asyncio.new_event_loop() |
| 121 | 121 | ||
| 122 | # Override any pre-existing loop. | ||
| 123 | # Without this, the PR server export selftest triggers a hang | ||
| 124 | # when running with Python 3.7. The drawback is that there is | ||
| 125 | # potential for issues if the PR and hash equiv (or some new) | ||
| 126 | # clients need to both be instantiated in the same process. | ||
| 127 | # This should be revisited if/when Python 3.9 becomes the | ||
| 128 | # minimum required version for BitBake, as it seems not | ||
| 129 | # required (but harmless) with it. | ||
| 130 | asyncio.set_event_loop(self.loop) | ||
| 131 | |||
| 122 | self._add_methods('connect_tcp', 'close', 'ping') | 132 | self._add_methods('connect_tcp', 'close', 'ping') |
| 123 | 133 | ||
| 124 | @abc.abstractmethod | 134 | @abc.abstractmethod |
diff --git a/bitbake/lib/bb/asyncrpc/serv.py b/bitbake/lib/bb/asyncrpc/serv.py index 45628698b6..b4cffff213 100644 --- a/bitbake/lib/bb/asyncrpc/serv.py +++ b/bitbake/lib/bb/asyncrpc/serv.py | |||
| @@ -136,10 +136,7 @@ class AsyncServer(object): | |||
| 136 | self.logger = logger | 136 | self.logger = logger |
| 137 | self.start = None | 137 | self.start = None |
| 138 | self.address = None | 138 | self.address = None |
| 139 | 139 | self.loop = None | |
| 140 | @property | ||
| 141 | def loop(self): | ||
| 142 | return asyncio.get_event_loop() | ||
| 143 | 140 | ||
| 144 | def start_tcp_server(self, host, port): | 141 | def start_tcp_server(self, host, port): |
| 145 | def start_tcp(): | 142 | def start_tcp(): |
| @@ -228,6 +225,12 @@ class AsyncServer(object): | |||
| 228 | """ | 225 | """ |
| 229 | Serve requests in the current process | 226 | Serve requests in the current process |
| 230 | """ | 227 | """ |
| 228 | # Create loop and override any loop that may have existed in | ||
| 229 | # a parent process. It is possible that the usecases of | ||
| 230 | # serve_forever might be constrained enough to allow using | ||
| 231 | # get_event_loop here, but better safe than sorry for now. | ||
| 232 | self.loop = asyncio.new_event_loop() | ||
| 233 | asyncio.set_event_loop(self.loop) | ||
| 231 | self.start() | 234 | self.start() |
| 232 | self._serve_forever() | 235 | self._serve_forever() |
| 233 | 236 | ||
| @@ -236,6 +239,19 @@ class AsyncServer(object): | |||
| 236 | Serve requests in a child process | 239 | Serve requests in a child process |
| 237 | """ | 240 | """ |
| 238 | def run(queue): | 241 | def run(queue): |
| 242 | # Create loop and override any loop that may have existed | ||
| 243 | # in a parent process. Without doing this and instead | ||
| 244 | # using get_event_loop, at the very minimum the hashserv | ||
| 245 | # unit tests will hang when running the second test. | ||
| 246 | # This happens since get_event_loop in the spawned server | ||
| 247 | # process for the second testcase ends up with the loop | ||
| 248 | # from the hashserv client created in the unit test process | ||
| 249 | # when running the first testcase. The problem is somewhat | ||
| 250 | # more general, though, as any potential use of asyncio in | ||
| 251 | # Cooker could create a loop that needs to replaced in this | ||
| 252 | # new process. | ||
| 253 | self.loop = asyncio.new_event_loop() | ||
| 254 | asyncio.set_event_loop(self.loop) | ||
| 239 | try: | 255 | try: |
| 240 | self.start() | 256 | self.start() |
| 241 | finally: | 257 | finally: |
