private void nextTask(long offset, int retried, string upHost) { //上传中途触发停止 if (this.isCancelled()) { this.upCompletionHandler(this.key, ResponseInfo.cancelled(), null); return; } //所有分片已上传 if (offset == this.size) { this.makeFile(upHost, new CompletionHandler(delegate(ResponseInfo respInfo, string response) { //makeFile成功 if (respInfo.isOk()) { removeRecord(); Console.WriteLine("mkfile ok, upload done!"); this.upCompletionHandler(this.key, respInfo, response); return; } //失败重试,如果614,则不重试 if (respInfo.StatusCode != 614) { if (respInfo.needRetry() && retried < Config.RETRY_MAX) { Console.WriteLine("mkfile retrying due to {0}...", respInfo.StatusCode); string upHost2 = Config.ZONE.UploadHost; nextTask(offset, retried + 1, upHost2); return; } } Console.WriteLine("mkfile error, upload failed due to {0}", respInfo.StatusCode); this.upCompletionHandler(key, respInfo, response); })); return; } //创建块或上传分片 int chunkSize = calcBPutChunkSize(offset); ProgressHandler progressHandler = new ProgressHandler(delegate(long bytesWritten, long totalBytes) { double percent = (double)(offset) / this.size; Console.WriteLine("resumable upload progress {0}", percent); if (percent > 0.95) { percent = 0.95; } this.uploadOptions.ProgressHandler(this.key, percent); }); CompletionHandler completionHandler = new CompletionHandler(delegate(ResponseInfo respInfo, string response) { if (offset % Config.BLOCK_SIZE == 0) { Console.WriteLine("mkblk result {0}, offset {1}", respInfo.StatusCode, offset); } else { Console.WriteLine("bput result {0}, offset {1}", respInfo.StatusCode, offset); } if (!respInfo.isOk()) { //如果是701错误,为mkblk的ctx过期 if (respInfo.StatusCode == 701) { nextTask((offset / Config.BLOCK_SIZE) * Config.BLOCK_SIZE, retried, upHost); return; } if (retried >= Config.RETRY_MAX || !respInfo.needRetry()) { this.upCompletionHandler(key, respInfo, response); return; } String upHost2 = upHost; if (respInfo.needRetry()) { upHost2 = Config.ZONE.UploadHost; } nextTask(offset, retried + 1, upHost2); return; } //请求成功 string chunkContext = null; if (response == null || string.IsNullOrEmpty(response)) { nextTask(offset, retried + 1, upHost); return; } long chunkCrc32 = 0; Dictionary <string, string> respDict = JsonConvert.DeserializeObject <Dictionary <string, string> >(response); if (respDict.ContainsKey("ctx")) { chunkContext = respDict["ctx"]; } if (respDict.ContainsKey("crc32")) { chunkCrc32 = Convert.ToInt64(respDict["crc32"]); } if (chunkContext == null || chunkCrc32 != this.crc32) { nextTask(offset, retried + 1, upHost); return; } this.contexts[offset / Config.BLOCK_SIZE] = chunkContext; record(offset + chunkSize); nextTask(offset + chunkSize, retried, upHost); }); //创建块 if (offset % Config.BLOCK_SIZE == 0) { int blockSize = calcMakeBlockSize(offset); this.makeBlock(upHost, offset, blockSize, chunkSize, progressHandler, completionHandler); return; } //上传分片 string context = this.contexts[offset / Config.BLOCK_SIZE]; this.putChunk(upHost, offset, chunkSize, context, progressHandler, completionHandler); }
private void nextTask(long offset, int retried, string upHost) { //上传中途触发停止 if (this.isCancelled()) { this.upCompletionHandler(this.key, ResponseInfo.cancelled(), null); return; } //所有分片已上传 if (offset == this.size) { this.makeFile(upHost, new CompletionHandler(delegate(ResponseInfo respInfo, string response) { //makeFile成功 if (respInfo.isOk()) { removeRecord(); Console.WriteLine("mkfile ok, upload done!"); this.upCompletionHandler(this.key, respInfo, response); return; } //失败重试,如果614,则不重试 if (respInfo.StatusCode != 614) { if (respInfo.needRetry() && retried < Config.RETRY_MAX) { Console.WriteLine("mkfile retrying due to {0}...", respInfo.StatusCode); //string upHost2 = Config.ZONE.UploadHost; fileStream.Seek(offset, SeekOrigin.Begin); nextTask(offset, retried + 1, upHost); return; } } Console.WriteLine("mkfile error, upload failed due to {0}", respInfo.StatusCode); this.upCompletionHandler(key, respInfo, response); })); return; } //创建块或上传分片 int chunkSize = calcBPutChunkSize(offset); ProgressHandler progressHandler = new ProgressHandler(delegate(long bytesWritten, long totalBytes) { double percent = (double)(offset) / this.size; Console.WriteLine("resumable upload progress {0}", percent); // why 0.95 //if (percent > 0.95) //{ // percent = 0.95; //} this.uploadOptions.ProgressHandler(this.key, percent); }); CompletionHandler completionHandler = new CompletionHandler(delegate(ResponseInfo respInfo, string response) { if (offset % Config.BLOCK_SIZE == 0) { Console.WriteLine("mkblk result {0}, offset {1}", respInfo.StatusCode, offset); } else { Console.WriteLine("bput result {0}, offset {1}", respInfo.StatusCode, offset); } if (!respInfo.isOk()) { //如果是701错误,为mkblk的ctx过期 if (respInfo.StatusCode == 701) { Console.WriteLine("mkblk ctx is out of date, re-do upload"); offset = (offset / Config.BLOCK_SIZE) * Config.BLOCK_SIZE; fileStream.Seek(offset, SeekOrigin.Begin); nextTask(offset, retried, upHost); return; } if (retried >= Config.RETRY_MAX || !respInfo.needRetry()) { Console.WriteLine("retried " + retried + " times, all failed"); this.upCompletionHandler(key, respInfo, response); return; } // 下一个任务,使用uploadHost string uploadHost = upHost; if (respInfo.needRetry()) { Console.WriteLine(string.Format("upload-retry #{0}", retried + 1)); if (Config.RetryWaitForNext) { Console.WriteLine(string.Format("wait for {0} milisecond(s)", Config.RETRY_INTERVAL_MILISEC)); // 如果需要重试,并且设置了多次重试之间的时间间隔 System.Threading.Thread.Sleep(Config.RETRY_INTERVAL_MILISEC); } //// 交替使用两个域名重试 //if (retried % 2 != 0) //{ // uploadHost = Config.UploadFromCDN ? Config.ZONE.UploadHost : Config.ZONE.UpHost; //} //else //{ // uploadHost = Config.UploadFromCDN ? Config.ZONE.UpHost : Config.ZONE.UploadHost; //} } fileStream.Seek(offset, SeekOrigin.Begin); nextTask(offset, retried + 1, uploadHost); return; } //请求成功 string chunkContext = null; if (response == null || string.IsNullOrEmpty(response)) { fileStream.Seek(offset, SeekOrigin.Begin); nextTask(offset, retried + 1, upHost); return; } long chunkCrc32 = 0; Dictionary <string, string> respDict = JsonConvert.DeserializeObject <Dictionary <string, string> >(response); if (respDict.ContainsKey("ctx")) { chunkContext = respDict["ctx"]; } if (respDict.ContainsKey("crc32")) { chunkCrc32 = Convert.ToInt64(respDict["crc32"]); } //if(respDict.ContainsKey("host")) //{ // upHost = respDict["host"]; //} if (chunkContext == null || chunkCrc32 != this.crc32) { fileStream.Seek(offset, SeekOrigin.Begin); nextTask(offset, retried + 1, upHost); return; } this.contexts[offset / Config.BLOCK_SIZE] = chunkContext; record(offset + chunkSize); nextTask(offset + chunkSize, retried, upHost); }); //创建块 if (offset % Config.BLOCK_SIZE == 0) { int blockSize = calcMakeBlockSize(offset); this.makeBlock(upHost, offset, blockSize, chunkSize, progressHandler, completionHandler); return; } //上传分片 string context = this.contexts[offset / Config.BLOCK_SIZE]; this.putChunk(upHost, offset, chunkSize, context, progressHandler, completionHandler); }