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

added support for put-if-absent operations #1823

Merged
merged 2 commits into from
Apr 27, 2021
Merged

Conversation

ozkatz
Copy link
Collaborator

@ozkatz ozkatz commented Apr 27, 2021

No description provided.

@ozkatz ozkatz linked an issue Apr 27, 2021 that may be closed by this pull request
@ozkatz ozkatz added the area/API Improvements or additions to the API label Apr 27, 2021
@ozkatz ozkatz self-assigned this Apr 27, 2021
clients/python/lakefs_client/api/objects_api.py Outdated Show resolved Hide resolved
api/swagger.yml Outdated Show resolved Hide resolved
@@ -70,6 +70,12 @@ components:
application/json:
schema:
$ref: "#/components/schemas/Error"
PreconditionFailed:
Copy link
Contributor

Choose a reason for hiding this comment

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

note these are the docs

pkg/graveler/graveler.go Outdated Show resolved Hide resolved
pkg/graveler/graveler.go Outdated Show resolved Hide resolved
pkg/graveler/graveler.go Outdated Show resolved Hide resolved
pkg/graveler/graveler.go Outdated Show resolved Hide resolved
// before writing body, ensure preconditions - this means we essentially check for object existence twice:
// once before uploading the body to save resources and time,
// and then graveler will check again when passed a WriteCondition.
allowOverwrite := true
Copy link
Contributor

Choose a reason for hiding this comment

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

  1. Swagger validator should catch invalid value for IfNoneMatch - part of the JSON schema validation (if not ignore this comment)
  2. Why do we need to write code at this level to verify the existence and not just pass the boolean value to the underlying catalog? if WriteCondition members were public this will be easier to pass in this case.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

The idea is to test this specific condition outside of Graveler - why wait for the user to upload the body only to fail at CreateEntry if I already know this write is going to fail?

Copy link
Contributor

@johnnyaug johnnyaug left a comment

Choose a reason for hiding this comment

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

Nice!


t.Run("overwrite", func(t *testing.T) {
// write
contentType, buf := writeMultipart("content", "bar", "hello world!")
Copy link
Contributor

Choose a reason for hiding this comment

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

Since this is a separate test, you shouldn't count on the object from the previous test already being written. I would upload the object twice here.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Done

@@ -25,7 +25,7 @@ func TestSetGet(t *testing.T) {
t.Fatalf("error different than expected. expected=%v, got=%v", graveler.ErrNotFound, err)
}
value := newTestValue("identity1", "value1")
err = s.Set(ctx, "t1", []byte("a/b/c/"), value)
err = s.Set(ctx, "t1", []byte("a/b/c/"), value, true)
Copy link
Contributor

Choose a reason for hiding this comment

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

Can we add a case to this test with overwrite=false?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Done

@ozkatz ozkatz requested review from johnnyaug and nopcoder April 27, 2021 13:32
@ozkatz ozkatz merged commit 7e611ed into master Apr 27, 2021
@ozkatz ozkatz deleted the feature/put-if-absent branch April 27, 2021 15:29
Copy link
Contributor

@arielshaqed arielshaqed left a comment

Choose a reason for hiding this comment

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

Sorry for late review. Nice code, and a great indicator of where we can go with this!

We might want to tighten conditions on this: a write-only user can use conditional uploads to determine whether a file exists.

required: false
schema:
type: string
pattern: '^\*$' # Currently, only "*" is supported
Copy link
Contributor

Choose a reason for hiding this comment

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

@nopcoder I hope our generated clients don't validate. Otherwise when we add other values, an old client library won't work with an application that wants to use a non-* value.

@@ -1714,7 +1736,12 @@ func (c *Controller) UploadObject(w http.ResponseWriter, r *http.Request, reposi
Size: blob.Size,
Checksum: blob.Checksum,
}
err = c.Catalog.CreateEntry(ctx, repo.Name, branch, entry)

err = c.Catalog.CreateEntry(ctx, repo.Name, branch, entry, graveler.IfAbsent(!allowOverwrite))
Copy link
Contributor

Choose a reason for hiding this comment

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

Cool, double-checked locking actually works here! (The previous test is only an optimization, but still nice to know.)

@@ -671,7 +671,7 @@ func (c *Catalog) CreateEntry(ctx context.Context, repository string, branch str
if err != nil {
return err
}
return c.Store.Set(ctx, repositoryID, branchID, key, *value)
return c.Store.Set(ctx, repositoryID, branchID, key, *value, writeConditions...)
Copy link
Contributor

Choose a reason for hiding this comment

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

Style nit: no real reason to have varargs here, this API only ever gets generated slices (here on the server side). varargs now means we cannot varargs later, when we might really want it.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area/API Improvements or additions to the API
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Support PutIfAbsent in the lakeFS API
4 participants