Files
OpenFlare/internal/apps/upload/storage/access_state.go
T
ryan 63cd906cfc refactor(repo): consolidate openflare-server to root and move subprojects to internal/apps
- Merge all files inside openflare-server to the repository root directory.
- Relocate agent, relay, and flared subprojects from internal/ to internal/apps/.
- Combine docker-compose files and update build context paths to root.
- Update GitHub workflows and Dockerfiles to refer to new directories and package names.
- Rewrite Go package imports across all files.
- Resolve database renew test race condition and clean up docs.
2026-06-19 14:23:29 +08:00

89 lines
2.3 KiB
Go

// Copyright 2026 Arctel.net
// SPDX-License-Identifier: Apache-2.0
// Package storage provides upload storage backend operations and migration state.
package storage
import (
"context"
"sync"
"time"
"github.com/Rain-kl/Wavelet/internal/apps/upload/shared"
"github.com/Rain-kl/Wavelet/internal/model"
"github.com/Rain-kl/Wavelet/internal/storage"
)
// MigrationAccessState captures cached migration maintenance state.
type MigrationAccessState struct {
ReadOnly bool
Target storage.Config
HasTarget bool
TargetErr error
LoadErr error
}
var (
migrationAccessMu sync.RWMutex
migrationAccessCached MigrationAccessState
migrationAccessValid bool
migrationAccessCheckedAt time.Time
)
// ResetMigrationAccessCache clears the in-process migration access cache.
func ResetMigrationAccessCache() {
migrationAccessMu.Lock()
migrationAccessValid = false
migrationAccessMu.Unlock()
}
// LoadMigrationAccessState returns cached migration maintenance state.
func LoadMigrationAccessState(ctx context.Context) MigrationAccessState {
migrationAccessMu.RLock()
if migrationAccessValid && time.Since(migrationAccessCheckedAt) < time.Duration(shared.AccessCacheTTL)*time.Second {
state := migrationAccessCached
migrationAccessMu.RUnlock()
return state
}
migrationAccessMu.RUnlock()
migrationAccessMu.Lock()
defer migrationAccessMu.Unlock()
if migrationAccessValid && time.Since(migrationAccessCheckedAt) < time.Duration(shared.AccessCacheTTL)*time.Second {
return migrationAccessCached
}
migrationAccessCached = buildMigrationAccessState(ctx)
migrationAccessValid = true
migrationAccessCheckedAt = time.Now()
return migrationAccessCached
}
func buildMigrationAccessState(ctx context.Context) MigrationAccessState {
execution, ok, err := LatestMigrationExecution(ctx)
if err != nil {
return MigrationAccessState{LoadErr: err, ReadOnly: true}
}
if !ok {
return MigrationAccessState{}
}
state := MigrationAccessState{
ReadOnly: execution.Status != model.TaskExecutionStatusSucceeded,
}
if execution.Status == model.TaskExecutionStatusSucceeded {
return state
}
target, err := ParseMigrationTargetConfig(ctx, []byte(execution.Payload))
if err != nil {
state.TargetErr = err
return state
}
state.Target = target
state.HasTarget = true
return state
}