{"action":"created","issue":{"url":"https://api.github.com/repos/jettify/aiobotocore/issues/17","labels_url":"https://api.github.com/repos/jettify/aiobotocore/issues/17/labels{/name}","comments_url":"https://api.github.com/repos/jettify/aiobotocore/issues/17/comments","events_url":"https://api.github.com/repos/jettify/aiobotocore/issues/17/events","html_url":"https://github.com/jettify/aiobotocore/issues/17","id":123222503,"number":17,"title":"get_object is broken in case of concurrent execution.","user":{"login":"oselivanov","id":1576032,"avatar_url":"https://avatars.githubusercontent.com/u/1576032?v=3","gravatar_id":"","url":"https://api.github.com/users/oselivanov","html_url":"https://github.com/oselivanov","followers_url":"https://api.github.com/users/oselivanov/followers","following_url":"https://api.github.com/users/oselivanov/following{/other_user}","gists_url":"https://api.github.com/users/oselivanov/gists{/gist_id}","starred_url":"https://api.github.com/users/oselivanov/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/oselivanov/subscriptions","organizations_url":"https://api.github.com/users/oselivanov/orgs","repos_url":"https://api.github.com/users/oselivanov/repos","events_url":"https://api.github.com/users/oselivanov/events{/privacy}","received_events_url":"https://api.github.com/users/oselivanov/received_events","type":"User","site_admin":false},"labels":[],"state":"open","locked":false,"assignee":null,"milestone":null,"comments":3,"created_at":"2015-12-21T07:12:06Z","updated_at":"2015-12-23T21:56:06Z","closed_at":null,"body":"I've tried to build simplest possible web server talking to s3 and found an issue:\r\n\r\nRun following example:\r\n```\r\n#!/usr/bin/env python3\r\nfrom os import environ\r\nfrom time import time\r\n\r\nimport aiobotocore\r\nfrom aiohttp import web\r\nfrom asyncio import get_event_loop\r\n\r\nbucket = 'my-bucket'\r\nkey = 'my-1mb-key'\r\n\r\nsession = aiobotocore.get_session()\r\nclient = session.create_client(\r\n    's3', region_name='us-east-1',\r\n    aws_secret_access_key=environ['AWS_SECRET_ACCESS_KEY'],\r\n    aws_access_key_id=environ['AWS_ACCESS_KEY_ID'])\r\n\r\nasync def get_content(key):\r\n    obj = await client.get_object(Bucket=bucket, Key=key)\r\n    body = await obj['Body'].read()\r\n    return body\r\n\r\nasync def index(request):\r\n    print('got request')\r\n    t = time()\r\n    results = await get_content(key)\r\n    content = str(len(results)).encode() + b' ' + str(time() - t).encode()\r\n    print('request done')\r\n    return web.Response(body=content)\r\n\r\napp = web.Application()\r\napp.router.add_route('GET', '/', index)\r\n\r\nloop = get_event_loop()\r\nhandler = app.make_handler()\r\nf = loop.create_server(handler, '0.0.0.0', 8080)\r\nsrv = loop.run_until_complete(f)\r\nprint('serving on', srv.sockets[0].getsockname())\r\ntry:\r\n    loop.run_forever()\r\nexcept KeyboardInterrupt:\r\n    pass\r\nfinally:\r\n    loop.run_until_complete(handler.finish_connections(1.0))\r\n    srv.close()\r\n    loop.run_until_complete(srv.wait_closed())\r\n    loop.run_until_complete(app.finish())\r\nloop.close()\r\n```\r\n\r\nThen use \r\n\r\n        siege -c 4 -t 600s 'http://localhost:8080/'\r\n\r\nYou'll get following output:\r\n\r\n```\r\n** SIEGE 3.1.0\r\n** Preparing 4 concurrent users for battle.\r\nThe server is now under siege...\r\nHTTP/1.1 200   3.76 secs:      17 bytes ==> GET  /\r\nHTTP/1.1 200   3.76 secs:      17 bytes ==> GET  /\r\nHTTP/1.1 200   4.19 secs:      17 bytes ==> GET  /\r\nHTTP/1.1 500   2.35 secs:     170 bytes ==> GET  /\r\nHTTP/1.1 200   2.39 secs:      18 bytes ==> GET  /\r\nHTTP/1.1 500   2.42 secs:     170 bytes ==> GET  /\r\nHTTP/1.1 500   2.69 secs:     170 bytes ==> GET  /\r\nHTTP/1.1 500   9.37 secs:     170 bytes ==> GET  /\r\nHTTP/1.1 500   1.79 secs:     170 bytes ==> GET  /\r\nHTTP/1.1 200   4.79 secs:      17 bytes ==> GET  /\r\nHTTP/1.1 200   2.83 secs:      17 bytes ==> GET  /\r\nHTTP/1.1 500   2.58 secs:     170 bytes ==> GET  /\r\nHTTP/1.1 500   2.12 secs:     170 bytes ==> GET  /\r\nHTTP/1.1 500   2.54 secs:     170 bytes ==> GET  /\r\nHTTP/1.1 200   5.29 secs:      17 bytes ==> GET  /\r\nHTTP/1.1 200   7.09 secs:      17 bytes ==> GET  /\r\nHTTP/1.1 500   5.86 secs:     170 bytes ==> GET  /\r\nHTTP/1.1 500   5.43 secs:     170 bytes ==> GET  /\r\nHTTP/1.1 500   2.38 secs:     170 bytes ==> GET  /\r\nHTTP/1.1 200   5.51 secs:      16 bytes ==> GET  /\r\n```\r\n\r\nIn logs:\r\n```\r\nError handling request\r\nTraceback (most recent call last):\r\n  File \"/Library/Frameworks/Python.framework/Versions/3.5/lib/python3.5/site-packages/aiohttp/server.py\", line 262, in start\r\n    yield from self.handle_request(message, payload)\r\n  File \"/Library/Frameworks/Python.framework/Versions/3.5/lib/python3.5/site-packages/aiohttp/web.py\", line 87, in handle_request\r\n    resp = yield from handler(request)\r\n  File \"./py35aio.py\", line 25, in index\r\n    results = await get_content(key)\r\n  File \"./py35aio.py\", line 19, in get_content\r\n    body = await obj['Body'].read()\r\n  File \"/Library/Frameworks/Python.framework/Versions/3.5/lib/python3.5/site-packages/aiohttp/streams.py\", line 472, in wrapper\r\n    result = yield from func(self, *args, **kw)\r\n  File \"/Library/Frameworks/Python.framework/Versions/3.5/lib/python3.5/site-packages/aiohttp/streams.py\", line 527, in read\r\n    return (yield from super().read(n))\r\n  File \"/Library/Frameworks/Python.framework/Versions/3.5/lib/python3.5/site-packages/aiohttp/streams.py\", line 247, in read\r\n    block = yield from self.readany()\r\n  File \"/Library/Frameworks/Python.framework/Versions/3.5/lib/python3.5/site-packages/aiohttp/streams.py\", line 472, in wrapper\r\n    result = yield from func(self, *args, **kw)\r\n  File \"/Library/Frameworks/Python.framework/Versions/3.5/lib/python3.5/site-packages/aiohttp/streams.py\", line 535, in readany\r\n    return (yield from super().readany())\r\n  File \"/Library/Frameworks/Python.framework/Versions/3.5/lib/python3.5/site-packages/aiohttp/streams.py\", line 270, in readany\r\n    yield from self._waiter\r\n  File \"/Library/Frameworks/Python.framework/Versions/3.5/lib/python3.5/asyncio/futures.py\", line 385, in __iter__\r\n    yield self  # This tells Task to wait for completion.\r\n  File \"/Library/Frameworks/Python.framework/Versions/3.5/lib/python3.5/asyncio/tasks.py\", line 288, in _wakeup\r\n    value = future.result()\r\n  File \"/Library/Frameworks/Python.framework/Versions/3.5/lib/python3.5/asyncio/futures.py\", line 274, in result\r\n    raise self._exception\r\naiohttp.errors.ServerDisconnectedError\r\nError handling request\r\nTraceback (most recent call last):\r\n  File \"/Library/Frameworks/Python.framework/Versions/3.5/lib/python3.5/site-packages/aiohttp/server.py\", line 262, in start\r\n    yield from self.handle_request(message, payload)\r\n  File \"/Library/Frameworks/Python.framework/Versions/3.5/lib/python3.5/site-packages/aiohttp/web.py\", line 87, in handle_request\r\n    resp = yield from handler(request)\r\n  File \"./py35aio.py\", line 25, in index\r\n    results = await get_content(key)\r\n  File \"./py35aio.py\", line 19, in get_content\r\n    body = await obj['Body'].read()\r\n  File \"/Library/Frameworks/Python.framework/Versions/3.5/lib/python3.5/site-packages/aiohttp/streams.py\", line 472, in wrapper\r\n    result = yield from func(self, *args, **kw)\r\n  File \"/Library/Frameworks/Python.framework/Versions/3.5/lib/python3.5/site-packages/aiohttp/streams.py\", line 527, in read\r\n    return (yield from super().read(n))\r\n  File \"/Library/Frameworks/Python.framework/Versions/3.5/lib/python3.5/site-packages/aiohttp/streams.py\", line 247, in read\r\n    block = yield from self.readany()\r\n  File \"/Library/Frameworks/Python.framework/Versions/3.5/lib/python3.5/site-packages/aiohttp/streams.py\", line 472, in wrapper\r\n    result = yield from func(self, *args, **kw)\r\n  File \"/Library/Frameworks/Python.framework/Versions/3.5/lib/python3.5/site-packages/aiohttp/streams.py\", line 535, in readany\r\n    return (yield from super().readany())\r\n  File \"/Library/Frameworks/Python.framework/Versions/3.5/lib/python3.5/site-packages/aiohttp/streams.py\", line 270, in readany\r\n    yield from self._waiter\r\n  File \"/Library/Frameworks/Python.framework/Versions/3.5/lib/python3.5/asyncio/futures.py\", line 385, in __iter__\r\n    yield self  # This tells Task to wait for completion.\r\n  File \"/Library/Frameworks/Python.framework/Versions/3.5/lib/python3.5/asyncio/tasks.py\", line 288, in _wakeup\r\n    value = future.result()\r\n  File \"/Library/Frameworks/Python.framework/Versions/3.5/lib/python3.5/asyncio/futures.py\", line 274, in result\r\n    raise self._exception\r\naiohttp.errors.ServerDisconnectedError\r\n```\r\n\r\nIt seems that in case of multiple requests obj['Body'] might be broken.\r\n```\r\n    obj = await client.get_object(Bucket=bucket, Key=key)\r\n    body = await obj['Body'].read()\r\n```\r\n\r\nEven if you try to move this block \r\n```\r\nsession = aiobotocore.get_session()\r\nclient = session.create_client(\r\n    's3', region_name='us-east-1',\r\n    aws_secret_access_key=environ['AWS_SECRET_ACCESS_KEY'],\r\n    aws_access_key_id=environ['AWS_ACCESS_KEY_ID'])\r\n``` \r\ninside of the \"get_content\" function it will act the same."},"comment":{"url":"https://api.github.com/repos/jettify/aiobotocore/issues/comments/166998491","html_url":"https://github.com/jettify/aiobotocore/issues/17#issuecomment-166998491","issue_url":"https://api.github.com/repos/jettify/aiobotocore/issues/17","id":166998491,"user":{"login":"oselivanov","id":1576032,"avatar_url":"https://avatars.githubusercontent.com/u/1576032?v=3","gravatar_id":"","url":"https://api.github.com/users/oselivanov","html_url":"https://github.com/oselivanov","followers_url":"https://api.github.com/users/oselivanov/followers","following_url":"https://api.github.com/users/oselivanov/following{/other_user}","gists_url":"https://api.github.com/users/oselivanov/gists{/gist_id}","starred_url":"https://api.github.com/users/oselivanov/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/oselivanov/subscriptions","organizations_url":"https://api.github.com/users/oselivanov/orgs","repos_url":"https://api.github.com/users/oselivanov/repos","events_url":"https://api.github.com/users/oselivanov/events{/privacy}","received_events_url":"https://api.github.com/users/oselivanov/received_events","type":"User","site_admin":false},"created_at":"2015-12-23T21:56:06Z","updated_at":"2015-12-23T21:56:06Z","body":"I have not time to test it these days, maybe later. But assumption that aws breaks in case of 2 concurrent requests per second sounds awkward. \r\nI just know when we use vanilla boto in production in thread pool with a lot of concurrent requests it works just fine."}}