登录

纪念一下非 channel 的 golang 内存队列,不推荐使用

Coding
2025-11-24 16:11:32

如果在 golang 中使用内存队列还是推荐使用 make(chan any,1024) 这种方式。纪念一下删除的代码,不推荐自己实现,如果有特殊需求的例外。

package memqueue

import (
	"errors"
	"sync"

	"gopt/app/arms/collectionopt"
	"gopt/app/arms/fileopt"
	"gopt/app/arms/jsonopt"
)

var queueLock = &sync.Mutex{}

var queueSaveLock = &sync.Mutex{}

var queueFilePath string

var queueList = make(map[string][]string)

func InitQueue(path string) {
	queueFilePath = path
	data, _ := fileopt.FileGetContents(queueFilePath)
	fileQueue := jsonopt.Decode[map[string][]string](string(data))
	if fileQueue != nil {
		queueList = fileQueue
	}
}

func saveQueueData() {
	if len(queueFilePath) == 0 {
		return
	}
	queueSaveLock.Lock()
	defer queueSaveLock.Unlock()
	fileopt.FilePutContents(queueFilePath, jsonopt.EncodeFormat(queueList))
}

func QueueRPush(key string, data ...string) {
	queueLock.Lock()
	defer queueLock.Unlock()
	queue, _ := queueList[key]
	queue = append(queue, data...)
	queueList[key] = queue
	saveQueueData()
}

func QueueLPop(key string) (string, error) {
	queueLock.Lock()
	defer queueLock.Unlock()
	queue, _ := queueList[key]
	if len(queue) > 0 {
		result := queue[0]
		queue = queue[1:]
		queueList[key] = queue
		saveQueueData()
		return result, nil
	}
	return "", errors.New("queue is null")
}

func QueueRPushObj[T any](key string, data ...T) {
	queueLock.Lock()
	defer queueLock.Unlock()
	queue, _ := queueList[key]
	strData := collectionopt.ArrayMap(func(t T) string {
		entity := jsonopt.Encode(t)
		return entity
	}, data)
	queue = append(queue, strData...)
	queueList[key] = queue
	saveQueueData()
}

func QueueLPopObj[t any](key string) (t, error) {
	queueLock.Lock()
	defer queueLock.Unlock()
	queue, _ := queueList[key]
	if len(queue) > 0 {
		result := queue[0]
		queue = queue[1:]
		queueList[key] = queue
		saveQueueData()
		return jsonopt.DecodeE[t](result)
	}
	var obj t
	return obj, errors.New("queue is null")
}

func QueueLen(key string) int {
	queueLock.Lock()
	defer queueLock.Unlock()
	queue, ok := queueList[key]
	if ok {
		return len(queue)
	}
	return 0
}

加入讨论

登录或注册以发表评论