Component
pygls/protocol/json_rpc.py
Summary
When sending data over an async writer, the result of writer.write() is sometimes awaitable. The code calls asyncio.ensure_future(res) and immediately drops the returned Task. Exceptions are silently lost and the task cannot be cancelled during shutdown.
Steps to Reproduce
- Send a large payload over an async transport under backpressure.
- The write task is created but not tracked.
Expected Behavior
Pending writes should be tracked so they can be awaited and errors caught.
Actual Behavior
Write tasks are fire-and-forget.
Affected Code (pygls/protocol/json_rpc.py, ~L541-543)
res = self.writer.write(data.encode(self.CHARSET))
if inspect.isawaitable(res):
asyncio.ensure_future(res)
Proposed Fix
Track the task in a set and discard it when done:
if inspect.isawaitable(res):
task = asyncio.ensure_future(res)
self._pending_writes.add(task)
task.add_done_callback(self._pending_writes.discard)
Component
pygls/protocol/json_rpc.py
Summary
When sending data over an async writer, the result of
writer.write()is sometimes awaitable. The code callsasyncio.ensure_future(res)and immediately drops the returnedTask. Exceptions are silently lost and the task cannot be cancelled during shutdown.Steps to Reproduce
Expected Behavior
Pending writes should be tracked so they can be awaited and errors caught.
Actual Behavior
Write tasks are fire-and-forget.
Affected Code (
pygls/protocol/json_rpc.py, ~L541-543)Proposed Fix
Track the task in a set and discard it when done: