Uploaded image for project: 'Go Driver'
  1. Go Driver
  2. GODRIVER-648

Collection usage sometimes leads to CursorNotFound

    • Type: Icon: Task Task
    • Resolution: Works as Designed
    • Priority: Icon: Major - P3 Major - P3
    • None
    • Affects Version/s: 0.0.18
    • None

      After moving from `mgo` to `mongo-go-driver` we started facing CursorNotFound errors when getting documents on one collection:

      (CursorNotFound) Cursor not found (namespace: 'arbiter_stage.memberships', id: 2282861465586709065).
      

      Here is the code used to search documents (error is triggered from cursor.Err() check):

      // FindAll - simple method for reading multiple documents into array
      func (coll Collection) FindAll(ctx context.Context, query interface{}, result interface{}, opts ...*options.FindOptions) error {
      	opts = append(opts, options.Find().SetNoCursorTimeout(true))
      
      	var err error
      
      	// Based on .All() method in go-mgo https://github.com/globalsign/mgo/blob/master/session.go#L4428
      	resultv := reflect.ValueOf(result)
      	if resultv.Kind() != reflect.Ptr {
      		panic("result argument must be a slice address")
      	}
      
      	slicev := resultv.Elem()
      
      	if slicev.Kind() == reflect.Interface {
      		slicev = slicev.Elem()
      	}
      	if slicev.Kind() != reflect.Slice {
      		panic("result argument must be a slice address")
      	}
      
      	cursor, err := coll.Find(ctx, query, opts...)
      	if err != nil {
      		return err
      	}
      	defer cursor.Close(ctx)
      
      	slicev = slicev.Slice(0, slicev.Cap())
      	elemt := slicev.Type().Elem()
      	i := 0
      	for cursor.Next(ctx) {
      		if slicev.Len() == i {
      			// If we went beyound slice capacity, we need to reallocate slice
      			elemp := reflect.New(elemt)
      			err = cursor.Decode(elemp.Interface())
      			if err != nil {
      				return err
      			}
      			slicev = reflect.Append(slicev, elemp.Elem())
      			slicev = slicev.Slice(0, slicev.Cap())
      		} else {
      			// In case we inside slice capacity, we can just overwrite value at index i
      			err = cursor.Decode(slicev.Index(i).Addr().Interface())
      			if err != nil {
      				return err
      			}
      		}
      		i++
      	}
      	// Overwrite original result value with new one
      	resultv.Elem().Set(slicev.Slice(0, i))
      
      	if err := cursor.Err(); err != nil {
      		return err
      	}
      
      	return nil
      }
      

       

      After the error happens it continues appearing and stops after a certain amount of time.

      We noticed that error goes away after restarting the docker container with go code.

       

      Driver version:

      0.0.18 ( dbffb1c211bf96fbd721b4bd6911331e5c1886ab )

       

      Go version:

      go version go1.11 linux/amd64

      mongos version:

      mongos version v3.6.9
      git version: 167861a164723168adfaaa866f310cb94010428f
      OpenSSL version: OpenSSL 1.1.0f  25 May 2017
      allocator: tcmalloc
      modules: none
      build environment:
          distmod: debian92
          distarch: x86_64
          target_arch: x86_64
      

            Assignee:
            jeff.yemin@mongodb.com Jeffrey Yemin
            Reporter:
            istrel Ivan Strelkov
            Votes:
            1 Vote for this issue
            Watchers:
            4 Start watching this issue

              Created:
              Updated:
              Resolved: