Example #1
0
        /// <summary>
        ///     创建块(携带首片数据),同时检查CRC32
        /// </summary>
        /// <param name="resumeBlockerObj">创建分片上次的块请求</param>
        private async Task MakeBlock(object resumeBlockerObj)
        {
            var resumeBlocker    = (ResumeBlocker)resumeBlockerObj;
            var doneEvent        = resumeBlocker.DoneEvent;
            var blockMakeResults = resumeBlocker.BlockMakeResults;
            var putExtra         = resumeBlocker.PutExtra;
            var blockIndex       = resumeBlocker.BlockIndex;
            var result           = new HttpResult();

            //check whether to cancel
            while (true)
            {
                var upCtl = resumeBlocker.PutExtra.UploadController();
                if (upCtl == UploadControllerAction.Suspended)
                {
                    doneEvent.WaitOne(1000);
                }
                else if (upCtl == UploadControllerAction.Aborted)
                {
                    doneEvent.Set();

                    result.Code     = (int)HttpCode.USER_CANCELED;
                    result.RefCode  = (int)HttpCode.USER_CANCELED;
                    result.RefText += $"[{DateTime.Now:yyyy-MM-dd HH:mm:ss.ffff}] [ResumableUpload] Info: upload task is aborted, mkblk {blockIndex}\n";
                    blockMakeResults.Add(blockIndex, result);
                    return;
                }
                else
                {
                    break;
                }
            }

            var blockBuffer = resumeBlocker.BlockBuffer;
            var blockSize   = blockBuffer.Length;

            var upToken           = resumeBlocker.UploadToken;
            var uploadedBytesDict = resumeBlocker.UploadedBytesDict;
            var fileSize          = resumeBlocker.FileSize;
            var progressLock      = resumeBlocker.ProgressLock;
            var resumeInfo        = resumeBlocker.ResumeInfo;

            try
            {
                //get upload host
                var ak     = UpToken.GetAccessKeyFromUpToken(upToken);
                var bucket = UpToken.GetBucketFromUpToken(upToken);
                if (ak == null || bucket == null)
                {
                    result = HttpResult.InvalidToken;
                    doneEvent.Set();
                    return;
                }

                var uploadHost = await _config.UpHost(ak, bucket);

                var url        = $"{uploadHost}/mkblk/{blockSize}";
                var upTokenStr = $"UpToken {upToken}";
                using (var ms = new MemoryStream(blockBuffer, 0, blockSize))
                {
                    var data = ms.ToArray();

                    result = await _httpManager.PostDataAsync(url, data, token : upTokenStr);

                    if (result.Code == (int)HttpCode.OK)
                    {
                        var rc = JsonConvert.DeserializeObject <ResumeContext>(result.Text);

                        if (rc.Crc32 > 0)
                        {
                            var crc1 = rc.Crc32;
                            var crc2 = Crc32.CheckSumSlice(blockBuffer, 0, blockSize);
                            if (crc1 != crc2)
                            {
                                result.RefCode  = (int)HttpCode.USER_NEED_RETRY;
                                result.RefText += $" CRC32: remote={crc1}, local={crc2}\n";
                            }
                            else
                            {
                                //write the mkblk context
                                resumeInfo.Contexts[blockIndex] = rc.Ctx;
                                resumeInfo.ExpiredAt            = rc.ExpiredAt;
                                lock (progressLock)
                                {
                                    uploadedBytesDict["UploadProgress"] += blockSize;
                                }

                                putExtra.ProgressHandler(uploadedBytesDict["UploadProgress"], fileSize);
                            }
                        }
                        else
                        {
                            result.RefText += $"[{DateTime.Now:yyyy-MM-dd HH:mm:ss.ffff}] JSON Decode Error: text = {result.Text}";
                            result.RefCode  = (int)HttpCode.USER_NEED_RETRY;
                        }
                    }
                    else
                    {
                        result.RefCode = (int)HttpCode.USER_NEED_RETRY;
                    }
                }
            }
            catch (Exception ex)
            {
                var sb = new StringBuilder();
                sb.Append($"[{DateTime.Now:yyyy-MM-dd HH:mm:ss.ffff}] mkblk Error: ");
                var e = ex;
                while (e != null)
                {
                    sb.Append(e.Message + " ");
                    e = e.InnerException;
                }

                sb.AppendLine();

                if (ex is QiniuException qex)
                {
                    result.Code     = qex.HttpResult.Code;
                    result.RefCode  = qex.HttpResult.Code;
                    result.Text     = qex.HttpResult.Text;
                    result.RefText += sb.ToString();
                }
                else
                {
                    result.RefCode  = (int)HttpCode.USER_UNDEF;
                    result.RefText += sb.ToString();
                }
            }

            //return the http result
            blockMakeResults.Add(blockIndex, result);
            doneEvent.Set();
        }