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
© Allow specification reprint