Main async serving loop.
(self)
| 159 | self._cleanup() |
| 160 | |
| 161 | async def _serve(self): |
| 162 | """Main async serving loop.""" |
| 163 | # Run lifespan startup |
| 164 | lifespan_mode = getattr(self.cfg, 'asgi_lifespan', 'auto') |
| 165 | if lifespan_mode != "off": |
| 166 | from gunicorn.asgi.lifespan import LifespanManager |
| 167 | self.lifespan = LifespanManager(self.asgi, self.log, self.state) |
| 168 | try: |
| 169 | await self.lifespan.startup() |
| 170 | except Exception as e: |
| 171 | if lifespan_mode == "on": |
| 172 | self.log.error("ASGI lifespan startup failed: %s", e) |
| 173 | return |
| 174 | else: |
| 175 | # auto mode - app doesn't support lifespan |
| 176 | self.log.debug("ASGI lifespan not supported by app: %s", e) |
| 177 | self.lifespan = None |
| 178 | |
| 179 | # Create servers for each listener socket |
| 180 | ssl_context = self._get_ssl_context() |
| 181 | |
| 182 | for sock in self.sockets: |
| 183 | try: |
| 184 | server = await self.loop.create_server( |
| 185 | lambda: ASGIProtocol(self), |
| 186 | sock=sock.sock, |
| 187 | ssl=ssl_context, |
| 188 | reuse_address=True, |
| 189 | start_serving=True, |
| 190 | ) |
| 191 | self.servers.append(server) |
| 192 | self.log.info("ASGI server listening on %s", sock) |
| 193 | except Exception as e: |
| 194 | self.log.error("Failed to create server on %s: %s", sock, e) |
| 195 | |
| 196 | if not self.servers: |
| 197 | self.log.error("No servers could be started") |
| 198 | return |
| 199 | |
| 200 | # Main loop with heartbeat |
| 201 | try: |
| 202 | while self.alive: |
| 203 | self.notify() |
| 204 | |
| 205 | # Check if parent is still alive |
| 206 | if self.ppid != os.getppid(): |
| 207 | self.log.info("Parent changed, shutting down: %s", self) |
| 208 | break |
| 209 | |
| 210 | # Check connection limit |
| 211 | # (Connections are managed by nr_conns in ASGIProtocol) |
| 212 | |
| 213 | await asyncio.sleep(1.0) |
| 214 | |
| 215 | except asyncio.CancelledError: |
| 216 | pass |
| 217 | |
| 218 | # Graceful shutdown |
no test coverage detected