singledo - 單例執行

概述

singledo 模組確保操作只執行一次,防止重複計算或執行。

類型

Single[T]

泛型單例執行器。

type Single[T any] struct {
    mux    sync.Mutex
    last   time.Time
    wait   time.Duration
    call   *call[T]
    result T
}

構造函數

NewSingleT

創建新的單例執行器。

func NewSingle[T any](wait time.Duration) *Single[T]

參數:

  • wait - 允許重新執行前的等待時間

返回:

  • 單例執行器實例

示例:

single := singledo.NewSingle[string](time.Minute)

方法

Do()

使用單例保證執行函數。

func (s *Single[T]) Do(fn func() (T, error)) (v T, err error)

參數:

  • fn - 要執行的函數

返回:

  • 函數的結果
  • 函數的錯誤

行為:

  • 如果在等待時間內,返回緩存結果
  • 否則,執行函數並緩存結果

示例:

single := singledo.NewSingle[string](time.Minute)

result, err := single.Do(func() (string, error) {
    log.Info("Executing expensive operation...")
    
    data, err := fetchExpensiveData()
    if err != nil {
        return "", err
    }
    
    return data, nil
})

if err != nil {
    log.Errorf("Operation failed: %v", err)
} else {
    log.Infof("Result: %s", result)
}

Reset()

重置單例執行器。

func (s *Single[T]) Reset()

示例:

single.Reset()

使用模式

昂貴計算

var calculationSingle = singledo.NewSingle[int64](time.Hour)

func getExpensiveResult() (int64, error) {
    return calculationSingle.Do(func() (int64, error) {
        log.Info("Performing expensive calculation...")
        
        result, err := performExpensiveCalculation()
        if err != nil {
            return 0, err
        }
        
        return result, nil
    })
}

數據加載

var dataLoaderSingle = singledo.NewSingle[[]byte](5 * time.Minute)

func loadData() ([]byte, error) {
    return dataLoaderSingle.Do(func() ([]byte, error) {
        log.Info("Loading data from remote...")
        
        data, err := http.Get("https://api.example.com/data")
        if err != nil {
            return nil, err
        }
        
        return data, nil
    })
}

配置加載

var configSingle = singledo.NewSingle[Config](time.Hour)

func getConfig() (*Config, error) {
    return configSingle.Do(func() (*Config, error) {
        log.Info("Loading configuration...")
        
        cfg, err := loadConfiguration()
        if err != nil {
            return nil, err
        }
        
        return cfg, nil
    })
}

最佳實踐

等待時間

// 好的做法: 使用適當的等待時間
var shortCache = singledo.NewSingle[string](time.Minute)      // 1 分鐘
var mediumCache = singledo.NewSingle[string](time.Hour)      // 1 小時
var longCache = singledo.NewSingle[string](24 * time.Hour) // 24 小時

錯誤處理

// 好的做法: 正確處理錯誤
result, err := single.Do(func() (string, error) {
    data, err := fetchData()
    if err != nil {
        return "", err
    }
    
    return processData(data), nil
})

if err != nil {
    log.Errorf("Operation failed: %v", err)
} else {
    log.Infof("Result: %s", result)
}

相關文檔