Skip to content

Add a cursor abstraction #1

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 7 commits into from
Closed

Add a cursor abstraction #1

wants to merge 7 commits into from

Conversation

jyemin
Copy link
Contributor

@jyemin jyemin commented Feb 8, 2017

Added a cursor abstraction to core. Some notes:

  • Works only with 3.2 and up, as it relies on the getMore and killCursors commands
  • Added some common types to command_types.go. We may not want to keep these, but I needed them for both the tests and examples so currently they are public.
  • The Cursor abstraction has the same API as mgo
  • There's a missing abstraction around connection management. Currently NewCursor is passed a Connection, which is used for iterating the cursor with getMore and closing it with killCursors. This is fine for our purposes, since we're going to be using a single connection per session, but once we add connection pooling to the client we'll need to do this differently so that a connection can be retrieved from a pool.
  • No tailable support

@@ -0,0 +1,19 @@
package core
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We have a results.go file these can go into. I'd probably also create a CursorResult interface that has 3 methods, NS(), ID(), and FirstBatch()

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

// The first batch of the cursor
FirstBatch []bson.Raw `bson:"firstBatch"`
// The namespace to use for iterating the cursor
NS string `bson:"ns"`
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's create that Namespace struct type.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

core/cursor.go Outdated
)

// Create a new cursor
func NewCursor(databaseName string, collectionName string, firstBatch []bson.Raw, cursorId int64, batchSize int32, connection Connection) Cursor {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Once you have a CursorResult interface, this should just be able to take that as an argument for the first 4 parameters.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

core/cursor.go Outdated
c.currentBatch = response.Cursor.NextBatch
}

type getMoreCommand struct {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't necessarily see these types getting used anywhere outside this particular file. It'd be nice to define these types right where they will be used inside the functions. In some cases, they could probably even be anonymous structs.

For example:

getMoreCommand := struct {
  CursorId   int64  `bson:"getMore"`
  Collection string `bson:"collection"`
  BatchSize  int32  `bson:"batchSize"`
} {
    CursorId:   c.cursorId,
    Collection: c.collectionName,
}

Same with the responses...

I could probably do this in other places too...

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

"testing"
)

const collectionName = "CursorTest"
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This collectionName variable is now available to all the things using the core_test package. Meaning, that this name is probably not what we want to be used in other packages that aren't testing cursors...

If we didn't use the same collection name for each test, we could add t.Parallel() to each of these.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done, though didn't make the tests parallel yet

core/cursor.go Outdated
currentBatch []bson.Raw
cursorId int64
err error
connection Connection // TODO: missing abstraction. Shouldn't require a connection here, but just a way to acquire and release one
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's have this take a Server instead...

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Deferred, as discussed

Copy link
Collaborator

@craiggwilson craiggwilson left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

lgtm. Little nits and fix the example, but push when you are ready.

log.Fatalf("Failed to execute command: %v", err)
}

cursor := core.NewCursor(databaseName, collectionName, response.Cursor.FirstBatch, response.Cursor.ID, 0, connection)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

seems like this isn't gonna work anymore.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

@@ -0,0 +1,199 @@
package core_test
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

since you are using different collections, might as well mark each with t.Parallel().

Also, might be nice to find a way to get the current method name from a stack trace, then use that for the collection name?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Marked as parallel. Leaving the current method name detection for another time.

"testing"
)

func TestEmpty(t *testing.T) {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe let's prefix each of these with what it's testing... TestCursor_Empty, TestCursor_Close, TestCursor_SingleBatch... etc...

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done, though without the underscore separator

Copy link
Collaborator

@craiggwilson craiggwilson left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

lgtm. 2 debug comments left in.

core/cursor.go Outdated
@@ -44,9 +45,11 @@ type cursorImpl struct {
func (c *cursorImpl) Next(result interface{}) bool {
found := c.getNextFromCurrentBatch(result)
if found {
fmt.Println("found")
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

debug?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

core/cursor.go Outdated
return true
}
if c.err != nil {
fmt.Printf("error: %v\n", c.err)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

debug?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

@jyemin
Copy link
Contributor Author

jyemin commented Feb 9, 2017

Rebasing and committing

@jyemin jyemin closed this Feb 9, 2017
skriptble pushed a commit that referenced this pull request Dec 6, 2018
edaniels referenced this pull request in edaniels/mongo-go-driver Feb 10, 2020
STITCH-4296: Export contextWithSession
edaniels referenced this pull request in mongodb-forks/mongo-go-driver Sep 1, 2020
GODRIVER-672 Change session IDs to be stored as bson.Raw (mongodb#339)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants