关于scheduler代码实现的几个问题
来源:5-5 task示例的实现
Schwarzeni
2019-04-13
-
老师您在视频 5-5 15:29 左右的时候说重复读取要删除的文件没有关系,但是
func deleteVideo(vid string) error中删除本地文件出错是会有日志打印的,也就是可能会出现如下情况:
goroutine A 和 goroutine B 先后执行删除文件aaa的操作,但是B要删除aaa时A已经将aaa删除了,此时B就会打印错误日志说文件不存在。
这可能会对查看日志debug的人产生困惑,所以我觉得这个问题是必须要进行处理的 -
不论是将要删除视频的名称存入数据库,还是在
VideoClearExecutor中对其进行删除的时候都没有对其在磁盘是否存在做出判断,也没有将错误的数据从数据库中删除,这会导致定时任务每执行一次就会打印一次文件不存在的日志,我觉得这个也是不太严谨的 -
在问题VideoClearExcutor的实现是否会出现并发问题? 中老师您回答说
for是个阻塞的死循环,只有在下面break之后才会跳出, 但是我遇到了如下情况:
dc(data chan)只会送出一个数据,而且那个数据(也就是文件名),在磁盘上是不存在的,那么对如如下代码
forloop:
for {
select {
case vid := <-dc:
go func(id interface{}) {
if err := deleteVideo(id.(string)); err != nil {
errMap.Store(id, err)
return
}
if err := dbops.DelVideoDeletionRecord(id.(string)); err != nil {
errMap.Store(id, err)
return
}
}(vid)
default:
break forloop
}
}
在 case vid :=<- dc 启动一个goroutine后就会立刻完成一次循环到default,然后break掉,这样子就结束了for循环,但是此时那个goroutine中的逻辑还没执行完,也就那个goroutine中出现的所有错误都无法捕获了,所以errMap 此时是空的,也就是返回了 nil ,然后在 startDispatch() 那个for循环中的那段代码
if err := r.Executor(r.Data); err != nil {
r.Error <- CLOSE
} else {
r.Controller <- READY_TO_DISPATCH
}
就会执行 r.Controller <- READY_TO_DISPATCH,然后再启动一个VideoClearExecutor ,再次从数据库中读取那个在磁盘中不存在的文件名,这就导致了一个goroutine的死循环,然后每隔一段时间就会生成一个这样的死循环;我觉得这个问题是很严重的,必须进行同步
2回答
-
Quincy515
2019-09-26
请问,你是如何枷锁实现同步的?
00 -
慕尼黑9152544
2019-05-10
没事的 啊 不用都行的啊
00
相似问题