Skip to content
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

fix(bigtable): Track number of readrows to set rowsLimit in subsequent requests #10213

Open
wants to merge 7 commits into
base: main
Choose a base branch
from

Conversation

bhshkh
Copy link
Contributor

@bhshkh bhshkh commented May 16, 2024

Tracking bug: b/303943537

This PR fixes TestReadRows_NoRetry_ErrorAfterLastRow test

https://github.com/googleapis/cloud-bigtable-clients-test/blob/db4d6a9e8e5e38b6f07383bd46ac14bfc8d8b9b6/tests/readrows_test.go#L171-L173

fails with error:

--- FAIL: TestReadRows_NoRetry_ErrorAfterLastRow (0.03s)
    readrows_test.go:201: 
        	Error Trace:	cloud-bigtable-clients-test/tests/readrows_test.go:201
        	Error:      	Not equal: 
        	            	expected: 1
        	            	actual  : 2
        	Test:       	TestReadRows_NoRetry_ErrorAfterLastRow
--- FAIL: TestReadRows_Retry_LastScannedRow_Reverse (0.04s)

The test sends below request to Go Bigtable proxy:

Request: &btpb.ReadRowsRequest{
	TableName: buildTableName("table"),
	RowsLimit: 1,
},

On receiving the request, the proxy creates a ReadRows request for the client library and invokes ReadRows function.
Even though test sends RowsLimit field in the method, the proxy does not add it to the client library request. This has been fixed in this PR.

@product-auto-label product-auto-label bot added the api: bigtable Issues related to the Bigtable API. label May 16, 2024
@codyoss
Copy link
Member

codyoss commented Dec 10, 2024

@bhshkh is this still wanted/needed?

@bhshkh bhshkh changed the title test(bigtable): test(bigtable): Fix conformance test TestReadRows_NoRetry_ErrorAfterLastRow Dec 11, 2024
@bhshkh
Copy link
Contributor Author

bhshkh commented Dec 11, 2024

@bhshkh is this still wanted/needed?

Yes

@bhshkh bhshkh marked this pull request as ready for review December 11, 2024 19:32
@bhshkh bhshkh requested review from a team as code owners December 11, 2024 19:32
@bhshkh bhshkh changed the title test(bigtable): Fix conformance test TestReadRows_NoRetry_ErrorAfterLastRow fix(bigtable): Track number of readrows to set rowsLimit in subsequent requests Jan 13, 2025
@bhshkh bhshkh requested review from mutianf and gkevinzheng January 13, 2025 22:23
for _, opt := range opts {
if l, ok := opt.(limitRows); ok {
rowLimitSet = true
intialRowLimit = l.limit
Copy link
Contributor

Choose a reason for hiding this comment

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

Maybe fail fast on l.limit < 0

err = gaxInvokeWithRecorder(ctx, mt, "ReadRows", func(ctx context.Context, headerMD, trailerMD *metadata.MD, _ gax.CallSettings) error {
if rowLimitSet && numRowsRead == intialRowLimit {
Copy link
Contributor

Choose a reason for hiding this comment

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

Should we add a safety check in case numRowsRead > initialRowLimit as an extra safety measure against bugs down the stream?

}

func makeReadSettings(req *btpb.ReadRowsRequest) readSettings {
return readSettings{req, nil}
func makeReadSettings(req *btpb.ReadRowsRequest, numRowsRead int64) readSettings {
Copy link
Contributor

Choose a reason for hiding this comment

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

NIT: it took me a while to understand how makeReadSettings works with readSettings.set. Maybe add a one line comment either here or on the read execution itself explaining

@@ -965,7 +982,9 @@ func LimitRows(limit int64) ReadOption { return limitRows{limit} }

type limitRows struct{ limit int64 }

func (lr limitRows) set(settings *readSettings) { settings.req.RowsLimit = lr.limit }
func (lr limitRows) set(settings *readSettings) {
settings.req.RowsLimit = lr.limit - settings.numRowsRead
Copy link
Contributor

Choose a reason for hiding this comment

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

Maybe add a comment explaining the reasoning for this subtraction

err = gaxInvokeWithRecorder(ctx, mt, "ReadRows", func(ctx context.Context, headerMD, trailerMD *metadata.MD, _ gax.CallSettings) error {
if rowLimitSet && numRowsRead == intialRowLimit {
return nil
Copy link
Contributor

Choose a reason for hiding this comment

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

If the number of rows requested (initialRowLimit) is higher than the total number of rows we will eventually receive, am I correct to assume that the block if err == io.EOF { would break us out of the loop?

If so, can we add a test with this scenario? (e.g. a table with 2 rows and set rowLimit = 5)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
api: bigtable Issues related to the Bigtable API.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants