예제 #1
0
        public static async Task <StatusFile> GetStatusFile(S3Helper s3h, SyncTarget st, long minTimestamp, long maxTimestamp)
        {
            var bkp    = st.status.ToBucketKeyPair();
            var prefix = $"{bkp.key}/{UploadStatusFilePrefix}";
            var list   = await GetStatusList(s3h, st, UploadStatusFilePrefix);

            if (list.IsNullOrEmpty())
            {
                return(null);
            }

            list.Reverse();
            foreach (var f in list) //find non obsolete files
            {
                var timestamp = f.Key.TrimStart(prefix).TrimEnd(".json").ToLongOrDefault(0);

                if (timestamp < minTimestamp || timestamp > maxTimestamp)
                {
                    continue;
                }

                var s = await s3h.DownloadJsonAsync <StatusFile>(bkp.bucket, f.Key, throwIfNotFound : false)
                        .Timeout(msTimeout: st.timeout)
                        .TryCatchRetryAsync(maxRepeats: st.retry);

                if (s?.finalized == true)
                {
                    return(s);
                }
            }

            return(null);
        }
예제 #2
0
        public static async Task <StatusFile> GetStatusFile(S3Helper s3h, SyncTarget st, string statusPrefix)
        {
            var bkp    = st.status.ToBucketKeyPair();
            var prefix = $"{bkp.key}/{statusPrefix}";
            var list   = await GetStatusList(s3h, st, statusPrefix);

            var id = list.IsNullOrEmpty() ? 0 : list.Last().Key.TrimStart(prefix).TrimEnd(".json").ToLongOrDefault(0); //latest staus id

            id = id <= 0 ? DateTimeEx.TimestampNow() : id;
            var key = $"{prefix}{id}.json";

            if (list.IsNullOrEmpty() || id <= 0)
            {
                return(new StatusFile()
                {
                    id = id.ToString(),
                    timestamp = DateTimeEx.UnixTimestampNow(),
                    bucket = bkp.bucket,
                    key = key,
                    location = $"{bkp.bucket}/{key}",
                    finalized = false,
                    version = 0
                });
            }

            var status = await s3h.DownloadJsonAsync <StatusFile>(bkp.bucket, key, throwIfNotFound : true)
                         .Timeout(msTimeout: st.timeout)
                         .TryCatchRetryAsync(maxRepeats: st.retry);

            var elapsed = (DateTime.UtcNow - long.Parse(status?.id ?? "0").ToDateTimeFromTimestamp()).TotalSeconds;

            if (status == null || (status.finalized == true && st.retention > 0 && elapsed > st.retention))
            {
                id     = DateTimeEx.TimestampNow();
                key    = $"{prefix}{id}.json";
                status = new Models.StatusFile()
                {
                    id        = id.ToString(),
                    timestamp = DateTimeEx.UnixTimestampNow(),
                    bucket    = bkp.bucket,
                    key       = key,
                    location  = $"{bkp.bucket}/{key}",
                    finalized = false,
                    version   = 0
                };
            }

            if (st.cleanup && st.rotation > 0 && list.Count > st.rotation)
            {
                var validStatus = new List <StatusFile>();
                list.Reverse();
                foreach (var f in list) //find non obsolete files
                {
                    var s = await s3h.DownloadJsonAsync <StatusFile>(bkp.bucket, f.Key, throwIfNotFound : false)
                            .Timeout(msTimeout: st.timeout)
                            .TryCatchRetryAsync(maxRepeats: st.retry);

                    if (s == null)
                    {
                        continue;
                    }

                    if (s.finalized && s.id.ToLongOrDefault(0) > 0)
                    {
                        validStatus.Add(s);
                    }
                    else if (!s.finalized || status.id == id.ToString())
                    {
                        validStatus.Add(s);
                    }

                    if (validStatus.Count > st.rotation)
                    {
                        break;
                    }
                }

                status.obsoletes = list.Where(x => !validStatus.Any(v => v.key.ToLower().Trim() == x.Key.ToLower().Trim()))
                                   .Select(x => x.Key).ToArray(); //status files that are obsolete
            }

            return(status);
        }