[英]How to stop a goroutine that is listening for RethinkDB changefeeds?
我想弄清楚如何在 golang 中使用 RethinkDB changefeeds。 我的具體問題是如何停止監聽數據庫更改的 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
}
}
您可以通過關閉光標來停止正在偵聽 changefeed 的 goroutine。 例如,此代碼將在關閉前偵聽 changefeed 10 秒:
go func() {
time.Sleep(10 * time.Second)
cur.Close()
}()
for cur.Next(&rec) {
c <- rec
}
// Loop exits as the cursor has been closed
您應該通過context停止 changefeed。 您可以將您的上下文傳遞給RunOpts
。 這將立即關閉您的更改源。
我認為管理這種情況的最好方法是使用上下文來關閉游標,使用 goroutine。 這里有一些來自 go 博客的關於上下文的好文檔。
這是帶有上下文的實現示例:
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
}
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.