package main

import (
    "context"
    "fmt"
    "github.com/sirupsen/logrus"
    "math/rand"
    "slices"
    "sync"
    "time"
)

type CustomFormatter struct{}

func (f *CustomFormatter) Format(entry *logrus.Entry) ([]byte, error) {
    timestamp := time.Now().Format("2006-01-02 15:04:05,000")
    msg := fmt.Sprintf("[%s] [%s] %s\n", entry.Level.String(), timestamp, entry.Message)
    return []byte(msg), nil
}

func main() {
    //初始化日志格式
    log := logrus.New()
    log.SetReportCaller(true)
    log.SetFormatter(&CustomFormatter{})

    //初始化当前数量和chan
    var counter int
    do := make(chan struct{})
    //设置总数和时间范围
    const increments = 100
    const duration = time.Minute * 5

    //执行计数
    go func() {
        defer func() {
            if r := recover(); r != nil {
                log.Errorf("panic: %s", r)
            }
        }()

        var mu sync.Mutex
        timer := time.NewTimer(time.Hour)
        for {
            select {
            case <-do:
                mu.Lock()
                counter++
                log.Infof("%s %d", time.Now().Format(time.DateTime), counter)
                if counter >= increments {
                    mu.Unlock()
                    goto EXIT
                }
                mu.Unlock()
            //超时退出
            case <-timer.C:
                goto EXIT
            }
        }
    EXIT:
    }()

    //随机间隔 按时间排序
    rand.Seed(time.Now().UnixNano())
    totalMilliseconds := int64(duration / time.Millisecond)
    doTimes := make([]uint64, increments)
    for i := 0; i < increments; i++ {
        delay := time.Duration(rand.Int63n(totalMilliseconds)) * time.Millisecond
        doTimes[i] = uint64(delay.Nanoseconds())
    }
    slices.Sort(doTimes)

    now := time.Now()
    for {
        log.Println(now.Add(time.Duration(doTimes[0])).Format(time.DateTime))
        deadline, cancelFunc := context.WithDeadline(context.Background(), now.Add(time.Duration(doTimes[0])))
        //到时间执行计数
        <-deadline.Done()
        do <- struct{}{}
        if len(doTimes) == 1 {
            cancelFunc()
            return
        }
        doTimes = doTimes[1:]
        cancelFunc()
    }
}
Last modification:May 28, 2024
如果觉得我的文章对你有用,请收藏本站