FutureSession:套接字连接未关闭
FutureSession: socket connections not closed
我正在开发一个 PyQt 程序,它主要从 Internet 收集数据。在此示例中,我尝试从 RSS 网页获取数据。
假设 self.feed 是包含所有文章的 RSS 页面,并且假设 "entry" 是一篇文章。 "entry.url" 是文章的原始页面,在网站上。
from requests_futures.sessions import FuturesSession
self.session_pages = FuturesSession(max_workers=20)
for entry in self.feed.entries:
future = self.session_pages.get(entry.url, timeout=10)
future.add_done_callback(my_call_back)
我基本上就是这样做的。它嵌入在 PyQt 线程中,我同时 运行 多个线程,但我认为问题不来自 PyQt。
我的问题是我认为未来不会关闭连接,即使它们已经完成。我这样检查:
lsof -i | grep "python" | wc -l
losf -i 给出连接中涉及的打开文件。命令的其余部分是计算打开的文件数。
这个数字不会停止增长(大约 900),然后我收到以下错误:
(python:28285): GLib-ERROR **: Creating pipes for GWakeup: Too many open files
[1] 28285 trace trap (core dumped) python gui.py
我认为问题出在期货上,但实际上我不确定。
我试过类似的东西:
self.session_pages.shutdown()
在线程的末尾,但没有用。
你有什么想法吗?
我在 python 的 concurrent.futures
中没有看到 FutureSession
?我在这里做一些假设。
除非每个回调都是唯一的 self.session_page.get(...)
我认为 future.add_done_callback(my_call_back)
行可能正在创建新的并覆盖回调的对象 ID,或者可能不正确?
这是来自 the only place 的地方,我可以在您使用的上下文中找到对 FutureSession
的引用:
from pprint import pprint
from requests_futures.sessions import FuturesSession
session = FuturesSession()
def bg_cb(sess, resp):
# parse the json storing the result on the response object
resp.data = resp.json()
future = session.get('http://httpbin.org/get', background_callback=bg_cb)
# do some other stuff, send some more requests while this one works
response = future.result()
print('response status {0}'.format(response.status_code))
# data will have been attached to the response object in the background
pprint(response.data)
尝试设置background_callback
更新:
- 唯一的Method that is being overwritten/wrapped is
from requests import Session
as inherited here和concurrent.futures
既没有get,也没有request。
我会尝试使用 self.session_pages.request
而不是 self.session_pages.get
因为 FutureSession
由线程池执行器和 requests.Sessions
组成
是这样的:
(Pdb) inspect.getmro(FuturesSession)
(<class '__main__.FuturesSession'>, <class 'requests.sessions.Session'>, <class 'requests.sessions.SessionRedirectMixin'>, <class 'object'>)
(Pdb) vars()
{'DEFAULT_POOLSIZE': 10, '__return__': None, '__spec__': None, 'inspect': <module 'inspect' from '/usr/lib/python3.4/inspect.py'>, '__file__': 'requestsfutures.py', 'FuturesSession': <class '__main__.FuturesSession'>, 'HTTPAdapter': <class 'requests.adapters.HTTPAdapter'>, 'ThreadPoolExecutor': <class 'concurrent.futures.thread.ThreadPoolExecutor'>, 'Session': <class 'requests.sessions.Session'>, '__name__': '__main__', '__cached__': None, '__doc__': "\nrequests_futures\n~~~~~~~~~~~~~~~~\n\nThis module provides a small add-on for the requests http library. It makes use\nof python 3.3's concurrent.futures or the futures backport for previous\nreleases of python.\n\n from requests_futures import FuturesSession\n\n session = FuturesSession()\n # request is run in the background\n future = session.get('http://httpbin.org/get')\n # ... do other stuff ...\n # wait for the request to complete, if it hasn't already\n response = future.result()\n print('response status: {0}'.format(response.status_code))\n print(response.content)\n\n", 'pdb': <module 'pdb' from '/usr/lib/python3.4/pdb.py'>, '__loader__': <_frozen_importlib.SourceFileLoader object at 0x7f6d84194470>, '__builtins__': <module 'builtins' (built-in)>, '__package__': None}
(Pdb) vars().keys()
dict_keys(['DEFAULT_POOLSIZE', '__return__', '__spec__', 'inspect', '__file__', 'FuturesSession', 'HTTPAdapter', 'ThreadPoolExecutor', 'Session', '__name__', '__cached__', '__doc__', 'pdb', '__loader__', '__builtins__', '__package__'])
(Pdb) vars()['FuturesSession']
<class '__main__.FuturesSession'>
(Pdb) vars()['FuturesSession'].get
<function Session.get at 0x7f6d80c07488>
(Pdb) vars()['Session'].get
<function Session.get at 0x7f6d80c07488>
好的,你是对的@jm_____。
get() 调用只是对 requests.get 的调用。所以我使用了这里的答案:
更具体地说:
future = self.session_pages.get(url, timeout=20, headers={'Connection':'close'})
现在 lsof 表示正常数字。谢谢。
我正在开发一个 PyQt 程序,它主要从 Internet 收集数据。在此示例中,我尝试从 RSS 网页获取数据。
假设 self.feed 是包含所有文章的 RSS 页面,并且假设 "entry" 是一篇文章。 "entry.url" 是文章的原始页面,在网站上。
from requests_futures.sessions import FuturesSession
self.session_pages = FuturesSession(max_workers=20)
for entry in self.feed.entries:
future = self.session_pages.get(entry.url, timeout=10)
future.add_done_callback(my_call_back)
我基本上就是这样做的。它嵌入在 PyQt 线程中,我同时 运行 多个线程,但我认为问题不来自 PyQt。
我的问题是我认为未来不会关闭连接,即使它们已经完成。我这样检查:
lsof -i | grep "python" | wc -l
losf -i 给出连接中涉及的打开文件。命令的其余部分是计算打开的文件数。 这个数字不会停止增长(大约 900),然后我收到以下错误:
(python:28285): GLib-ERROR **: Creating pipes for GWakeup: Too many open files
[1] 28285 trace trap (core dumped) python gui.py
我认为问题出在期货上,但实际上我不确定。
我试过类似的东西:
self.session_pages.shutdown()
在线程的末尾,但没有用。
你有什么想法吗?
我在 python 的 concurrent.futures
中没有看到 FutureSession
?我在这里做一些假设。
除非每个回调都是唯一的 self.session_page.get(...)
我认为 future.add_done_callback(my_call_back)
行可能正在创建新的并覆盖回调的对象 ID,或者可能不正确?
这是来自 the only place 的地方,我可以在您使用的上下文中找到对 FutureSession
的引用:
from pprint import pprint
from requests_futures.sessions import FuturesSession
session = FuturesSession()
def bg_cb(sess, resp):
# parse the json storing the result on the response object
resp.data = resp.json()
future = session.get('http://httpbin.org/get', background_callback=bg_cb)
# do some other stuff, send some more requests while this one works
response = future.result()
print('response status {0}'.format(response.status_code))
# data will have been attached to the response object in the background
pprint(response.data)
尝试设置background_callback
更新:
- 唯一的Method that is being overwritten/wrapped is
from requests import Session
as inherited here和concurrent.futures
既没有get,也没有request。
我会尝试使用 self.session_pages.request
而不是 self.session_pages.get
因为 FutureSession
由线程池执行器和 requests.Sessions
是这样的:
(Pdb) inspect.getmro(FuturesSession)
(<class '__main__.FuturesSession'>, <class 'requests.sessions.Session'>, <class 'requests.sessions.SessionRedirectMixin'>, <class 'object'>)
(Pdb) vars()
{'DEFAULT_POOLSIZE': 10, '__return__': None, '__spec__': None, 'inspect': <module 'inspect' from '/usr/lib/python3.4/inspect.py'>, '__file__': 'requestsfutures.py', 'FuturesSession': <class '__main__.FuturesSession'>, 'HTTPAdapter': <class 'requests.adapters.HTTPAdapter'>, 'ThreadPoolExecutor': <class 'concurrent.futures.thread.ThreadPoolExecutor'>, 'Session': <class 'requests.sessions.Session'>, '__name__': '__main__', '__cached__': None, '__doc__': "\nrequests_futures\n~~~~~~~~~~~~~~~~\n\nThis module provides a small add-on for the requests http library. It makes use\nof python 3.3's concurrent.futures or the futures backport for previous\nreleases of python.\n\n from requests_futures import FuturesSession\n\n session = FuturesSession()\n # request is run in the background\n future = session.get('http://httpbin.org/get')\n # ... do other stuff ...\n # wait for the request to complete, if it hasn't already\n response = future.result()\n print('response status: {0}'.format(response.status_code))\n print(response.content)\n\n", 'pdb': <module 'pdb' from '/usr/lib/python3.4/pdb.py'>, '__loader__': <_frozen_importlib.SourceFileLoader object at 0x7f6d84194470>, '__builtins__': <module 'builtins' (built-in)>, '__package__': None}
(Pdb) vars().keys()
dict_keys(['DEFAULT_POOLSIZE', '__return__', '__spec__', 'inspect', '__file__', 'FuturesSession', 'HTTPAdapter', 'ThreadPoolExecutor', 'Session', '__name__', '__cached__', '__doc__', 'pdb', '__loader__', '__builtins__', '__package__'])
(Pdb) vars()['FuturesSession']
<class '__main__.FuturesSession'>
(Pdb) vars()['FuturesSession'].get
<function Session.get at 0x7f6d80c07488>
(Pdb) vars()['Session'].get
<function Session.get at 0x7f6d80c07488>
好的,你是对的@jm_____。 get() 调用只是对 requests.get 的调用。所以我使用了这里的答案:
更具体地说:
future = self.session_pages.get(url, timeout=20, headers={'Connection':'close'})
现在 lsof 表示正常数字。谢谢。