Add SaveStateWithETag() convenience function (#321)

In the state API there's an existing DeleteStateWithETag() convenience
function but there does not appear to be an equivalent
SaveStateWithETag(). This commit adds SetStateWithETag() so that
consumers of the SDK don't have to employ the more verbose
SaveBulkState() when they only need to update a singular item.

Client code updating a single item with an etag prior to this commit
looks like:

--
item := &dapr.SetStateItem{
	Etag: &dapr.ETag{
		Value: "deadbeef",
	},
	Key:   "order_1",
	Value: []byte(data),
}

err := client.SaveBulkState(ctx, store, item)
--

Client code after this commit can reduce to:

--
err := client.SaveStateWithEtag(ctx, store, "order_1", []byte(data), "deadbeef")
--

Signed-off-by: Mike Brown <github@torvosoft.com>

Signed-off-by: Mike Brown <github@torvosoft.com>
This commit is contained in:
mikeb26 2022-09-28 16:47:33 +00:00 committed by GitHub
parent c1556a4bf1
commit c89770a473
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 14 additions and 17 deletions

View File

@ -90,6 +90,9 @@ type Client interface {
// SaveState saves the raw data into store using default state options.
SaveState(ctx context.Context, storeName, key string, data []byte, meta map[string]string, so ...StateOption) error
// SaveState saves the raw data into store using provided state options and etag.
SaveStateWithETag(ctx context.Context, storeName, key string, data []byte, etag string, meta map[string]string, so ...StateOption) error
// SaveBulkState saves multiple state item to store with specified options.
SaveBulkState(ctx context.Context, storeName string, items ...*SetStateItem) error

View File

@ -276,6 +276,11 @@ func (c *GRPCClient) ExecuteStateTransaction(ctx context.Context, storeName stri
// SaveState saves the raw data into store, default options: strong, last-write.
func (c *GRPCClient) SaveState(ctx context.Context, storeName, key string, data []byte, meta map[string]string, so ...StateOption) error {
return c.SaveStateWithETag(ctx, storeName, key, data, "", meta, so...)
}
// SaveStateWithETag saves the raw data into store using provided state options and etag.
func (c *GRPCClient) SaveStateWithETag(ctx context.Context, storeName, key string, data []byte, etag string, meta map[string]string, so ...StateOption) error {
stateOptions := new(StateOptions)
for _, o := range so {
o(stateOptions)
@ -289,6 +294,9 @@ func (c *GRPCClient) SaveState(ctx context.Context, storeName, key string, data
Metadata: meta,
Options: stateOptions,
}
if etag != "" {
item.Etag = &ETag{Value: etag}
}
return c.SaveBulkState(ctx, storeName, item)
}

View File

@ -86,14 +86,7 @@ func TestSaveState(t *testing.T) {
})
t.Run("save data with version", func(t *testing.T) {
item := &SetStateItem{
Etag: &ETag{
Value: "1",
},
Key: key,
Value: []byte(data),
}
err := testClient.SaveBulkState(ctx, store, item)
err := testClient.SaveStateWithETag(ctx, store, key, []byte(data), "1", nil)
assert.Nil(t, err)
})
@ -147,15 +140,8 @@ func TestDeleteState(t *testing.T) {
})
t.Run("save data again with etag, meta", func(t *testing.T) {
err := testClient.SaveBulkState(ctx, store, &SetStateItem{
Key: key,
Value: []byte(data),
Etag: &ETag{
Value: "1",
},
Metadata: map[string]string{"meta1": "value1"},
Options: &StateOptions{Concurrency: StateConcurrencyFirstWrite, Consistency: StateConsistencyEventual},
})
meta := map[string]string{"meta1": "value1"}
err := testClient.SaveStateWithETag(ctx, store, key, []byte(data), "1", meta, WithConsistency(StateConsistencyEventual), WithConcurrency(StateConcurrencyFirstWrite))
assert.Nil(t, err)
})
t.Run("confirm data saved", func(t *testing.T) {