From a1843fd5d1f350003e683beadba7faefd4c5e044 Mon Sep 17 00:00:00 2001 From: Zachary Edgell Date: Wed, 27 Mar 2024 02:00:15 -0400 Subject: [PATCH 01/11] Added distributed lock Signed-off-by: Zachary Edgell --- .github/workflows/validate-examples.yml | 2 +- Cargo.toml | 4 ++ examples/distributed-lock/README.md | 31 +++++++++++ .../components/local-storage.yml | 12 +++++ .../components/statestore.yml | 14 +++++ examples/distributed-lock/dapr.yaml | 10 ++++ examples/distributed-lock/main.rs | 43 +++++++++++++++ src/client.rs | 52 +++++++++++++++++++ 8 files changed, 167 insertions(+), 1 deletion(-) create mode 100644 examples/distributed-lock/README.md create mode 100644 examples/distributed-lock/components/local-storage.yml create mode 100644 examples/distributed-lock/components/statestore.yml create mode 100644 examples/distributed-lock/dapr.yaml create mode 100644 examples/distributed-lock/main.rs diff --git a/.github/workflows/validate-examples.yml b/.github/workflows/validate-examples.yml index e6e461ff..b83cd629 100644 --- a/.github/workflows/validate-examples.yml +++ b/.github/workflows/validate-examples.yml @@ -144,7 +144,7 @@ jobs: fail-fast: false matrix: examples: - [ "actors", "client", "configuration", "crypto", "invoke/grpc", "invoke/grpc-proxying", "pubsub", "secrets-bulk" ] + [ "actors", "client", "configuration", "crypto", "distributed-lock" "invoke/grpc", "invoke/grpc-proxying", "pubsub", "secrets-bulk" ] steps: - name: Check out code uses: actions/checkout@v4 diff --git a/Cargo.toml b/Cargo.toml index c871b3e7..1d7dc184 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -58,6 +58,10 @@ path = "examples/configuration/main.rs" name = "crypto" path = "examples/crypto/main.rs" +[[example]] +name = "distributed-lock" +path = "examples/distributed-lock/main.rs" + [[example]] name = "invoke-grpc-client" path = "examples/invoke/grpc/client.rs" diff --git a/examples/distributed-lock/README.md b/examples/distributed-lock/README.md new file mode 100644 index 00000000..f9ca40ef --- /dev/null +++ b/examples/distributed-lock/README.md @@ -0,0 +1,31 @@ +# Distributed Lock + +This is a simple example that demonstrates Dapr's Distributed Lock capabilities. + +> **Note:** Make sure to use latest version of proto bindings. + +## Running + +To run this example: + +1. Run the multi-app run template: + + + +```bash +dapr run -f . +``` + + + +2. Stop with `ctrl + c` diff --git a/examples/distributed-lock/components/local-storage.yml b/examples/distributed-lock/components/local-storage.yml new file mode 100644 index 00000000..d7c69764 --- /dev/null +++ b/examples/distributed-lock/components/local-storage.yml @@ -0,0 +1,12 @@ +apiVersion: dapr.io/v1alpha1 +kind: Component +metadata: + name: lockstore +spec: + type: lock.redis + version: v1 + metadata: + - name: redisHost + value: localhost:6379 + - name: redisPassword + value: "" \ No newline at end of file diff --git a/examples/distributed-lock/components/statestore.yml b/examples/distributed-lock/components/statestore.yml new file mode 100644 index 00000000..8f50d896 --- /dev/null +++ b/examples/distributed-lock/components/statestore.yml @@ -0,0 +1,14 @@ +apiVersion: dapr.io/v1alpha1 +kind: Component +metadata: + name: statestore +spec: + type: state.redis + version: v1 + metadata: + - name: redisHost + value: localhost:6379 + - name: redisPassword + value: "" + - name: actorStateStore + value: "true" \ No newline at end of file diff --git a/examples/distributed-lock/dapr.yaml b/examples/distributed-lock/dapr.yaml new file mode 100644 index 00000000..02991e02 --- /dev/null +++ b/examples/distributed-lock/dapr.yaml @@ -0,0 +1,10 @@ +version: 1 +common: + daprdLogDestination: console +apps: + - appID: distributed-lock-example + appDirPath: ./ + daprGRPCPort: 35002 + logLevel: debug + command: [ "cargo", "run", "--example", "distributed-lock" ] + resourcesPath: ./components \ No newline at end of file diff --git a/examples/distributed-lock/main.rs b/examples/distributed-lock/main.rs new file mode 100644 index 00000000..13dd4758 --- /dev/null +++ b/examples/distributed-lock/main.rs @@ -0,0 +1,43 @@ +use tokio::time::sleep; + +#[tokio::main] +async fn main() -> Result<(), Box> { + sleep(std::time::Duration::new(2, 0)).await; + let port: u16 = std::env::var("DAPR_GRPC_PORT")?.parse()?; + let addr = format!("https://127.0.0.1:{}", port); + + let mut client = dapr::Client::::connect(addr).await?; + + let files = vec![("my-data", b"some-data".to_vec())]; + + client.save_state("statestore", files).await.unwrap(); + + let result = client + .lock(dapr::client::TryLockRequest { + store_name: "lockstore".to_string(), + resource_id: "my-data".to_string(), + lock_owner: "some-random-id".to_string(), + expiry_in_seconds: 60, + }) + .await + .unwrap(); + + assert!(result.success); + + println!("Successfully locked my-data"); + + let result = client + .unlock(dapr::client::UnlockRequest { + store_name: "lockstore".to_string(), + resource_id: "my-data".to_string(), + lock_owner: "some-random-id".to_string(), + }) + .await + .unwrap(); + + assert_eq!(0, result.status); + + println!("Successfully unlocked my-data"); + + Ok(()) +} diff --git a/src/client.rs b/src/client.rs index 712280e4..203b4ae9 100644 --- a/src/client.rs +++ b/src/client.rs @@ -455,6 +455,24 @@ impl Client { .collect(); self.0.decrypt(requested_items).await } + + /// Distributed lock request call + /// + /// # Arguments + /// + /// * `request` - Request to be made, TryLockRequest + pub async fn lock(&mut self, request: TryLockRequest) -> Result { + self.0.lock(request).await + } + + /// Distributed lock request call + /// + /// # Arguments + /// + /// * `request` - Request to be made, TryLockRequest + pub async fn unlock(&mut self, request: UnlockRequest) -> Result { + self.0.unlock(request).await + } } #[async_trait] @@ -501,6 +519,10 @@ pub trait DaprInterface: Sized { -> Result, Status>; async fn decrypt(&mut self, payload: Vec) -> Result, Status>; + + async fn lock(&mut self, request: TryLockRequest) -> Result; + + async fn unlock(&mut self, request: UnlockRequest) -> Result; } #[async_trait] @@ -661,6 +683,24 @@ impl DaprInterface for dapr_v1::dapr_client::DaprClient { } Ok(data) } + + /// Distributed lock request call + /// + /// # Arguments + /// + /// * `request` - Request to be made, TryLockRequest + async fn lock(&mut self, request: TryLockRequest) -> Result { + Ok(self.try_lock_alpha1(request).await?.into_inner()) + } + + /// Distributed unlock request call + /// + /// # Arguments + /// + /// * `request` - Request to be made, UnlockRequest + async fn unlock(&mut self, request: UnlockRequest) -> Result { + Ok(self.unlock_alpha1(request).await?.into_inner()) + } } /// A request from invoking a service @@ -752,6 +792,18 @@ pub type EncryptRequestOptions = crate::dapr::dapr::proto::runtime::v1::EncryptR /// Decryption request options pub type DecryptRequestOptions = crate::dapr::dapr::proto::runtime::v1::DecryptRequestOptions; +/// Lock response +pub type TryLockResponse = crate::dapr::dapr::proto::runtime::v1::TryLockResponse; + +/// Lock request +pub type TryLockRequest = crate::dapr::dapr::proto::runtime::v1::TryLockRequest; + +/// Unlock request +pub type UnlockRequest = crate::dapr::dapr::proto::runtime::v1::UnlockRequest; + +/// Unlock response +pub type UnlockResponse = crate::dapr::dapr::proto::runtime::v1::UnlockResponse; + type StreamPayload = crate::dapr::dapr::proto::common::v1::StreamPayload; impl From<(K, Vec)> for common_v1::StateItem where From 3b06b4ca09da055caf2b771a016680109a9768c2 Mon Sep 17 00:00:00 2001 From: Zachary Edgell Date: Wed, 27 Mar 2024 02:21:06 -0400 Subject: [PATCH 02/11] Updated examples Signed-off-by: Zachary Edgell --- .../components/statestore.yml | 14 ----------- examples/distributed-lock/main.rs | 24 +++++++++++++------ 2 files changed, 17 insertions(+), 21 deletions(-) delete mode 100644 examples/distributed-lock/components/statestore.yml diff --git a/examples/distributed-lock/components/statestore.yml b/examples/distributed-lock/components/statestore.yml deleted file mode 100644 index 8f50d896..00000000 --- a/examples/distributed-lock/components/statestore.yml +++ /dev/null @@ -1,14 +0,0 @@ -apiVersion: dapr.io/v1alpha1 -kind: Component -metadata: - name: statestore -spec: - type: state.redis - version: v1 - metadata: - - name: redisHost - value: localhost:6379 - - name: redisPassword - value: "" - - name: actorStateStore - value: "true" \ No newline at end of file diff --git a/examples/distributed-lock/main.rs b/examples/distributed-lock/main.rs index 13dd4758..02629ce3 100644 --- a/examples/distributed-lock/main.rs +++ b/examples/distributed-lock/main.rs @@ -8,28 +8,38 @@ async fn main() -> Result<(), Box> { let mut client = dapr::Client::::connect(addr).await?; - let files = vec![("my-data", b"some-data".to_vec())]; + let result = client + .lock(dapr::client::TryLockRequest { + store_name: "lockstore".to_string(), + resource_id: "some-data".to_string(), + lock_owner: "some-random-id".to_string(), + expiry_in_seconds: 60, + }) + .await + .unwrap(); - client.save_state("statestore", files).await.unwrap(); + assert!(result.success); + + println!("Successfully locked some-data"); let result = client .lock(dapr::client::TryLockRequest { store_name: "lockstore".to_string(), - resource_id: "my-data".to_string(), + resource_id: "some-data".to_string(), lock_owner: "some-random-id".to_string(), expiry_in_seconds: 60, }) .await .unwrap(); - assert!(result.success); + assert!(!result.success); - println!("Successfully locked my-data"); + println!("Unsuccessfully locked some-data"); let result = client .unlock(dapr::client::UnlockRequest { store_name: "lockstore".to_string(), - resource_id: "my-data".to_string(), + resource_id: "some-data".to_string(), lock_owner: "some-random-id".to_string(), }) .await @@ -37,7 +47,7 @@ async fn main() -> Result<(), Box> { assert_eq!(0, result.status); - println!("Successfully unlocked my-data"); + println!("Successfully unlocked some-data"); Ok(()) } From 64be79e48c2c3fd4ce6e8e649a5a42fecfdd8c3c Mon Sep 17 00:00:00 2001 From: Zachary Edgell Date: Wed, 27 Mar 2024 02:21:51 -0400 Subject: [PATCH 03/11] Updated examples Signed-off-by: Zachary Edgell --- .github/workflows/validate-examples.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/validate-examples.yml b/.github/workflows/validate-examples.yml index b83cd629..92f63fee 100644 --- a/.github/workflows/validate-examples.yml +++ b/.github/workflows/validate-examples.yml @@ -144,7 +144,7 @@ jobs: fail-fast: false matrix: examples: - [ "actors", "client", "configuration", "crypto", "distributed-lock" "invoke/grpc", "invoke/grpc-proxying", "pubsub", "secrets-bulk" ] + [ "actors", "client", "configuration", "crypto", "distributed-lock", "invoke/grpc", "invoke/grpc-proxying", "pubsub", "secrets-bulk" ] steps: - name: Check out code uses: actions/checkout@v4 From ab9f22bcc8555e5c896888973cb912124949f3c3 Mon Sep 17 00:00:00 2001 From: Zachary Edgell Date: Wed, 27 Mar 2024 02:23:07 -0400 Subject: [PATCH 04/11] Updated examples Signed-off-by: Zachary Edgell --- examples/distributed-lock/README.md | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/examples/distributed-lock/README.md b/examples/distributed-lock/README.md index f9ca40ef..84ff1a0e 100644 --- a/examples/distributed-lock/README.md +++ b/examples/distributed-lock/README.md @@ -15,8 +15,9 @@ name: Run multi-app output_match_mode: substring match_order: none expected_stdout_lines: - - '== APP - distributed-lock-example == Successfully locked my-data' - - '== APP - distributed-lock-example == Successfully unlocked my-data' + - '== APP - distributed-lock-example == Successfully locked some-data' + - '== APP - distributed-lock-example == Unsuccessfully locked some-data' + - '== APP - distributed-lock-example == Successfully unlocked some-data' background: true sleep: 30 timeout_seconds: 90 From 886748e00f94caa5e1d6ab7713b2d2fc4ef58ce1 Mon Sep 17 00:00:00 2001 From: Mike Nguyen Date: Thu, 28 Mar 2024 11:21:43 +0000 Subject: [PATCH 05/11] fix: update example and clarity and validation Signed-off-by: Mike Nguyen --- examples/distributed-lock/README.md | 9 +++++---- examples/distributed-lock/main.rs | 24 +++++++++++++++++++----- 2 files changed, 24 insertions(+), 9 deletions(-) diff --git a/examples/distributed-lock/README.md b/examples/distributed-lock/README.md index 84ff1a0e..29663a94 100644 --- a/examples/distributed-lock/README.md +++ b/examples/distributed-lock/README.md @@ -13,11 +13,12 @@ To run this example: