Skip to content

Commit 522e51a

Browse files
Merge branch 'main' into statestore-examples
2 parents 49e4152 + cbc632e commit 522e51a

File tree

5 files changed

+122
-13
lines changed

5 files changed

+122
-13
lines changed

dapr/actor/runtime/state_manager.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -85,7 +85,7 @@ async def try_add_state(self, state_name: str, value: T) -> bool:
8585
existed = await self._actor.runtime_ctx.state_provider.contains_state(
8686
self._type_name, self._actor.id.id, state_name
8787
)
88-
if not existed:
88+
if existed:
8989
return False
9090

9191
state_change_tracker[state_name] = StateMetadata(value, StateChangeKind.add)

examples/invoke-http/README.md

Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
# Example - Invoke a service
2+
3+
This example utilizes a receiver and a caller for the `invoke_method` functionality.
4+
5+
> **Note:** Make sure to use the latest proto bindings
6+
7+
## Pre-requisites
8+
9+
- [Dapr CLI and initialized environment](https://docs.dapr.io/getting-started)
10+
- [Install Python 3.8+](https://www.python.org/downloads/)
11+
12+
### Install requirements
13+
14+
You can install dapr SDK package using pip command:
15+
16+
<!-- STEP
17+
name: Install requirements
18+
-->
19+
20+
```sh
21+
pip3 install dapr Flask
22+
```
23+
24+
<!-- END_STEP -->
25+
26+
## Run the example
27+
28+
To run this example, the following code can be utilized:
29+
30+
Start the receiver:
31+
<!-- STEP
32+
name: Run invoke http example
33+
expected_stdout_lines:
34+
- '== APP == Order received : {"id": 1, "message": "hello world"}'
35+
- '== APP == Order error : {"id": 2, "message": "hello world"}'
36+
background: true
37+
sleep: 5
38+
-->
39+
40+
```bash
41+
dapr run --app-id=invoke-receiver --app-port=8088 --app-protocol http -- python3 invoke-receiver.py
42+
```
43+
<!-- END_STEP -->
44+
45+
Start the caller:
46+
<!-- STEP
47+
name: Run invoke http example
48+
expected_stdout_lines:
49+
- '== APP == text/html'
50+
- '== APP == {"success": true}'
51+
- '== APP == 200'
52+
- '== APP == error occurred'
53+
- '== APP == MY_CODE'
54+
background: true
55+
sleep: 5
56+
-->
57+
58+
```bash
59+
dapr run --app-id=invoke-caller -- python3 invoke-caller.py
60+
```
61+
<!-- END_STEP -->
62+
63+
## Cleanup
64+
65+
<!-- STEP
66+
expected_stdout_lines:
67+
- '✅ app stopped successfully: invoke-receiver'
68+
name: Shutdown dapr
69+
-->
70+
71+
```bash
72+
dapr stop --app-id invoke-receiver
73+
```
74+
75+
<!-- END_STEP -->

examples/invoke-http/invoke-caller.py

Lines changed: 22 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -6,18 +6,29 @@
66
with DaprClient() as d:
77
req_data = {'id': 1, 'message': 'hello world'}
88

9-
while True:
10-
# Create a typed message with content type and body
11-
resp = d.invoke_method(
9+
# First message: success
10+
# Create a typed message with content type and body
11+
resp1 = d.invoke_method(
12+
'invoke-receiver',
13+
'my-method',
14+
http_verb='POST',
15+
data=json.dumps(req_data),
16+
)
17+
18+
# Print the response
19+
print(resp1.content_type, flush=True)
20+
print(resp1.text(), flush=True)
21+
print(str(resp1.status_code), flush=True)
22+
23+
# Second message: error
24+
req_data = {'id': 2, 'message': 'hello world'}
25+
try:
26+
resp2 = d.invoke_method(
1227
'invoke-receiver',
13-
'my-method',
28+
'my-method-err',
1429
http_verb='POST',
1530
data=json.dumps(req_data),
1631
)
17-
18-
# Print the response
19-
print(resp.content_type, flush=True)
20-
print(resp.text(), flush=True)
21-
print(str(resp.status_code), flush=True)
22-
23-
time.sleep(2)
32+
except Exception as e:
33+
print(e._message, flush=True)
34+
print(e._error_code, flush=True)

examples/invoke-http/invoke-receiver.py

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,4 +12,13 @@ def getOrder():
1212
return json.dumps({'success': True}), 200, {'ContentType': 'application/json'}
1313

1414

15+
@app.route('/my-method-err', methods=['POST'])
16+
def getOrderErr():
17+
data = request.json
18+
print('Order error : ' + json.dumps(data), flush=True)
19+
resp = {'message': 'error occurred', 'errorCode': 'MY_CODE'}
20+
return json.dumps(resp), 503, {'ContentType': 'application/json'}
21+
22+
23+
print('Starting Flask app on port 8088...', flush=True)
1524
app.run(port=8088)

tests/actor/test_state_manager.py

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ def setUp(self):
4646

4747
@mock.patch(
4848
'tests.actor.fake_client.FakeDaprActorClient.get_state',
49-
new=_async_mock(return_value=base64.b64encode(b'"value1"')),
49+
new=_async_mock(),
5050
)
5151
@mock.patch(
5252
'tests.actor.fake_client.FakeDaprActorClient.save_state_transactionally', new=_async_mock()
@@ -67,6 +67,20 @@ def test_add_state(self):
6767
added = _run(state_manager.try_add_state('state1', 'value1'))
6868
self.assertFalse(added)
6969

70+
@mock.patch(
71+
'tests.actor.fake_client.FakeDaprActorClient.get_state',
72+
new=_async_mock(return_value=base64.b64encode(b'"value1"')),
73+
)
74+
@mock.patch(
75+
'tests.actor.fake_client.FakeDaprActorClient.save_state_transactionally', new=_async_mock()
76+
)
77+
def test_add_state_with_existing_state(self):
78+
state_manager = ActorStateManager(self._fake_actor)
79+
80+
# Add first 'state1'
81+
added = _run(state_manager.try_add_state('state1', 'value1'))
82+
self.assertFalse(added)
83+
7084
@mock.patch('tests.actor.fake_client.FakeDaprActorClient.get_state', new=_async_mock())
7185
def test_get_state_for_no_state(self):
7286
state_manager = ActorStateManager(self._fake_actor)

0 commit comments

Comments
 (0)