[GODRIVER-1202] Panic when Change Stream is closed Created: 22/Jul/19  Updated: 31/Jul/19  Resolved: 29/Jul/19

Status: Closed
Project: Go Driver
Component/s: CRUD
Affects Version/s: 1.0.4
Fix Version/s: None

Type: Bug Priority: Major - P3
Reporter: Joël Gähwiler Assignee: Emmanuel Eppinger (Inactive)
Resolution: Done Votes: 0
Labels: None
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified


 Description   

The following code, that opens a change stream and closes it while the iterator is waiting for an event, panics on master:
 

package main
 
import (
   "context"
   "fmt"
   "time"
 
   "go.mongodb.org/mongo-driver/bson"
   "go.mongodb.org/mongo-driver/mongo"
   "go.mongodb.org/mongo-driver/mongo/options"
)
 
func main() {
   opts := options.Client().ApplyURI("mongodb://0.0.0.0/issue")
 
   client, err := mongo.Connect(nil, opts)
   if err != nil {
      panic(err)
   }
 
   db := client.Database("issue")
 
   cs, err := db.Collection("foo").Watch(context.Background(), []bson.M{}, options.ChangeStream())
   if err != nil {
      panic(err)
   }
   defer cs.Close(nil)
 
   go func() {
      time.Sleep(time.Second)
      cs.Close(nil)
   }()
 
   for cs.Next(context.Background()) {
      fmt.Println(cs.Current)
   }
}

 

panic: runtime error: invalid memory address or nil pointer dereference
[signal SIGSEGV: segmentation violation code=0x1 addr=0x28 pc=0x13ae12d]
 
goroutine 1 [running]:
go.mongodb.org/mongo-driver/mongo.(*ChangeStream).loopNext(0xc000102960, 0x15d08c0, 0xc0000a6008)
	/Users/256dpi/Development/Go/pkg/mod/go.mongodb.org/mongo-driver@v1.0.1-0.20190712184055-9ec4480161a7/mongo/change_stream.go:452 +0x15d
go.mongodb.org/mongo-driver/mongo.(*ChangeStream).Next(0xc000102960, 0x15d08c0, 0xc0000a6008, 0x0)
	/Users/256dpi/Development/Go/pkg/mod/go.mongodb.org/mongo-driver@v1.0.1-0.20190712184055-9ec4480161a7/mongo/change_stream.go:420 +0x151
main.main()
	/Users/256dpi/Development/GitHub/256dpi/fire/spark/issue/main.go:34 +0x35c



 Comments   
Comment by Divjot Arora (Inactive) [ 31/Jul/19 ]

joel.gaehwiler@gmail.com Our cursors and change streams are not thread-safe. The purpose of close is to actually close the cursor on the server via the killCursors command so the server does not use extra resources. Because the change stream Close method closes the underlying batch cursor, calling Close while concurrently doing an operation will likely cause a panic or data race in the batch cursor code.

Comment by Joël Gähwiler [ 30/Jul/19 ]

I realized that and updated my code accordingly already. The bug report was more about the panic. IMHO calling the Close() method should not crash the program and either return an error or also work as a method to close the change stream. If not, why having a Close method at all? The only way to close the change steam properly would then be anyway to cancel the context and not call Close...?

Comment by Emmanuel Eppinger (Inactive) [ 29/Jul/19 ]

Hi Joël,

 

So this is not a supported use case of change streams. I imagine that you are looking to close a change stream after 1 second. If you are looking to do that you can provide a context with a timeout or that is able to be canceled when calling Watch.

 

Thanks

Emmanuel  

Generated at Thu Feb 08 08:35:54 UTC 2024 using Jira 9.7.1#970001-sha1:2222b88b221c4928ef0de3161136cc90c8356a66.