我试图找出如何使用golang的RethinkDB更改源。
我的具体问题是如何阻止听取改变的goroutine
数据库。例如,请参阅下面的函数getData()
。我从一个处理程序运行它
通过调用go getData(c)
来发挥作用。每当数据库更新时,记录就是
传递给通道c
,然后传递给处理函数并发送到客户端
使用SSE技术。我的问题是:当客户端断开连接时,我知道如何停止和退出
处理函数;但是运行getData()
函数的goroutine仍在运行。什么可以
我要关闭它吗?基于stackoverflow的其他答案,我能想到的一个解决方案是
发送信号以关闭另一个通道上的goroutine并使用select语句来处理此问题
信号。例如,我可以替换
for cur.Next(&rec) {
c <- rec
}
在下面的函数定义中:
for cur.Next(&rec) {
select {
case <- closesignal:
return
default:
c <- rec
}
}
其中,closesignal
是作为getData()
的第三个参数给出的另一个通道
当客户端断开连接时,处理程序在此通道上发送消息。
这种方法的问题是:如果特定rethinkdb查询的结果怎么办?
从不更新。在这种情况下,将不会输入for cur.Next(&rec)
循环,并且不会使用closesignal
。
这个goroutine会继续运行吗?如果是这样,我该如何阻止这个goroutine?
getData()
功能
func getData(session *r.Session, c chan interface{}) {
var rec interface{}
changesOpts := r.ChangesOpts{
IncludeInitial: true,
}
cur, err := r.DB(DBNAME).Table("test").Changes(changesOpts).Run(session)
if err != nil {
log.Println(err)
return
}
defer cur.Close()
defer func() {
fmt.Println("exiting getData goroutine()...")
}()
for cur.Next(&rec) {
c <- rec
}
}
答案 0 :(得分:1)
您可以通过关闭光标来停止正在侦听更改源的goroutine。例如,此代码将在关闭之前收听更改请求10秒:
go func() {
time.Sleep(10 * time.Second)
cur.Close()
}()
for cur.Next(&rec) {
c <- rec
}
// Loop exits as the cursor has been closed
答案 1 :(得分:0)
您应通过context停止更改供稿。您可以将上下文传递给RunOpts
。这将立即关闭您的更改供稿。
答案 2 :(得分:0)
我认为处理这种情况的最好方法是使用contexts和goroutine来关闭光标。 这里有一些good documentation from the go blog关于上下文的信息。
这是带有上下文的实现示例:
func AreThereChanges(ctx context.Context) error {
cursor, err := r.Table("something").
Changes().
Run(db.Session)
if err != nil {
//manage error
}
go func(ctx context.Context) {
<-ctx.Done()
cursor.Close()
}(ctx)
var changeFeed map[string]interface{}
for cursor.Next(&changeFeed) {
if changeFeed["old_val"] != nil {
//do something
}
if changeFeed["new_val"] != nil {
//do something
}
}