我有两个goroutines:
添加和清除可能不会同时进行。
如果任务状态为成功,我想从队列中删除任务,否则,我将重试状态为成功(有时间限制)。如果失败,我将记录日志并从队列中删除。
我们无法在添加和删除之间进行通信,因为这不是现实情况下的工作方式。
我想要一个监视程序,它监视队列中的添加并进行以下清理。为了增加复杂性,即使在清除过程中也可能添加Add(此处未显示)。我想在不使用外部程序包的情况下实现它。
我该如何实现?
type Task struct {
name string
status string //completed, failed
}
var list []*Task
func main() {
done := make(chan bool)
go Add()
time.Sleep(15)
go clean(done)
<-done
}
func Add() {
t1 := &Task{"test1", "completed"}
t2 := &Task{"test2", "failed"}
list = append(list, t1, t2)
}
func clean() {
for k, v := range list {
if v.status == "completed" {
RemoveIndex(list, k)
} else {
//for now consider this as retry
v.status == "completed"
}
if len(list) > 0 {
clean()
}
<-done
}
}
func RemoveIndex(s []int, index int) []int {
return append(s[:index], s[index+1:]...)
}
最佳答案
所以我找到了一个对我有用的解决方案,并将其发布在这里对可能有用的任何人。
在我的主要工作中,我添加了一个行情自动收录器,它每隔x秒运行一次,以查看队列中是否添加了某些内容。
type Task struct {
name string
status string //completed, failed
}
var list []*Task
func main() {
done := make(chan bool)
c := make(chan os.Signal, 2)
go Add()
go func() {
for {
select {
// case <-done:
// Cleaner(k)
case <-ticker.C:
Monitor(done)
}
}
}()
signal.Notify(c, os.Interrupt, syscall.SIGTERM)
<-c
//waiting for interrupt here
}
func Add() {
t1 := &Task{"test1", "completed"}
t2 := &Task{"test2", "failed"}
list = append(list, t1, t2)
}
func Monitor(done chan bool) {
if len(list) > 0 {
Cleaner()
}
}
func cleaner(){
//do cleaning here
// pop each element from queue and delete
}
func RemoveIndex(s []int, index int) []int {
return append(s[:index], s[index+1:]...)
}
因此,现在该解决方案无需依赖go例程之间的通信,在现实世界中,该程序永远不会消失,并且会根据用例进行添加和清除。您可以通过在添加队列和从队列中删除之前进行锁定和解锁来更好地进行优化。
关于go - 注意包含结构的队列中的更改,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/65523276/