{"action":"created","comment":{"url":"https://api.github.com/repos/boto/s3transfer/pulls/comments/69023479","id":69023479,"diff_hunk":"@@ -378,11 +389,114 @@ def _register_handlers(self):\n         self._client.meta.events.register_last(\n             event_name, enable_upload_callbacks, unique_id=enable_id)\n \n-    def shutdown(self):\n+    def __enter__(self):\n+        return self\n+\n+    def __exit__(self, exc_type, *args):\n+        cancel = False\n+        # If a exception was raised in the context handler, signal to cancel\n+        # all of the inprogress futures in the shutdown.\n+        if exc_type:\n+            cancel = True\n+        self.shutdown(cancel)\n+\n+    def shutdown(self, cancel=False):\n         \"\"\"Shutdown the TransferManager\n \n-        It will wait till all requests complete before it complete shuts down.\n+        It will wait till all transfers complete before it completely shuts\n+        down.\n+\n+        :type cancel: boolean\n+        :param cancel: If True, calls TransferFuture.cancel() for\n+            all in-progress in transfers. This is useful if you want the\n+            shutdown to happen quicker.\n+        \"\"\"\n+        if cancel:\n+            # Cancel all in-flight transfers if requested, before waiting\n+            # for them to complete.\n+            self._canceler.cancel()\n+        try:\n+            # Wait until there are no more in-progress transfers. This is\n+            # wrapped in a try statement because this can be interrupted\n+            # with a KeyboardInterrupt that needs to be caught.\n+            self._canceler.wait()\n+        finally:\n+            # If not errors were raised in the try block, the cancel should\n+            # have no coordinators it needs to run cancel on. If there was\n+            # an error raised in the try statement we want to cancel all of\n+            # the inflight transfers before shutting down to speed that\n+            # process up.\n+            self._canceler.cancel()\n+            # Shutdown all of the executors.\n+            self._submission_executor.shutdown()\n+            self._request_executor.shutdown()\n+            self._io_executor.shutdown()\n+\n+\n+class TransferCoordinatorCanceler(object):","path":"s3transfer/manager.py","position":86,"original_position":86,"commit_id":"b8bb9bf20f954965564b24576ad055964c4bf00f","original_commit_id":"b8bb9bf20f954965564b24576ad055964c4bf00f","user":{"login":"kyleknap","id":4605355,"avatar_url":"https://avatars.githubusercontent.com/u/4605355?v=3","gravatar_id":"","url":"https://api.github.com/users/kyleknap","html_url":"https://github.com/kyleknap","followers_url":"https://api.github.com/users/kyleknap/followers","following_url":"https://api.github.com/users/kyleknap/following{/other_user}","gists_url":"https://api.github.com/users/kyleknap/gists{/gist_id}","starred_url":"https://api.github.com/users/kyleknap/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/kyleknap/subscriptions","organizations_url":"https://api.github.com/users/kyleknap/orgs","repos_url":"https://api.github.com/users/kyleknap/repos","events_url":"https://api.github.com/users/kyleknap/events{/privacy}","received_events_url":"https://api.github.com/users/kyleknap/received_events","type":"User","site_admin":false},"body":"Yeah... I was having troubles coming up with a name. Any ideas? I originally was going to call it a TransferManagerController but that is vague.","created_at":"2016-06-29T20:42:07Z","updated_at":"2016-06-29T20:42:07Z","html_url":"https://github.com/boto/s3transfer/pull/19#discussion_r69023479","pull_request_url":"https://api.github.com/repos/boto/s3transfer/pulls/19","_links":{"self":{"href":"https://api.github.com/repos/boto/s3transfer/pulls/comments/69023479"},"html":{"href":"https://github.com/boto/s3transfer/pull/19#discussion_r69023479"},"pull_request":{"href":"https://api.github.com/repos/boto/s3transfer/pulls/19"}}},"pull_request":{"url":"https://api.github.com/repos/boto/s3transfer/pulls/19","id":75571382,"html_url":"https://github.com/boto/s3transfer/pull/19","diff_url":"https://github.com/boto/s3transfer/pull/19.diff","patch_url":"https://github.com/boto/s3transfer/pull/19.patch","issue_url":"https://api.github.com/repos/boto/s3transfer/issues/19","number":19,"state":"open","locked":false,"title":"Add TransferManagerController for Cntrl-C","user":{"login":"kyleknap","id":4605355,"avatar_url":"https://avatars.githubusercontent.com/u/4605355?v=3","gravatar_id":"","url":"https://api.github.com/users/kyleknap","html_url":"https://github.com/kyleknap","followers_url":"https://api.github.com/users/kyleknap/followers","following_url":"https://api.github.com/users/kyleknap/following{/other_user}","gists_url":"https://api.github.com/users/kyleknap/gists{/gist_id}","starred_url":"https://api.github.com/users/kyleknap/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/kyleknap/subscriptions","organizations_url":"https://api.github.com/users/kyleknap/orgs","repos_url":"https://api.github.com/users/kyleknap/repos","events_url":"https://api.github.com/users/kyleknap/events{/privacy}","received_events_url":"https://api.github.com/users/kyleknap/received_events","type":"User","site_admin":false},"body":"The abstraction serves the purpose of keeping track all in progress transfers such that:\r\n\r\n   * We can Cntrl-C for TransferFuture.result().\r\n\r\n   * Introduce a context handler on the TransferManager that wait for all\r\n     TransferFutures to complete, can be quickly cancel all TransferFutures\r\n     if encounters Cntrl-C, and can cancel all inprogress TransferFutures if\r\n     an exception is raised in the middle of the with statement as if there\r\n     is an exception the goal should be to exit as quickly and cleanly as\r\n     possible while still raising the exception hit.\r\n\r\n\r\nNote that Cntrl-C for uploads are still pretty slow. We will need to wrap the body that is sent with something that will interrupt the sending of the body.\r\n\r\n@jamesls @JordonPhillips ","created_at":"2016-06-29T00:21:40Z","updated_at":"2016-06-29T20:42:07Z","closed_at":null,"merged_at":null,"merge_commit_sha":"9c4f6f937f523bff9f8addba0924f30538fde676","assignee":null,"assignees":[],"milestone":null,"commits_url":"https://api.github.com/repos/boto/s3transfer/pulls/19/commits","review_comments_url":"https://api.github.com/repos/boto/s3transfer/pulls/19/comments","review_comment_url":"https://api.github.com/repos/boto/s3transfer/pulls/comments{/number}","comments_url":"https://api.github.com/repos/boto/s3transfer/issues/19/comments","statuses_url":"https://api.github.com/repos/boto/s3transfer/statuses/b8bb9bf20f954965564b24576ad055964c4bf00f","head":{"label":"kyleknap:canceler","ref":"canceler","sha":"b8bb9bf20f954965564b24576ad055964c4bf00f","user":{"login":"kyleknap","id":4605355,"avatar_url":"https://avatars.githubusercontent.com/u/4605355?v=3","gravatar_id":"","url":"https://api.github.com/users/kyleknap","html_url":"https://github.com/kyleknap","followers_url":"https://api.github.com/users/kyleknap/followers","following_url":"https://api.github.com/users/kyleknap/following{/other_user}","gists_url":"https://api.github.com/users/kyleknap/gists{/gist_id}","starred_url":"https://api.github.com/users/kyleknap/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/kyleknap/subscriptions","organizations_url":"https://api.github.com/users/kyleknap/orgs","repos_url":"https://api.github.com/users/kyleknap/repos","events_url":"https://api.github.com/users/kyleknap/events{/privacy}","received_events_url":"https://api.github.com/users/kyleknap/received_events","type":"User","site_admin":false},"repo":{"id":49536530,"name":"s3transfer","full_name":"kyleknap/s3transfer","owner":{"login":"kyleknap","id":4605355,"avatar_url":"https://avatars.githubusercontent.com/u/4605355?v=3","gravatar_id":"","url":"https://api.github.com/users/kyleknap","html_url":"https://github.com/kyleknap","followers_url":"https://api.github.com/users/kyleknap/followers","following_url":"https://api.github.com/users/kyleknap/following{/other_user}","gists_url":"https://api.github.com/users/kyleknap/gists{/gist_id}","starred_url":"https://api.github.com/users/kyleknap/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/kyleknap/subscriptions","organizations_url":"https://api.github.com/users/kyleknap/orgs","repos_url":"https://api.github.com/users/kyleknap/repos","events_url":"https://api.github.com/users/kyleknap/events{/privacy}","received_events_url":"https://api.github.com/users/kyleknap/received_events","type":"User","site_admin":false},"private":false,"html_url":"https://github.com/kyleknap/s3transfer","description":"[Experimental] Amazon S3 Transfer Manager for Python","fork":true,"url":"https://api.github.com/repos/kyleknap/s3transfer","forks_url":"https://api.github.com/repos/kyleknap/s3transfer/forks","keys_url":"https://api.github.com/repos/kyleknap/s3transfer/keys{/key_id}","collaborators_url":"https://api.github.com/repos/kyleknap/s3transfer/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/kyleknap/s3transfer/teams","hooks_url":"https://api.github.com/repos/kyleknap/s3transfer/hooks","issue_events_url":"https://api.github.com/repos/kyleknap/s3transfer/issues/events{/number}","events_url":"https://api.github.com/repos/kyleknap/s3transfer/events","assignees_url":"https://api.github.com/repos/kyleknap/s3transfer/assignees{/user}","branches_url":"https://api.github.com/repos/kyleknap/s3transfer/branches{/branch}","tags_url":"https://api.github.com/repos/kyleknap/s3transfer/tags","blobs_url":"https://api.github.com/repos/kyleknap/s3transfer/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/kyleknap/s3transfer/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/kyleknap/s3transfer/git/refs{/sha}","trees_url":"https://api.github.com/repos/kyleknap/s3transfer/git/trees{/sha}","statuses_url":"https://api.github.com/repos/kyleknap/s3transfer/statuses/{sha}","languages_url":"https://api.github.com/repos/kyleknap/s3transfer/languages","stargazers_url":"https://api.github.com/repos/kyleknap/s3transfer/stargazers","contributors_url":"https://api.github.com/repos/kyleknap/s3transfer/contributors","subscribers_url":"https://api.github.com/repos/kyleknap/s3transfer/subscribers","subscription_url":"https://api.github.com/repos/kyleknap/s3transfer/subscription","commits_url":"https://api.github.com/repos/kyleknap/s3transfer/commits{/sha}","git_commits_url":"https://api.github.com/repos/kyleknap/s3transfer/git/commits{/sha}","comments_url":"https://api.github.com/repos/kyleknap/s3transfer/comments{/number}","issue_comment_url":"https://api.github.com/repos/kyleknap/s3transfer/issues/comments{/number}","contents_url":"https://api.github.com/repos/kyleknap/s3transfer/contents/{+path}","compare_url":"https://api.github.com/repos/kyleknap/s3transfer/compare/{base}...{head}","merges_url":"https://api.github.com/repos/kyleknap/s3transfer/merges","archive_url":"https://api.github.com/repos/kyleknap/s3transfer/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/kyleknap/s3transfer/downloads","issues_url":"https://api.github.com/repos/kyleknap/s3transfer/issues{/number}","pulls_url":"https://api.github.com/repos/kyleknap/s3transfer/pulls{/number}","milestones_url":"https://api.github.com/repos/kyleknap/s3transfer/milestones{/number}","notifications_url":"https://api.github.com/repos/kyleknap/s3transfer/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/kyleknap/s3transfer/labels{/name}","releases_url":"https://api.github.com/repos/kyleknap/s3transfer/releases{/id}","deployments_url":"https://api.github.com/repos/kyleknap/s3transfer/deployments","created_at":"2016-01-12T23:50:28Z","updated_at":"2016-01-12T23:19:42Z","pushed_at":"2016-06-29T17:52:50Z","git_url":"git://github.com/kyleknap/s3transfer.git","ssh_url":"git@github.com:kyleknap/s3transfer.git","clone_url":"https://github.com/kyleknap/s3transfer.git","svn_url":"https://github.com/kyleknap/s3transfer","homepage":null,"size":226,"stargazers_count":0,"watchers_count":0,"language":null,"has_issues":false,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":0,"mirror_url":null,"open_issues_count":0,"forks":0,"open_issues":0,"watchers":0,"default_branch":"master"}},"base":{"label":"boto:develop","ref":"develop","sha":"6afd115d7b5b708405dea0031be1540cdc6304bb","user":{"login":"boto","id":327752,"avatar_url":"https://avatars.githubusercontent.com/u/327752?v=3","gravatar_id":"","url":"https://api.github.com/users/boto","html_url":"https://github.com/boto","followers_url":"https://api.github.com/users/boto/followers","following_url":"https://api.github.com/users/boto/following{/other_user}","gists_url":"https://api.github.com/users/boto/gists{/gist_id}","starred_url":"https://api.github.com/users/boto/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/boto/subscriptions","organizations_url":"https://api.github.com/users/boto/orgs","repos_url":"https://api.github.com/users/boto/repos","events_url":"https://api.github.com/users/boto/events{/privacy}","received_events_url":"https://api.github.com/users/boto/received_events","type":"Organization","site_admin":false},"repo":{"id":49535299,"name":"s3transfer","full_name":"boto/s3transfer","owner":{"login":"boto","id":327752,"avatar_url":"https://avatars.githubusercontent.com/u/327752?v=3","gravatar_id":"","url":"https://api.github.com/users/boto","html_url":"https://github.com/boto","followers_url":"https://api.github.com/users/boto/followers","following_url":"https://api.github.com/users/boto/following{/other_user}","gists_url":"https://api.github.com/users/boto/gists{/gist_id}","starred_url":"https://api.github.com/users/boto/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/boto/subscriptions","organizations_url":"https://api.github.com/users/boto/orgs","repos_url":"https://api.github.com/users/boto/repos","events_url":"https://api.github.com/users/boto/events{/privacy}","received_events_url":"https://api.github.com/users/boto/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/boto/s3transfer","description":"[Experimental] Amazon S3 Transfer Manager for Python","fork":false,"url":"https://api.github.com/repos/boto/s3transfer","forks_url":"https://api.github.com/repos/boto/s3transfer/forks","keys_url":"https://api.github.com/repos/boto/s3transfer/keys{/key_id}","collaborators_url":"https://api.github.com/repos/boto/s3transfer/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/boto/s3transfer/teams","hooks_url":"https://api.github.com/repos/boto/s3transfer/hooks","issue_events_url":"https://api.github.com/repos/boto/s3transfer/issues/events{/number}","events_url":"https://api.github.com/repos/boto/s3transfer/events","assignees_url":"https://api.github.com/repos/boto/s3transfer/assignees{/user}","branches_url":"https://api.github.com/repos/boto/s3transfer/branches{/branch}","tags_url":"https://api.github.com/repos/boto/s3transfer/tags","blobs_url":"https://api.github.com/repos/boto/s3transfer/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/boto/s3transfer/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/boto/s3transfer/git/refs{/sha}","trees_url":"https://api.github.com/repos/boto/s3transfer/git/trees{/sha}","statuses_url":"https://api.github.com/repos/boto/s3transfer/statuses/{sha}","languages_url":"https://api.github.com/repos/boto/s3transfer/languages","stargazers_url":"https://api.github.com/repos/boto/s3transfer/stargazers","contributors_url":"https://api.github.com/repos/boto/s3transfer/contributors","subscribers_url":"https://api.github.com/repos/boto/s3transfer/subscribers","subscription_url":"https://api.github.com/repos/boto/s3transfer/subscription","commits_url":"https://api.github.com/repos/boto/s3transfer/commits{/sha}","git_commits_url":"https://api.github.com/repos/boto/s3transfer/git/commits{/sha}","comments_url":"https://api.github.com/repos/boto/s3transfer/comments{/number}","issue_comment_url":"https://api.github.com/repos/boto/s3transfer/issues/comments{/number}","contents_url":"https://api.github.com/repos/boto/s3transfer/contents/{+path}","compare_url":"https://api.github.com/repos/boto/s3transfer/compare/{base}...{head}","merges_url":"https://api.github.com/repos/boto/s3transfer/merges","archive_url":"https://api.github.com/repos/boto/s3transfer/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/boto/s3transfer/downloads","issues_url":"https://api.github.com/repos/boto/s3transfer/issues{/number}","pulls_url":"https://api.github.com/repos/boto/s3transfer/pulls{/number}","milestones_url":"https://api.github.com/repos/boto/s3transfer/milestones{/number}","notifications_url":"https://api.github.com/repos/boto/s3transfer/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/boto/s3transfer/labels{/name}","releases_url":"https://api.github.com/repos/boto/s3transfer/releases{/id}","deployments_url":"https://api.github.com/repos/boto/s3transfer/deployments","created_at":"2016-01-12T23:19:42Z","updated_at":"2016-06-15T17:19:55Z","pushed_at":"2016-06-29T17:52:51Z","git_url":"git://github.com/boto/s3transfer.git","ssh_url":"git@github.com:boto/s3transfer.git","clone_url":"https://github.com/boto/s3transfer.git","svn_url":"https://github.com/boto/s3transfer","homepage":null,"size":204,"stargazers_count":7,"watchers_count":7,"language":"Python","has_issues":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":5,"mirror_url":null,"open_issues_count":3,"forks":5,"open_issues":3,"watchers":7,"default_branch":"develop"}},"_links":{"self":{"href":"https://api.github.com/repos/boto/s3transfer/pulls/19"},"html":{"href":"https://github.com/boto/s3transfer/pull/19"},"issue":{"href":"https://api.github.com/repos/boto/s3transfer/issues/19"},"comments":{"href":"https://api.github.com/repos/boto/s3transfer/issues/19/comments"},"review_comments":{"href":"https://api.github.com/repos/boto/s3transfer/pulls/19/comments"},"review_comment":{"href":"https://api.github.com/repos/boto/s3transfer/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/boto/s3transfer/pulls/19/commits"},"statuses":{"href":"https://api.github.com/repos/boto/s3transfer/statuses/b8bb9bf20f954965564b24576ad055964c4bf00f"}}}}
{"actor":{"display_login":"kyleknap"}}