{"action":"created","comment":{"url":"https://api.github.com/repos/Icenium/icenium-cli/pulls/comments/23002395","id":23002395,"diff_hunk":"@@ -39,29 +41,42 @@ export class MultipartUploadService implements IMultipartUploadService {\n \t\t\t\t}\n \n \t\t\t\tvar chunkStream = this.$fs.createReadStream(filePath, { start: chunkStartByte, end: endByte });\n-\t\t\t\t// Fibers crash in case we start multiple uploads simultaneously, so wait for each future.\n-\t\t\t\tthis.uploadChunk(bucketKey, chunkStartByte, endByte, chunkStream, fileSize).wait();\n+\t\t\t\tvar future = this.uploadChunk(bucketKey, chunkStartByte, endByte, chunkStream, fileSize);\n+\t\t\t\tfutures.push(future);\n \t\t\t\tchunkStartByte = endByte;\n \t\t\t}\n+\t\t\tthis.waitForFutures(futures).wait();\n+\n \t\t\tvar fileHash = this.$hashService.getFileHash(filePath, MultipartUploadService.INPUT_FILE_ENCODING, MultipartUploadService.HASH_ALGORITHM, MultipartUploadService.HASH_ENCODING).wait();\n+\n \t\t\tthis.$server.upload.completeUpload(bucketKey, fileHash).wait();\n \t\t}).future<void>()();\n \t}\n \n-\tprivate uploadChunk(path: string, startingIndex: number, endIndex: number, content: ReadableStream, fileSize: number): IFuture<void> {\n+\tprivate waitForFutures(futures: IFuture<void>[]): IFuture<void> {\n \t\treturn (() => {\n-\t\t\tvar headers = {\n-\t\t\t\t\"Content-Range\": util.format(\"bytes %d-%d/%s\", startingIndex, endIndex - 1, fileSize),\n-\t\t\t\t\"Content-Length\": endIndex - startingIndex\n-\t\t\t};\n-\n-\t\t\tthis.$logger.trace(\"Uploading chunk with Content-Range: %s\", headers[\"Content-Range\"]);\n+\t\t\tvar currentFuts: IFuture<void>[] = [];\n+\t\t\twhile(futures.length > 0) {\n+\t\t\t\twhile(futures.length > 0 && currentFuts.length < MultipartUploadService.MAX_CONCURRENT_FUTURES) {","path":"lib/services/multipart-upload.ts","position":45,"original_position":45,"commit_id":"fed4869677180034c7ed4b16d5d7c2bce429e69f","original_commit_id":"fed4869677180034c7ed4b16d5d7c2bce429e69f","user":{"login":"teobugslayer","id":5443453,"avatar_url":"https://avatars.githubusercontent.com/u/5443453?v=3","gravatar_id":"","url":"https://api.github.com/users/teobugslayer","html_url":"https://github.com/teobugslayer","followers_url":"https://api.github.com/users/teobugslayer/followers","following_url":"https://api.github.com/users/teobugslayer/following{/other_user}","gists_url":"https://api.github.com/users/teobugslayer/gists{/gist_id}","starred_url":"https://api.github.com/users/teobugslayer/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/teobugslayer/subscriptions","organizations_url":"https://api.github.com/users/teobugslayer/orgs","repos_url":"https://api.github.com/users/teobugslayer/repos","events_url":"https://api.github.com/users/teobugslayer/events{/privacy}","received_events_url":"https://api.github.com/users/teobugslayer/received_events","type":"User","site_admin":false},"body":"Why MAX_CONCURRENT_FUTURES instead of, say, MAX_CONCURRENT_UPLOADS?","created_at":"2015-01-15T10:54:42Z","updated_at":"2015-01-15T10:54:42Z","html_url":"https://github.com/Icenium/icenium-cli/pull/670#discussion_r23002395","pull_request_url":"https://api.github.com/repos/Icenium/icenium-cli/pulls/670","_links":{"self":{"href":"https://api.github.com/repos/Icenium/icenium-cli/pulls/comments/23002395"},"html":{"href":"https://github.com/Icenium/icenium-cli/pull/670#discussion_r23002395"},"pull_request":{"href":"https://api.github.com/repos/Icenium/icenium-cli/pulls/670"}}},"pull_request":{"url":"https://api.github.com/repos/Icenium/icenium-cli/pulls/670","id":27411396,"html_url":"https://github.com/Icenium/icenium-cli/pull/670","diff_url":"https://github.com/Icenium/icenium-cli/pull/670.diff","patch_url":"https://github.com/Icenium/icenium-cli/pull/670.patch","issue_url":"https://api.github.com/repos/Icenium/icenium-cli/issues/670","number":670,"state":"open","locked":false,"title":"Async chunk upload","user":{"login":"rosen-vladimirov","id":8351653,"avatar_url":"https://avatars.githubusercontent.com/u/8351653?v=3","gravatar_id":"","url":"https://api.github.com/users/rosen-vladimirov","html_url":"https://github.com/rosen-vladimirov","followers_url":"https://api.github.com/users/rosen-vladimirov/followers","following_url":"https://api.github.com/users/rosen-vladimirov/following{/other_user}","gists_url":"https://api.github.com/users/rosen-vladimirov/gists{/gist_id}","starred_url":"https://api.github.com/users/rosen-vladimirov/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/rosen-vladimirov/subscriptions","organizations_url":"https://api.github.com/users/rosen-vladimirov/orgs","repos_url":"https://api.github.com/users/rosen-vladimirov/repos","events_url":"https://api.github.com/users/rosen-vladimirov/events{/privacy}","received_events_url":"https://api.github.com/users/rosen-vladimirov/received_events","type":"User","site_admin":false},"body":"Upload multiple chunks simultaneously. Add maximum of simultaneously working futures (set to 3).\r\n\r\nhttp://teampulse.telerik.com/view#item/283781","created_at":"2015-01-15T07:56:01Z","updated_at":"2015-01-15T10:54:42Z","closed_at":null,"merged_at":null,"merge_commit_sha":"0ca8252c758cc8e62fbb92f1ab5b3e74f4da49bb","assignee":{"login":"rosen-vladimirov","id":8351653,"avatar_url":"https://avatars.githubusercontent.com/u/8351653?v=3","gravatar_id":"","url":"https://api.github.com/users/rosen-vladimirov","html_url":"https://github.com/rosen-vladimirov","followers_url":"https://api.github.com/users/rosen-vladimirov/followers","following_url":"https://api.github.com/users/rosen-vladimirov/following{/other_user}","gists_url":"https://api.github.com/users/rosen-vladimirov/gists{/gist_id}","starred_url":"https://api.github.com/users/rosen-vladimirov/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/rosen-vladimirov/subscriptions","organizations_url":"https://api.github.com/users/rosen-vladimirov/orgs","repos_url":"https://api.github.com/users/rosen-vladimirov/repos","events_url":"https://api.github.com/users/rosen-vladimirov/events{/privacy}","received_events_url":"https://api.github.com/users/rosen-vladimirov/received_events","type":"User","site_admin":false},"milestone":{"url":"https://api.github.com/repos/Icenium/icenium-cli/milestones/4","labels_url":"https://api.github.com/repos/Icenium/icenium-cli/milestones/4/labels","id":895514,"number":4,"title":"2.8.0","description":"","creator":{"login":"teobugslayer","id":5443453,"avatar_url":"https://avatars.githubusercontent.com/u/5443453?v=3","gravatar_id":"","url":"https://api.github.com/users/teobugslayer","html_url":"https://github.com/teobugslayer","followers_url":"https://api.github.com/users/teobugslayer/followers","following_url":"https://api.github.com/users/teobugslayer/following{/other_user}","gists_url":"https://api.github.com/users/teobugslayer/gists{/gist_id}","starred_url":"https://api.github.com/users/teobugslayer/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/teobugslayer/subscriptions","organizations_url":"https://api.github.com/users/teobugslayer/orgs","repos_url":"https://api.github.com/users/teobugslayer/repos","events_url":"https://api.github.com/users/teobugslayer/events{/privacy}","received_events_url":"https://api.github.com/users/teobugslayer/received_events","type":"User","site_admin":false},"open_issues":2,"closed_issues":20,"state":"open","created_at":"2014-12-08T10:45:20Z","updated_at":"2015-01-15T10:06:47Z","due_on":"2015-01-31T22:00:00Z","closed_at":null},"commits_url":"https://api.github.com/repos/Icenium/icenium-cli/pulls/670/commits","review_comments_url":"https://api.github.com/repos/Icenium/icenium-cli/pulls/670/comments","review_comment_url":"https://api.github.com/repos/Icenium/icenium-cli/pulls/comments/{number}","comments_url":"https://api.github.com/repos/Icenium/icenium-cli/issues/670/comments","statuses_url":"https://api.github.com/repos/Icenium/icenium-cli/statuses/fed4869677180034c7ed4b16d5d7c2bce429e69f","head":{"label":"Icenium:vladimirov/async-file-chunk-upload","ref":"vladimirov/async-file-chunk-upload","sha":"fed4869677180034c7ed4b16d5d7c2bce429e69f","user":{"login":"Icenium","id":1152554,"avatar_url":"https://avatars.githubusercontent.com/u/1152554?v=3","gravatar_id":"","url":"https://api.github.com/users/Icenium","html_url":"https://github.com/Icenium","followers_url":"https://api.github.com/users/Icenium/followers","following_url":"https://api.github.com/users/Icenium/following{/other_user}","gists_url":"https://api.github.com/users/Icenium/gists{/gist_id}","starred_url":"https://api.github.com/users/Icenium/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/Icenium/subscriptions","organizations_url":"https://api.github.com/users/Icenium/orgs","repos_url":"https://api.github.com/users/Icenium/repos","events_url":"https://api.github.com/users/Icenium/events{/privacy}","received_events_url":"https://api.github.com/users/Icenium/received_events","type":"Organization","site_admin":false},"repo":{"id":14398834,"name":"icenium-cli","full_name":"Icenium/icenium-cli","owner":{"login":"Icenium","id":1152554,"avatar_url":"https://avatars.githubusercontent.com/u/1152554?v=3","gravatar_id":"","url":"https://api.github.com/users/Icenium","html_url":"https://github.com/Icenium","followers_url":"https://api.github.com/users/Icenium/followers","following_url":"https://api.github.com/users/Icenium/following{/other_user}","gists_url":"https://api.github.com/users/Icenium/gists{/gist_id}","starred_url":"https://api.github.com/users/Icenium/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/Icenium/subscriptions","organizations_url":"https://api.github.com/users/Icenium/orgs","repos_url":"https://api.github.com/users/Icenium/repos","events_url":"https://api.github.com/users/Icenium/events{/privacy}","received_events_url":"https://api.github.com/users/Icenium/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/Icenium/icenium-cli","description":"Cross Platform Command Line Interface for Telerik AppBuilder","fork":false,"url":"https://api.github.com/repos/Icenium/icenium-cli","forks_url":"https://api.github.com/repos/Icenium/icenium-cli/forks","keys_url":"https://api.github.com/repos/Icenium/icenium-cli/keys{/key_id}","collaborators_url":"https://api.github.com/repos/Icenium/icenium-cli/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/Icenium/icenium-cli/teams","hooks_url":"https://api.github.com/repos/Icenium/icenium-cli/hooks","issue_events_url":"https://api.github.com/repos/Icenium/icenium-cli/issues/events{/number}","events_url":"https://api.github.com/repos/Icenium/icenium-cli/events","assignees_url":"https://api.github.com/repos/Icenium/icenium-cli/assignees{/user}","branches_url":"https://api.github.com/repos/Icenium/icenium-cli/branches{/branch}","tags_url":"https://api.github.com/repos/Icenium/icenium-cli/tags","blobs_url":"https://api.github.com/repos/Icenium/icenium-cli/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/Icenium/icenium-cli/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/Icenium/icenium-cli/git/refs{/sha}","trees_url":"https://api.github.com/repos/Icenium/icenium-cli/git/trees{/sha}","statuses_url":"https://api.github.com/repos/Icenium/icenium-cli/statuses/{sha}","languages_url":"https://api.github.com/repos/Icenium/icenium-cli/languages","stargazers_url":"https://api.github.com/repos/Icenium/icenium-cli/stargazers","contributors_url":"https://api.github.com/repos/Icenium/icenium-cli/contributors","subscribers_url":"https://api.github.com/repos/Icenium/icenium-cli/subscribers","subscription_url":"https://api.github.com/repos/Icenium/icenium-cli/subscription","commits_url":"https://api.github.com/repos/Icenium/icenium-cli/commits{/sha}","git_commits_url":"https://api.github.com/repos/Icenium/icenium-cli/git/commits{/sha}","comments_url":"https://api.github.com/repos/Icenium/icenium-cli/comments{/number}","issue_comment_url":"https://api.github.com/repos/Icenium/icenium-cli/issues/comments/{number}","contents_url":"https://api.github.com/repos/Icenium/icenium-cli/contents/{+path}","compare_url":"https://api.github.com/repos/Icenium/icenium-cli/compare/{base}...{head}","merges_url":"https://api.github.com/repos/Icenium/icenium-cli/merges","archive_url":"https://api.github.com/repos/Icenium/icenium-cli/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/Icenium/icenium-cli/downloads","issues_url":"https://api.github.com/repos/Icenium/icenium-cli/issues{/number}","pulls_url":"https://api.github.com/repos/Icenium/icenium-cli/pulls{/number}","milestones_url":"https://api.github.com/repos/Icenium/icenium-cli/milestones{/number}","notifications_url":"https://api.github.com/repos/Icenium/icenium-cli/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/Icenium/icenium-cli/labels{/name}","releases_url":"https://api.github.com/repos/Icenium/icenium-cli/releases{/id}","created_at":"2013-11-14T15:27:18Z","updated_at":"2015-01-14T15:57:02Z","pushed_at":"2015-01-15T07:51:55Z","git_url":"git://github.com/Icenium/icenium-cli.git","ssh_url":"git@github.com:Icenium/icenium-cli.git","clone_url":"https://github.com/Icenium/icenium-cli.git","svn_url":"https://github.com/Icenium/icenium-cli","homepage":"","size":34931,"stargazers_count":15,"watchers_count":15,"language":"TypeScript","has_issues":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":3,"mirror_url":null,"open_issues_count":7,"forks":3,"open_issues":7,"watchers":15,"default_branch":"master"}},"base":{"label":"Icenium:master","ref":"master","sha":"f2b4fc9cd9598a08a5b1a3f96c491b3af11234a7","user":{"login":"Icenium","id":1152554,"avatar_url":"https://avatars.githubusercontent.com/u/1152554?v=3","gravatar_id":"","url":"https://api.github.com/users/Icenium","html_url":"https://github.com/Icenium","followers_url":"https://api.github.com/users/Icenium/followers","following_url":"https://api.github.com/users/Icenium/following{/other_user}","gists_url":"https://api.github.com/users/Icenium/gists{/gist_id}","starred_url":"https://api.github.com/users/Icenium/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/Icenium/subscriptions","organizations_url":"https://api.github.com/users/Icenium/orgs","repos_url":"https://api.github.com/users/Icenium/repos","events_url":"https://api.github.com/users/Icenium/events{/privacy}","received_events_url":"https://api.github.com/users/Icenium/received_events","type":"Organization","site_admin":false},"repo":{"id":14398834,"name":"icenium-cli","full_name":"Icenium/icenium-cli","owner":{"login":"Icenium","id":1152554,"avatar_url":"https://avatars.githubusercontent.com/u/1152554?v=3","gravatar_id":"","url":"https://api.github.com/users/Icenium","html_url":"https://github.com/Icenium","followers_url":"https://api.github.com/users/Icenium/followers","following_url":"https://api.github.com/users/Icenium/following{/other_user}","gists_url":"https://api.github.com/users/Icenium/gists{/gist_id}","starred_url":"https://api.github.com/users/Icenium/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/Icenium/subscriptions","organizations_url":"https://api.github.com/users/Icenium/orgs","repos_url":"https://api.github.com/users/Icenium/repos","events_url":"https://api.github.com/users/Icenium/events{/privacy}","received_events_url":"https://api.github.com/users/Icenium/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/Icenium/icenium-cli","description":"Cross Platform Command Line Interface for Telerik AppBuilder","fork":false,"url":"https://api.github.com/repos/Icenium/icenium-cli","forks_url":"https://api.github.com/repos/Icenium/icenium-cli/forks","keys_url":"https://api.github.com/repos/Icenium/icenium-cli/keys{/key_id}","collaborators_url":"https://api.github.com/repos/Icenium/icenium-cli/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/Icenium/icenium-cli/teams","hooks_url":"https://api.github.com/repos/Icenium/icenium-cli/hooks","issue_events_url":"https://api.github.com/repos/Icenium/icenium-cli/issues/events{/number}","events_url":"https://api.github.com/repos/Icenium/icenium-cli/events","assignees_url":"https://api.github.com/repos/Icenium/icenium-cli/assignees{/user}","branches_url":"https://api.github.com/repos/Icenium/icenium-cli/branches{/branch}","tags_url":"https://api.github.com/repos/Icenium/icenium-cli/tags","blobs_url":"https://api.github.com/repos/Icenium/icenium-cli/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/Icenium/icenium-cli/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/Icenium/icenium-cli/git/refs{/sha}","trees_url":"https://api.github.com/repos/Icenium/icenium-cli/git/trees{/sha}","statuses_url":"https://api.github.com/repos/Icenium/icenium-cli/statuses/{sha}","languages_url":"https://api.github.com/repos/Icenium/icenium-cli/languages","stargazers_url":"https://api.github.com/repos/Icenium/icenium-cli/stargazers","contributors_url":"https://api.github.com/repos/Icenium/icenium-cli/contributors","subscribers_url":"https://api.github.com/repos/Icenium/icenium-cli/subscribers","subscription_url":"https://api.github.com/repos/Icenium/icenium-cli/subscription","commits_url":"https://api.github.com/repos/Icenium/icenium-cli/commits{/sha}","git_commits_url":"https://api.github.com/repos/Icenium/icenium-cli/git/commits{/sha}","comments_url":"https://api.github.com/repos/Icenium/icenium-cli/comments{/number}","issue_comment_url":"https://api.github.com/repos/Icenium/icenium-cli/issues/comments/{number}","contents_url":"https://api.github.com/repos/Icenium/icenium-cli/contents/{+path}","compare_url":"https://api.github.com/repos/Icenium/icenium-cli/compare/{base}...{head}","merges_url":"https://api.github.com/repos/Icenium/icenium-cli/merges","archive_url":"https://api.github.com/repos/Icenium/icenium-cli/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/Icenium/icenium-cli/downloads","issues_url":"https://api.github.com/repos/Icenium/icenium-cli/issues{/number}","pulls_url":"https://api.github.com/repos/Icenium/icenium-cli/pulls{/number}","milestones_url":"https://api.github.com/repos/Icenium/icenium-cli/milestones{/number}","notifications_url":"https://api.github.com/repos/Icenium/icenium-cli/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/Icenium/icenium-cli/labels{/name}","releases_url":"https://api.github.com/repos/Icenium/icenium-cli/releases{/id}","created_at":"2013-11-14T15:27:18Z","updated_at":"2015-01-14T15:57:02Z","pushed_at":"2015-01-15T07:51:55Z","git_url":"git://github.com/Icenium/icenium-cli.git","ssh_url":"git@github.com:Icenium/icenium-cli.git","clone_url":"https://github.com/Icenium/icenium-cli.git","svn_url":"https://github.com/Icenium/icenium-cli","homepage":"","size":34931,"stargazers_count":15,"watchers_count":15,"language":"TypeScript","has_issues":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":3,"mirror_url":null,"open_issues_count":7,"forks":3,"open_issues":7,"watchers":15,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/Icenium/icenium-cli/pulls/670"},"html":{"href":"https://github.com/Icenium/icenium-cli/pull/670"},"issue":{"href":"https://api.github.com/repos/Icenium/icenium-cli/issues/670"},"comments":{"href":"https://api.github.com/repos/Icenium/icenium-cli/issues/670/comments"},"review_comments":{"href":"https://api.github.com/repos/Icenium/icenium-cli/pulls/670/comments"},"review_comment":{"href":"https://api.github.com/repos/Icenium/icenium-cli/pulls/comments/{number}"},"commits":{"href":"https://api.github.com/repos/Icenium/icenium-cli/pulls/670/commits"},"statuses":{"href":"https://api.github.com/repos/Icenium/icenium-cli/statuses/fed4869677180034c7ed4b16d5d7c2bce429e69f"}}}}