diff --git a/dashboard/src/views/LogListView.vue b/dashboard/src/views/LogListView.vue index 8e4c411..1667d99 100644 --- a/dashboard/src/views/LogListView.vue +++ b/dashboard/src/views/LogListView.vue @@ -40,9 +40,9 @@ async function refreshFileList(): Promise { appLogs.push(f) continue } - const data = /^access\.(\d+)\.log(?:\.gz)?$/.exec(f.name) + const data = /^access(?:\.(\d+))?\.log(?:\.gz)?$/.exec(f.name) if (data) { - accessLogs.push({ n: Number.parseInt(data[1]), f: f }) + accessLogs.push({ n: data[1] ? Number.parseInt(data[1]) : 0, f: f }) continue } otherLogs.push(f) diff --git a/lang/en/us.go b/lang/en/us.go index 33309a6..b836f76 100644 --- a/lang/en/us.go +++ b/lang/en/us.go @@ -65,6 +65,7 @@ var areaUS = map[string]string{ "info.sync.none": "All files were synchronized", "warn.sync.interrupted": "File sync interrupted", "info.sync.config": "Sync config: %#v", + "error.sync.part.working": "Only %d out of %d storages are working! Sync will begin in a minute", "hint.sync.total": "Total: ", "hint.sync.downloading": "> Downloading ", "hint.sync.downloading.handler": "Downloading %s from handler", diff --git a/lang/zh/cn.go b/lang/zh/cn.go index a016356..ed16e39 100644 --- a/lang/zh/cn.go +++ b/lang/zh/cn.go @@ -65,6 +65,7 @@ var areaCN = map[string]string{ "info.sync.none": "所有文件已同步", "warn.sync.interrupted": "同步已中断", "info.sync.config": "同步配置: %#v", + "error.sync.part.working": "仅有 %d / %d 个存储工作正常! 同步将在1分钟内开始", "hint.sync.total": "总计: ", "hint.sync.downloading": "> 下载中 ", "hint.sync.downloading.handler": "Downloading %s from handler", diff --git a/storage/storage_webdav.go b/storage/storage_webdav.go index 35db4d8..2cff835 100644 --- a/storage/storage_webdav.go +++ b/storage/storage_webdav.go @@ -129,7 +129,7 @@ type WebDavStorage struct { httpCli *http.Client noRedCli *http.Client // no redirect client - measures utils.SyncMap[int, struct{}] + measures *utils.SyncMap[int, struct{}] working atomic.Int32 checkMux sync.RWMutex lastCheck time.Time @@ -196,6 +196,7 @@ func (s *WebDavStorage) Init(ctx context.Context) (err error) { return } + s.measures = utils.NewSyncMap[int, struct{}]() if err := s.cli.Mkdir("measure", 0755); err != nil { if !webdavIsHTTPError(err, http.StatusConflict) { log.Warnf("Cannot create measure folder for %s: %v", s.String(), err) diff --git a/sync.go b/sync.go index 37104bc..ea4ed60 100644 --- a/sync.go +++ b/sync.go @@ -529,6 +529,9 @@ func (cr *Cluster) syncFiles(ctx context.Context, files []FileInfo, heavyCheck b err := s.CheckUpload(tctx) cancel() if err != nil { + if err := ctx.Err(); err != nil { + return err + } aliveStorages-- log.Errorf("Storage %s does not work: %v", s.String(), err) } @@ -538,6 +541,14 @@ func (cr *Cluster) syncFiles(ctx context.Context, files []FileInfo, heavyCheck b log.Errorf(Tr("error.sync.failed"), err) return err } + if aliveStorages < len(cr.storages) { + log.Errorf(Tr("error.sync.part.working"), aliveStorages < len(cr.storages)) + select { + case <-time.After(time.Minute): + case <-ctx.Done(): + return ctx.Err() + } + } for _, f := range missing { log.Debugf("File %s is for %v", f.Hash, f.targets)