Пример #1
0
        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);
        }
Пример #2
0
        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);
        }