You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Since adding the StackImpact agent to a Tornado/asyncio application, we started seeing BufferErrors like this:
BufferError: Existing exports of data: object cannot be re-sized
File "tornado/web.py", line 1513, in _execute
self.finish()
File "tornado/web.py", line 991, in finish
self.flush(include_footers=True)
File "tornado/web.py", line 947, in flush
start_line, self._headers, chunk, callback=callback)
File "tornado/http1connection.py", line 400, in write_headers
self._pending_write = self.stream.write(data)
File "tornado/iostream.py", line 406, in write
self._handle_write()
File "tornado/iostream.py", line 872, in _handle_write
del self._write_buffer[:self._write_buffer_pos]
Environment
Our application runs inside a Docker container. We use:
Cursory googling turned up the same error happening in the same place, as reported in this comment on a Tornado pull request. I don't know enough about Tornado's internals to guess at what's going on here but maybe @bdarnell can provide more insight.
In any case, I'm happy to provide more details as needed.
Thanks for submitting the issue with the detailed info!
I've tried with a simple asyncio/tornado app, based on the code you provided, running for some time under high load. I get no errors and the agent reports everything it supposed to.
Is there any specific functionality in your app, which you think might be related and I need to try to reproduce? Any other modules?
One thing to try, if possible in your case, is to disable memory profiler by passing allocation_profiler_disabled = True on agent initialization. Just to make sure it is not caused by python's own allocation profiler, which the agent uses. Other profilers can be disabled as well setting the following flags to True: cpu_profiler_disabled, block_profiler_disabled, error_profiler_disabled.
Please note, we haven't yet worked on a full support of asyncio (only gevent). Especially time and server profilers might be affected.
I deployed a build of our app earlier this morning with allocation_profiler_disabled=True but unfortunately we still ran into the BufferError.
Our app is fairly complex with many 3rd-party modules but it's hard for me to say whether any of them might be contributing. From our requirements.txt:
Most of the app is asynchronous. It communicates with clients via REST and WebSocket. We use asyncio-native libraries to interface with upstream services where possible (AWS via aiobotocore, Redis via aioredis). Without a good, native asyncio Neo4j driver available we run synchronous calls to neo4j-driver in a ThreadPoolExecutor like this (again, simplified for brevity):
I was able to reproduce the issue, with and without the agent. What happens is that if we do current_frames = sys._current_frames() inside of a signal handler, the current_frames local variable isn't cleaned up soon enough, which causes the memoryview in iostream.py to complain, probably because there are some references kept in the thread frames longer than expected.
Cleaning up local variables explicitly in signal handler fixes the problem. The fix is released in agent v1.0.3.
Activity
dmelikyan commentedon Jun 28, 2017
Thanks for submitting the issue with the detailed info!
I've tried with a simple asyncio/tornado app, based on the code you provided, running for some time under high load. I get no errors and the agent reports everything it supposed to.
Is there any specific functionality in your app, which you think might be related and I need to try to reproduce? Any other modules?
One thing to try, if possible in your case, is to disable memory profiler by passing
allocation_profiler_disabled = Trueon agent initialization. Just to make sure it is not caused by python's own allocation profiler, which the agent uses. Other profilers can be disabled as well setting the following flags to True:cpu_profiler_disabled,block_profiler_disabled,error_profiler_disabled.Please note, we haven't yet worked on a full support of asyncio (only gevent). Especially time and server profilers might be affected.
adamrothman commentedon Jun 28, 2017
I deployed a build of our app earlier this morning with
allocation_profiler_disabled=Truebut unfortunately we still ran into theBufferError.Our app is fairly complex with many 3rd-party modules but it's hard for me to say whether any of them might be contributing. From our
requirements.txt:Most of the app is asynchronous. It communicates with clients via REST and WebSocket. We use asyncio-native libraries to interface with upstream services where possible (AWS via
aiobotocore, Redis viaaioredis). Without a good, native asyncio Neo4j driver available we run synchronous calls toneo4j-driverin aThreadPoolExecutorlike this (again, simplified for brevity):Apart from the above (which has never given us trouble), we had no other use of threading in the app prior to adding the StackImpact agent.
dmelikyan commentedon Jun 30, 2017
I was able to reproduce the issue, with and without the agent. What happens is that if we do
current_frames = sys._current_frames()inside of a signal handler, thecurrent_frameslocal variable isn't cleaned up soon enough, which causes thememoryviewin iostream.py to complain, probably because there are some references kept in the thread frames longer than expected.Cleaning up local variables explicitly in signal handler fixes the problem. The fix is released in agent v1.0.3.
adamrothman commentedon Jun 30, 2017
Awesome, thank you! I'll try it out again today or Monday and report back.