_monitor_fs does not seem to hold reference to callback
还没有人认领这个 Issue。
评估
- 难度
- 4/5
- 预计耗时
- 3-5 天
- 新手友好度
- 35/100
- Issue 类型
- 缺陷
- 描述清晰度
- 基本清楚
- 活跃度
- 停滞
- 技术栈
- linux, python
调研方向
运行提供的 reproducer,并观察 gc.collect 之后事件是否停止。然后跟踪 _monitor_fs 入口点及其 callback 的处理;当 callback 及其引用的 FileAndHandle 仍可用,并且垃圾回收后读取事件仍继续时,即表示完成。
由索引模型根据 Issue 内容生成。
描述
uvloop version: 0.17.0
python version: 3.8.10
platform: linux
The bug can be reproduced with the below script. I call _monitor_fs on the loop, passing in a function callback that itself has a reference to the file I'm reading as well as the handle to the _monitor_fs. I set a timer to later call gc.collect and when that happens, my object gets deleted and I stop getting read events.
This does seem to be a bug because the loop itself should have reference to my callback which has a reference to my object and that object has a reference to the file and handle, so GC should not be collecting them.
import functools
import gc
import sys
import tempfile
import typing
import uvloop
import os.path
import subprocess
class FileAndHandle:
def __init__(self, f: typing.IO):
self.f = f
self.handle = None
def __del__(self):
print('goodbye cruel world')
class FileWatcher:
_proc: typing.Optional[subprocess.Popen]
def __init__(self):
self._loop = uvloop.new_event_loop()
self._proc = None
self._last_read_event = 0
def _do_read(self, file_and_handle: FileAndHandle, _os_fn: bytes, _ev_enum: int):
self._last_read_event = self._loop.time()
print(f'read: {repr(file_and_handle.f.read())}')
def _check_read_timer(self):
t = self._loop.time()
if t - self._last_read_event > 3:
print('stopped getting read events')
self._proc.kill()
self._loop.stop()
else:
self._loop.call_later(1, self._check_read_timer)
def _start_watching(self, f_path: str) -> None:
fah = FileAndHandle(open(f_path))
fah.handle = self._loop._monitor_fs(f_path, functools.partial(self._do_read, fah))
def main(self) -> None:
with tempfile.TemporaryDirectory() as tmp_dir:
pth = os.path.join(tmp_dir, "file.txt")
open(pth, 'wt').close()
self._proc = subprocess.Popen([sys.executable, '-c', f'''
import time
with open("{pth}", "wt") as f:
while True:
time.sleep(2)
f.write("hello\\n")
f.flush()
'''])
self._start_watching(pth)
self._loop.call_later(3, self._check_read_timer)
self._loop.call_later(15, gc.collect)
self._loop.run_forever()
if __name__ == '__main__':
FileWatcher().main()
- 主要语言
- Cython
- 星标
- 11.9k
- 派生
- 615
- PR 合并指标
- 30 天内没有已合并 PR
贡献指南
这个仓库没有索引到贡献指南
从这里开始
- 先读完整个 Issue,再读项目的贡献指南。
- 在 Issue 下留言说明你要接手 —— 这能避免两个人做同样的事。
- Fork 仓库,在一个分支上完成修改。
- 提交 Pull Request,并在描述里引用这个 Issue 编号。
MagicStack/uvloop 的其他 Issue
-
难度 2/5 1-3 小时 新手友好度 68/100
MagicStack/uvloop#759 ·
-
难度 2/5 1-3 小时 新手友好度 68/100
MagicStack/uvloop#741 · 2 个 reaction ·
-
难度 2/5 1-3 小时 新手友好度 68/100
MagicStack/uvloop#702 · 8 条评论 · 9 个 reaction ·
-
难度 4/5 3-5 天 新手友好度 25/100
MagicStack/uvloop#766 ·
-
难度 4/5 3-5 天 新手友好度 52/100
MagicStack/uvloop#765 ·
查看 MagicStack/uvloop 的全部 Issue
相似的 Issue
-
enhancement
难度 2/5 1-3 小时 新手友好度 70/100
canonical/paas-charm#368 · 1 条评论 ·
-
难度 2/5 1-3 小时 新手友好度 75/100
-
tech debt
难度 2/5 1-3 小时 新手友好度 75/100
-
area:workflow bug ready-for-agent
难度 2/5 1-3 小时 新手友好度 75/100
fil-donadoni/tolaria#4409 ·
-
status/awaiting_triage
难度 2/5 1-3 小时 新手友好度 75/100