我有一个redis列表,可以用作队列。我将元素推向左侧,然后从右侧弹出,将来自不同用户的请求推入队列。我有一个goroutine池,它们从队列(POP)中读取请求并对其进行处理。我希望一次只能处理每个userId一个请求。我有一个永久运行的ReadRequest()函数,它会弹出具有userId的请求。我需要按照用户进入的顺序处理每个用户的请求。我不确定如何实现此请求。我需要每个用户ID的Redis列表吗?如果是这样,我将如何遍历所有处理请求的列表?
for i:=0; i< 5; i++{
wg.Add(1)
go ReadRequest(&wg)
}
func ReadRequest(){
for{
//redis pop request off list
request:=MyRedisPop()
fmt.Println(request.UserId)
// only call Process if no other goroutine is processing a request for this user
Process(request)
time.sleep(100000)
}
wg.Done()
}
答案 0 :(得分:1)
这是您可以在不创建多个Redis列表的情况下使用的伪代码:
// maintain a global map for all users
// if you see a new user, call NewPerUser() and add it to the list
// Then, send the request to the corresponding channel for processing
var userMap map[string]PerUser
type PerUser struct {
chan<- redis.Request // Whatever is the request type
semaphore *semaphore.Weighted // Semaphore to limit concurrent processing
}
func NewPerUser() *PerUser {
ch := make(chan redis.Request)
s := semaphore.NewWeighted(1) // One 1 concurrent request is allowed
go func(){
for req := range ch {
s.Acquire(context.Background(), 1)
defer s.Release(1)
// Process the request here
}
}()
}
请注意,这只是一个伪代码,我尚未测试它是否有效。