mirror of https://github.com/dapr/docs.git
Update statestore ETag/actor support (#1213)
* Update statestore ETag/actor support Add additional column to the supporte statestore table that indicates direct support of ETag usage. Also specify that transactional stores support actors. https://github.com/dapr/docs/issues/1199 * Add ETag example in statestore API reference This commit adds a walkthrough of how to work with ETags including finding them and using them for updates and deletes. * Update _index.md * Update state_api.md Co-authored-by: Mark Fussell <mfussell@microsoft.com> Co-authored-by: Yaron Schneider <yaronsc@microsoft.com>
This commit is contained in:
parent
778ebf9b9d
commit
de42e45f01
|
@ -26,13 +26,7 @@ Actors can save state reliably using state management capability.
|
|||
|
||||
You can interact with Dapr through HTTP/gRPC endpoints for state management.
|
||||
|
||||
To use actors, your state store must support multi-item transactions. This means your state store [component](https://github.com/dapr/components-contrib/tree/master/state) must implement the [TransactionalStore](https://github.com/dapr/components-contrib/blob/master/state/transactional_store.go) interface. The following state stores implement this interface:
|
||||
|
||||
- Redis
|
||||
- MongoDB
|
||||
- PostgreSQL
|
||||
- SQL Server
|
||||
- Azure CosmosDB
|
||||
To use actors, your state store must support multi-item transactions. This means your state store [component](https://github.com/dapr/components-contrib/tree/master/state) must implement the [TransactionalStore](https://github.com/dapr/components-contrib/blob/master/state/transactional_store.go) interface. The list of components that support transactions/actors can be found here: [supported state stores]({{< ref supported-state-stores.md >}}).
|
||||
|
||||
## Actor timers and reminders
|
||||
|
||||
|
|
|
@ -9,32 +9,36 @@ no_list: true
|
|||
|
||||
### Generic
|
||||
|
||||
| Name | CRUD | Transactional | Status |
|
||||
|----------------------------------------------------------------|------|---------------|--------|
|
||||
| [Aerospike]({{< ref setup-aerospike.md >}}) | ✅ | ❌ | Alpha |
|
||||
| [Apache Cassandra]({{< ref setup-cassandra.md >}}) | ✅ | ❌ | Alpha |
|
||||
| [Cloudstate]({{< ref setup-cloudstate.md >}}) | ✅ | ❌ | Alpha |
|
||||
| [Couchbase]({{< ref setup-couchbase.md >}}) | ✅ | ❌ | Alpha |
|
||||
| [Hashicorp Consul]({{< ref setup-consul.md >}}) | ✅ | ❌ | Alpha |
|
||||
| [Hazelcast]({{< ref setup-hazelcast.md >}}) | ✅ | ❌ | Alpha |
|
||||
| [Memcached]({{< ref setup-memcached.md >}}) | ✅ | ❌ | Alpha |
|
||||
| [MongoDB]({{< ref setup-mongodb.md >}}) | ✅ | ✅ | Alpha |
|
||||
| [MySQL]({{< ref setup-mysql.md >}}) | ✅ | ✅ | Alpha |
|
||||
| [PostgreSQL]({{< ref setup-postgresql.md >}}) | ✅ | ✅ | Alpha |
|
||||
| [Redis]({{< ref setup-redis.md >}}) | ✅ | ✅ | Alpha |
|
||||
| [Zookeeper]({{< ref setup-zookeeper.md >}}) | ✅ | ❌ | Alpha |
|
||||
| Name | CRUD | Transactional </br>(Supports Actors) | ETag | Status |
|
||||
|----------------------------------------------------------------|------|---------------------|------|--------|
|
||||
| [Aerospike]({{< ref setup-aerospike.md >}}) | ✅ | ❌ | ✅ | Alpha |
|
||||
| [Apache Cassandra]({{< ref setup-cassandra.md >}}) | ✅ | ❌ | ❌ | Alpha |
|
||||
| [Cloudstate]({{< ref setup-cloudstate.md >}}) | ✅ | ❌ | ✅ | Alpha |
|
||||
| [Couchbase]({{< ref setup-couchbase.md >}}) | ✅ | ❌ | ✅ | Alpha |
|
||||
| [Hashicorp Consul]({{< ref setup-consul.md >}}) | ✅ | ❌ | ❌ | Alpha |
|
||||
| [Hazelcast]({{< ref setup-hazelcast.md >}}) | ✅ | ❌ | ❌ | Alpha |
|
||||
| [Memcached]({{< ref setup-memcached.md >}}) | ✅ | ❌ | ❌ | Alpha |
|
||||
| [MongoDB]({{< ref setup-mongodb.md >}}) | ✅ | ✅ | ❌ | Alpha |
|
||||
| [MySQL]({{< ref setup-mysql.md >}}) | ✅ | ✅ | ✅ | Alpha |
|
||||
| [PostgreSQL]({{< ref setup-postgresql.md >}}) | ✅ | ✅ | ✅ | Alpha |
|
||||
| [Redis]({{< ref setup-redis.md >}}) | ✅ | ✅ | ✅ | Alpha |
|
||||
| RethinkDB | ✅ | ✅ | ✅ | Alpha |
|
||||
| [Zookeeper]({{< ref setup-zookeeper.md >}}) | ✅ | ❌ | ✅ | Alpha |
|
||||
|
||||
### Google Cloud Platform (GCP)
|
||||
| Name | CRUD | Transactional | Status |
|
||||
|-------------------------------------------------------|------|---------------|--------|
|
||||
| [GCP Firestore]({{< ref setup-firestore.md >}}) | ✅ | ❌ | Alpha |
|
||||
| Name | CRUD | Transactional </br>(Supports Actors) | ETag | Status |
|
||||
|-------------------------------------------------------|------|---------------------|------|--------|
|
||||
| [GCP Firestore]({{< ref setup-firestore.md >}}) | ✅ | ❌ | ❌ | Alpha |
|
||||
### Microsoft Azure
|
||||
|
||||
| Name | CRUD | Transactional | Status |
|
||||
|------------------------------------------------------------------|------|---------------|--------|
|
||||
| [Azure Blob Storage]({{< ref setup-azure-blobstorage.md >}}) | ✅ | ❌ | Alpha |
|
||||
| [Azure CosmosDB]({{< ref setup-azure-cosmosdb.md >}}) | ✅ | ✅ | Alpha |
|
||||
| [Azure SQL Server]({{< ref setup-sqlserver.md >}}) | ✅ | ❌ | Alpha |
|
||||
| [Azure Table Storage]({{< ref setup-azure-tablestorage.md >}}) | ✅ | ❌ | Alpha |
|
||||
|
||||
| Name | CRUD | Transactional </br>(Supports Actors) | ETag | Status |
|
||||
|------------------------------------------------------------------|------|---------------------|------|--------|
|
||||
| [Azure Blob Storage]({{< ref setup-azure-blobstorage.md >}}) | ✅ | ❌ | ✅ | Alpha |
|
||||
| [Azure CosmosDB]({{< ref setup-azure-cosmosdb.md >}}) | ✅ | ✅ | ✅ | Alpha |
|
||||
| [Azure SQL Server]({{< ref setup-sqlserver.md >}}) | ✅ | ✅ | ✅ | Alpha |
|
||||
| [Azure Table Storage]({{< ref setup-azure-tablestorage.md >}}) | ✅ | ❌ | ✅ | Alpha |
|
||||
|
||||
### Amazon Web Services (AWS)
|
||||
| Name | CRUD | Transactional </br>(Supports Actors) | ETag | Status |
|
||||
|------------------------------------------------------------------|------|---------------------|------|--------|
|
||||
| AWS DynamoDB | ✅ | ❌ | ❌ | Alpha |
|
||||
|
|
|
@ -103,7 +103,8 @@ curl -X POST http://localhost:3500/v1.0/state/starwars \
|
|||
-d '[
|
||||
{
|
||||
"key": "weapon",
|
||||
"value": "DeathStar"
|
||||
"value": "DeathStar",
|
||||
"etag": "1234"
|
||||
},
|
||||
{
|
||||
"key": "planet",
|
||||
|
@ -288,7 +289,7 @@ None.
|
|||
### Example
|
||||
|
||||
```shell
|
||||
curl -X "DELETE" http://localhost:3500/v1.0/state/starwars/planet -H "ETag: xxxxxxx"
|
||||
curl -X "DELETE" http://localhost:3500/v1.0/state/starwars/planet -H "If-Match: xxxxxxx"
|
||||
```
|
||||
|
||||
## State transactions
|
||||
|
@ -377,6 +378,7 @@ curl -X POST http://localhost:3500/v1.0/state/starwars/transaction \
|
|||
## Configuring state store for actors
|
||||
|
||||
Actors don't support multiple state stores and require a transactional state store to be used with Dapr. Currently Mongodb, Redis, PostgreSQL, SQL Server, and Azure CosmosDB implement the transactional state store interface.
|
||||
|
||||
To specify which state store to be used for actors, specify value of property `actorStateStore` as true in the metadata section of the state store component yaml file.
|
||||
Example: Following components yaml will configure redis to be used as the state store for Actors.
|
||||
|
||||
|
@ -434,9 +436,9 @@ When a strong consistency hint is attached, a state store should:
|
|||
* For read requests, the state store should return the most up-to-date data consistently across replicas.
|
||||
* For write/delete requests, the state store should synchronisely replicate updated data to configured quorum before completing the write request.
|
||||
|
||||
### Example
|
||||
### Example - Complete options request example
|
||||
|
||||
The following is a sample *set* request with a complete operation option definition:
|
||||
The following is an example *set* request with a complete options definition:
|
||||
|
||||
```shell
|
||||
curl -X POST http://localhost:3500/v1.0/state/starwars \
|
||||
|
@ -454,6 +456,82 @@ curl -X POST http://localhost:3500/v1.0/state/starwars \
|
|||
]'
|
||||
```
|
||||
|
||||
### Example - Working with ETags
|
||||
The following is an example which walks through the usage of an ETag when setting/deleting an object in a compatible statestore.
|
||||
|
||||
First, store an object in a statestore (this sample uses Redis that has been defined as 'statestore'):
|
||||
|
||||
```shell
|
||||
curl -X POST http://localhost:3500/v1.0/state/statestore \
|
||||
-H "Content-Type: application/json" \
|
||||
-d '[
|
||||
{
|
||||
"key": "sampleData",
|
||||
"value": "1"
|
||||
}
|
||||
]'
|
||||
```
|
||||
|
||||
Get the object to find the ETag that was set automatically by the statestore:
|
||||
|
||||
```shell
|
||||
curl http://localhost:3500/v1.0/state/statestore/sampleData -v
|
||||
* Connected to localhost (127.0.0.1) port 3500 (#0)
|
||||
> GET /v1.0/state/statestore/sampleData HTTP/1.1
|
||||
> Host: localhost:3500
|
||||
> User-Agent: curl/7.64.1
|
||||
> Accept: */*
|
||||
>
|
||||
< HTTP/1.1 200 OK
|
||||
< Server: fasthttp
|
||||
< Date: Sun, 14 Feb 2021 04:51:50 GMT
|
||||
< Content-Type: application/json
|
||||
< Content-Length: 3
|
||||
< Etag: 1
|
||||
< Traceparent: 00-3452582897d134dc9793a244025256b1-b58d8d773e4d661d-01
|
||||
<
|
||||
* Connection #0 to host localhost left intact
|
||||
"1"* Closing connection 0
|
||||
```
|
||||
|
||||
The returned ETag here was 1. Sending a new request to update or delete the data with the wrong ETag will return an error (omitting the ETag will allow the request):
|
||||
|
||||
```shell
|
||||
# Update
|
||||
curl -X POST http://localhost:3500/v1.0/state/statestore \
|
||||
-H "Content-Type: application/json" \
|
||||
-d '[
|
||||
{
|
||||
"key": "sampleData",
|
||||
"value": "2",
|
||||
"etag": "2"
|
||||
}
|
||||
]'
|
||||
{"errorCode":"ERR_STATE_SAVE","message":"failed saving state in state store statestore: possible etag mismatch. error from state store: ERR Error running script (call to f_83e03ec05d6a3b6fb48483accf5e594597b6058f): @user_script:1: user_script:1: failed to set key nodeapp||sampleData"}
|
||||
|
||||
# Delete
|
||||
curl -X DELETE -H 'If-Match: 5' http://localhost:3500/v1.0/state/statestore/sampleData
|
||||
{"errorCode":"ERR_STATE_DELETE","message":"failed deleting state with key sampleData: possible etag mismatch. error from state store: ERR Error running script (call to f_9b5da7354cb61e2ca9faff50f6c43b81c73c0b94): @user_script:1: user_script:1: failed to delete node
|
||||
app||sampleData"}
|
||||
```
|
||||
|
||||
In order to update or delete the object, simply match the ETag in either the request body (update) or the `If-Match` header (delete). Note, when the state is updated, it receives a new ETag so further updates or deletes will need to use the new ETag.
|
||||
|
||||
```shell
|
||||
# Update
|
||||
curl -X POST http://localhost:3500/v1.0/state/statestore \
|
||||
-H "Content-Type: application/json" \
|
||||
-d '[
|
||||
{
|
||||
"key": "sampleData",
|
||||
"value": "2",
|
||||
"etag": "1"
|
||||
}
|
||||
]'
|
||||
|
||||
# Delete
|
||||
curl -X DELETE -H 'If-Match: 1' http://localhost:3500/v1.0/state/statestore/sampleData
|
||||
```
|
||||
## Next Steps
|
||||
- [State management overview]({{< ref state-management-overview.md >}})
|
||||
- [How-To: Save & get state]({{< ref howto-get-save-state.md >}})
|
||||
|
|
Loading…
Reference in New Issue