class ActorManagerReminderTests(unittest.TestCase): def setUp(self): self._serializer = DefaultJSONSerializer() self._fake_client = FakeDaprActorClient self._test_reminder_req = self._serializer.serialize({ 'name': 'test_reminder', 'dueTime': timedelta(seconds=1), 'period': timedelta(seconds=1), 'ttl': timedelta(seconds=1), 'data': 'cmVtaW5kZXJfc3RhdGU=', }) def test_fire_reminder_for_non_reminderable(self): test_type_info = ActorTypeInformation.create(FakeSimpleActor) ctx = ActorRuntimeContext( test_type_info, self._serializer, self._serializer, self._fake_client) manager = ActorManager(ctx) with self.assertRaises(ValueError): _run(manager.fire_reminder(ActorId('testid'), 'test_reminder', self._test_reminder_req)) def test_fire_reminder_success(self): test_actor_id = ActorId('testid') test_type_info = ActorTypeInformation.create(FakeSimpleReminderActor) ctx = ActorRuntimeContext( test_type_info, self._serializer, self._serializer, self._fake_client) manager = ActorManager(ctx) _run(manager.activate_actor(test_actor_id)) _run(manager.fire_reminder(test_actor_id, 'test_reminder', self._test_reminder_req))
class ActorManagerTests(unittest.TestCase): def setUp(self): self._test_type_info = ActorTypeInformation.create( FakeMultiInterfacesActor) self._serializer = DefaultJSONSerializer() self._fake_client = FakeDaprActorClient self._runtime_ctx = ActorRuntimeContext(self._test_type_info, self._serializer, self._serializer, self._fake_client) self._manager = ActorManager(self._runtime_ctx) def test_activate_actor(self): """Activate ActorId(1)""" test_actor_id = ActorId('1') _run(self._manager.activate_actor(test_actor_id)) # assert self.assertEqual(test_actor_id, self._manager._active_actors[test_actor_id.id].id) self.assertTrue( self._manager._active_actors[test_actor_id.id].activated) self.assertFalse( self._manager._active_actors[test_actor_id.id].deactivated) def test_deactivate_actor(self): """Activate ActorId('2') and deactivate it""" test_actor_id = ActorId('2') _run(self._manager.activate_actor(test_actor_id)) # assert self.assertEqual(test_actor_id, self._manager._active_actors[test_actor_id.id].id) self.assertTrue( self._manager._active_actors[test_actor_id.id].activated) self.assertFalse( self._manager._active_actors[test_actor_id.id].deactivated) _run(self._manager.deactivate_actor(test_actor_id)) self.assertIsNone(self._manager._active_actors.get(test_actor_id.id)) def test_dispatch_success(self): """dispatch ActionMethod""" test_actor_id = ActorId('dispatch') _run(self._manager.activate_actor(test_actor_id)) request_body = { "message": "hello dapr", } test_request_body = self._serializer.serialize(request_body) response = _run( self._manager.dispatch(test_actor_id, "ActionMethod", test_request_body)) self.assertEqual(b'"hello dapr"', response)
class ActorTests(unittest.TestCase): def setUp(self): ActorRuntime._actor_managers = {} ActorRuntime.set_actor_config(ActorRuntimeConfig()) self._serializer = DefaultJSONSerializer() _run(ActorRuntime.register_actor(FakeSimpleActor)) _run(ActorRuntime.register_actor(FakeMultiInterfacesActor)) def test_get_registered_actor_types(self): actor_types = ActorRuntime.get_registered_actor_types() self.assertTrue(actor_types.index('FakeSimpleActor') >= 0) self.assertTrue(actor_types.index(FakeMultiInterfacesActor.__name__) >= 0) def test_actor_config(self): config = ActorRuntime.get_actor_config() self.assertTrue(config._drain_rebalanced_actors) self.assertEqual(timedelta(hours=1), config._actor_idle_timeout) self.assertEqual(timedelta(seconds=30), config._actor_scan_interval) self.assertEqual(timedelta(minutes=1), config._drain_ongoing_call_timeout) self.assertEqual(2, len(config._entities)) # apply new config new_config = ActorRuntimeConfig( timedelta(hours=3), timedelta(seconds=10), timedelta(minutes=1), False) ActorRuntime.set_actor_config(new_config) config = ActorRuntime.get_actor_config() self.assertFalse(config._drain_rebalanced_actors) self.assertEqual(timedelta(hours=3), config._actor_idle_timeout) self.assertEqual(timedelta(seconds=10), config._actor_scan_interval) self.assertEqual(timedelta(minutes=1), config._drain_ongoing_call_timeout) self.assertEqual(2, len(config._entities)) def test_entities_update(self): # Clean up managers ActorRuntime._actor_managers = {} ActorRuntime.set_actor_config(ActorRuntimeConfig()) config = ActorRuntime.get_actor_config() with self.assertRaises(ValueError): config._entities.index(FakeSimpleActor.__name__) _run(ActorRuntime.register_actor(FakeSimpleActor)) config = ActorRuntime.get_actor_config() self.assertTrue(config._entities.index(FakeSimpleActor.__name__) >= 0) def test_dispatch(self): _run(ActorRuntime.register_actor(FakeMultiInterfacesActor)) request_body = { "message": "hello dapr", } test_request_body = self._serializer.serialize(request_body) response = _run(ActorRuntime.dispatch( FakeMultiInterfacesActor.__name__, 'test-id', "ActionMethod", test_request_body)) self.assertEqual(b'"hello dapr"', response) _run(ActorRuntime.deactivate(FakeMultiInterfacesActor.__name__, 'test-id')) # Ensure test-id is deactivated with self.assertRaises(ValueError): _run(ActorRuntime.deactivate(FakeMultiInterfacesActor.__name__, 'test-id')) @mock.patch( 'tests.actor.fake_client.FakeDaprActorClient.register_reminder', new=_async_mock(return_value=b'"ok"')) @mock.patch( 'tests.actor.fake_client.FakeDaprActorClient.unregister_reminder', new=_async_mock(return_value=b'"ok"')) def test_register_reminder(self): test_actor_id = ActorId('test_id') test_type_info = ActorTypeInformation.create(FakeSimpleReminderActor) test_client = FakeDaprActorClient ctx = ActorRuntimeContext( test_type_info, self._serializer, self._serializer, test_client) test_actor = FakeSimpleReminderActor(ctx, test_actor_id) # register reminder _run(test_actor.register_reminder( 'test_reminder', b'reminder_message', timedelta(seconds=1), timedelta(seconds=1))) test_client.register_reminder.mock.assert_called_once() test_client.register_reminder.mock.assert_called_with( 'FakeSimpleReminderActor', 'test_id', 'test_reminder', b'{"name":"test_reminder","dueTime":"0h0m1s","period":"0h0m1s","data":"cmVtaW5kZXJfbWVzc2FnZQ=="}') # noqa E501 # unregister reminder _run(test_actor.unregister_reminder('test_reminder')) test_client.unregister_reminder.mock.assert_called_once() test_client.unregister_reminder.mock.assert_called_with( 'FakeSimpleReminderActor', 'test_id', 'test_reminder') @mock.patch( 'tests.actor.fake_client.FakeDaprActorClient.register_timer', new=_async_mock(return_value=b'"ok"')) @mock.patch( 'tests.actor.fake_client.FakeDaprActorClient.unregister_timer', new=_async_mock(return_value=b'"ok"')) def test_register_timer(self): test_actor_id = ActorId('test_id') test_type_info = ActorTypeInformation.create(FakeSimpleTimerActor) test_client = FakeDaprActorClient ctx = ActorRuntimeContext( test_type_info, self._serializer, self._serializer, test_client) test_actor = FakeSimpleTimerActor(ctx, test_actor_id) # register timer _run(test_actor.register_timer( 'test_timer', test_actor.timer_callback, "mydata", timedelta(seconds=1), timedelta(seconds=2))) test_client.register_timer.mock.assert_called_once() test_client.register_timer.mock.assert_called_with( 'FakeSimpleTimerActor', 'test_id', 'test_timer', b'{"callback":"timer_callback","data":"mydata","dueTime":"0h0m1s","period":"0h0m2s"}') # unregister timer _run(test_actor.unregister_timer('test_timer')) test_client.unregister_timer.mock.assert_called_once() test_client.unregister_timer.mock.assert_called_with( 'FakeSimpleTimerActor', 'test_id', 'test_timer') # register timer without timer name _run(test_actor.register_timer( None, test_actor.timer_callback, "timer call", timedelta(seconds=1), timedelta(seconds=1)))
class ActorRuntimeTests(unittest.TestCase): def setUp(self): ActorRuntime._actor_managers = {} ActorRuntime.set_actor_config(ActorRuntimeConfig()) self._serializer = DefaultJSONSerializer() _run(ActorRuntime.register_actor(FakeSimpleActor)) _run(ActorRuntime.register_actor(FakeMultiInterfacesActor)) _run(ActorRuntime.register_actor(FakeSimpleTimerActor)) def test_get_registered_actor_types(self): actor_types = ActorRuntime.get_registered_actor_types() self.assertTrue(actor_types.index('FakeSimpleActor') >= 0) self.assertTrue( actor_types.index(FakeMultiInterfacesActor.__name__) >= 0) self.assertTrue(actor_types.index(FakeSimpleTimerActor.__name__) >= 0) def test_actor_config(self): config = ActorRuntime.get_actor_config() self.assertTrue(config._drain_rebalanced_actors) self.assertEqual(timedelta(hours=1), config._actor_idle_timeout) self.assertEqual(timedelta(seconds=30), config._actor_scan_interval) self.assertEqual(timedelta(minutes=1), config._drain_ongoing_call_timeout) self.assertEqual(3, len(config._entities)) # apply new config new_config = ActorRuntimeConfig(timedelta(hours=3), timedelta(seconds=10), timedelta(minutes=1), False) ActorRuntime.set_actor_config(new_config) config = ActorRuntime.get_actor_config() self.assertFalse(config._drain_rebalanced_actors) self.assertEqual(timedelta(hours=3), config._actor_idle_timeout) self.assertEqual(timedelta(seconds=10), config._actor_scan_interval) self.assertEqual(timedelta(minutes=1), config._drain_ongoing_call_timeout) self.assertEqual(3, len(config._entities)) def test_entities_update(self): # Clean up managers ActorRuntime._actor_managers = {} ActorRuntime.set_actor_config(ActorRuntimeConfig()) config = ActorRuntime.get_actor_config() with self.assertRaises(ValueError): config._entities.index(FakeSimpleActor.__name__) _run(ActorRuntime.register_actor(FakeSimpleActor)) config = ActorRuntime.get_actor_config() self.assertTrue(config._entities.index(FakeSimpleActor.__name__) >= 0) def test_dispatch(self): _run(ActorRuntime.register_actor(FakeMultiInterfacesActor)) request_body = { "message": "hello dapr", } test_request_body = self._serializer.serialize(request_body) response = _run( ActorRuntime.dispatch(FakeMultiInterfacesActor.__name__, 'test-id', "ActionMethod", test_request_body)) self.assertEqual(b'"hello dapr"', response) _run( ActorRuntime.deactivate(FakeMultiInterfacesActor.__name__, 'test-id')) # Ensure test-id is deactivated with self.assertRaises(ValueError): _run( ActorRuntime.deactivate(FakeMultiInterfacesActor.__name__, 'test-id')) def test_fire_timer_success(self): # Fire timer _run( ActorRuntime.fire_timer( FakeSimpleTimerActor.__name__, 'test-id', 'test_timer', '{ "callback": "timer_callback", "data": "timer call" }'. encode('UTF8'))) manager = ActorRuntime._actor_managers[FakeSimpleTimerActor.__name__] actor = manager._active_actors['test-id'] self.assertTrue(actor.timer_called) def test_fire_timer_unregistered(self): with self.assertRaises(ValueError): _run( ActorRuntime.fire_timer( 'UnknownType', 'test-id', 'test_timer', '{ "callback": "timer_callback", "data": "timer call" }'. encode('UTF8')))
class ActorRuntimeTests(unittest.TestCase): def setUp(self): ActorRuntime._actor_managers = {} ActorRuntime.set_actor_config( ActorRuntimeConfig(reentrancy=ActorReentrancyConfig(enabled=True))) self._serializer = DefaultJSONSerializer() _run(ActorRuntime.register_actor(FakeReentrantActor)) _run(ActorRuntime.register_actor(FakeSlowReentrantActor)) _run(ActorRuntime.register_actor(FakeMultiInterfacesActor)) def test_reentrant_dispatch(self): _run(ActorRuntime.register_actor(FakeMultiInterfacesActor)) request_body = { "message": "hello dapr", } reentrancy_id = "0faa4c8b-f53a-4dff-9a9d-c50205035085" test_request_body = self._serializer.serialize(request_body) response = _run( ActorRuntime.dispatch(FakeMultiInterfacesActor.__name__, 'test-id', "ReentrantMethod", test_request_body, reentrancy_id=reentrancy_id)) self.assertEqual(b'"hello dapr"', response) _run( ActorRuntime.deactivate(FakeMultiInterfacesActor.__name__, 'test-id')) # Ensure test-id is deactivated with self.assertRaises(ValueError): _run( ActorRuntime.deactivate(FakeMultiInterfacesActor.__name__, 'test-id')) def test_interleaved_reentrant_actor_dispatch(self): _run(ActorRuntime.register_actor(FakeReentrantActor)) _run(ActorRuntime.register_actor(FakeSlowReentrantActor)) request_body = self._serializer.serialize({ "message": "Normal", }) normal_reentrancy_id = "f6319f23-dc0a-4880-90d9-87b23c19c20a" slow_reentrancy_id = "b1653a2f-fe54-4514-8197-98b52d156454" async def dispatchReentrantCall(actorName: str, method: str, reentrancy_id: str): return await ActorRuntime.dispatch(actorName, 'test-id', method, request_body, reentrancy_id=reentrancy_id) async def run_parallel_actors(): slow = dispatchReentrantCall(FakeSlowReentrantActor.__name__, "ReentrantMethod", slow_reentrancy_id) normal = dispatchReentrantCall(FakeReentrantActor.__name__, "ReentrantMethod", normal_reentrancy_id) res = await asyncio.gather(slow, normal) self.slow_res = res[0] self.normal_res = res[1] _run(run_parallel_actors()) self.assertEqual(self.normal_res, bytes('"' + normal_reentrancy_id + '"', 'utf-8')) self.assertEqual(self.slow_res, bytes('"' + slow_reentrancy_id + '"', 'utf-8')) _run( ActorRuntime.deactivate(FakeSlowReentrantActor.__name__, 'test-id')) _run(ActorRuntime.deactivate(FakeReentrantActor.__name__, 'test-id')) # Ensure test-id is deactivated with self.assertRaises(ValueError): _run( ActorRuntime.deactivate(FakeSlowReentrantActor.__name__, 'test-id')) _run( ActorRuntime.deactivate(FakeReentrantActor.__name__, 'test-id')) def test_reentrancy_header_passthrough(self): _run(ActorRuntime.register_actor(FakeReentrantActor)) _run(ActorRuntime.register_actor(FakeSlowReentrantActor)) request_body = self._serializer.serialize({ "message": "Normal", }) async def expected_return_value(*args, **kwargs): return ["expected", "None"] reentrancy_id = "f6319f23-dc0a-4880-90d9-87b23c19c20a" actor = FakeSlowReentrantActor.__name__ method = 'ReentrantMethod' with mock.patch('dapr.clients.http.client.DaprHttpClient.send_bytes' ) as mocked: mocked.side_effect = expected_return_value _run( ActorRuntime.dispatch(FakeReentrantActor.__name__, 'test-id', 'ReentrantMethodWithPassthrough', request_body, reentrancy_id=reentrancy_id)) mocked.assert_called_with( method="POST", url= f'http://127.0.0.1:3500/v1.0/actors/{actor}/test-id/method/{method}', data=None, headers={'Dapr-Reentrancy-Id': reentrancy_id}) _run(ActorRuntime.deactivate(FakeReentrantActor.__name__, 'test-id')) # Ensure test-id is deactivated with self.assertRaises(ValueError): _run( ActorRuntime.deactivate(FakeReentrantActor.__name__, 'test-id')) def test_header_passthrough_reentrancy_disabled(self): config = ActorRuntimeConfig(reentrancy=None) ActorRuntime.set_actor_config(config) _run(ActorRuntime.register_actor(FakeReentrantActor)) _run(ActorRuntime.register_actor(FakeSlowReentrantActor)) request_body = self._serializer.serialize({ "message": "Normal", }) async def expected_return_value(*args, **kwargs): return ["expected", "None"] reentrancy_id = "f6319f23-dc0a-4880-90d9-87b23c19c20a" actor = FakeSlowReentrantActor.__name__ method = 'ReentrantMethod' with mock.patch('dapr.clients.http.client.DaprHttpClient.send_bytes' ) as mocked: mocked.side_effect = expected_return_value _run( ActorRuntime.dispatch(FakeReentrantActor.__name__, 'test-id', 'ReentrantMethodWithPassthrough', request_body, reentrancy_id=reentrancy_id)) mocked.assert_called_with( method="POST", url= f'http://127.0.0.1:3500/v1.0/actors/{actor}/test-id/method/{method}', data=None, headers={}) _run(ActorRuntime.deactivate(FakeReentrantActor.__name__, 'test-id')) # Ensure test-id is deactivated with self.assertRaises(ValueError): _run( ActorRuntime.deactivate(FakeReentrantActor.__name__, 'test-id')) def test_parse_incoming_reentrancy_header_flask(self): from ext.flask_dapr import flask_dapr from flask import Flask app = Flask(f'{FakeReentrantActor.__name__}Service') flask_dapr.DaprActor(app) reentrancy_id = "b1653a2f-fe54-4514-8197-98b52d156454" actor_type_name = FakeReentrantActor.__name__ actor_id = 'test-id' method_name = 'ReentrantMethod' request_body = self._serializer.serialize({ "message": "Normal", }) relativeUrl = f'/actors/{actor_type_name}/{actor_id}/method/{method_name}' with mock.patch( 'dapr.actor.runtime.runtime.ActorRuntime.dispatch') as mocked: client = app.test_client() mocked.return_value = None client.put(relativeUrl, headers={ flask_dapr.actor.DAPR_REENTRANCY_ID_HEADER: reentrancy_id }, data=request_body) mocked.assert_called_with(actor_type_name, actor_id, method_name, request_body, reentrancy_id) def test_parse_incoming_reentrancy_header_fastapi(self): from fastapi import FastAPI from fastapi.testclient import TestClient from dapr.ext import fastapi app = FastAPI(title=f'{FakeReentrantActor.__name__}Service') fastapi.DaprActor(app) reentrancy_id = "b1653a2f-fe54-4514-8197-98b52d156454" actor_type_name = FakeReentrantActor.__name__ actor_id = 'test-id' method_name = 'ReentrantMethod' request_body = self._serializer.serialize({ "message": "Normal", }) relativeUrl = f'/actors/{actor_type_name}/{actor_id}/method/{method_name}' with mock.patch( 'dapr.actor.runtime.runtime.ActorRuntime.dispatch') as mocked: client = TestClient(app) mocked.return_value = None client.put(relativeUrl, headers={ fastapi.actor.DAPR_REENTRANCY_ID_HEADER: reentrancy_id }, data=request_body) mocked.assert_called_with(actor_type_name, actor_id, method_name, request_body, reentrancy_id)
class DaprActor(object): def __init__(self, app: FastAPI): self._dapr_serializer = DefaultJSONSerializer() self._router = APIRouter() self.init_routes(self._router) app.include_router(self._router) def init_routes(self, router: APIRouter): @router.get("/healthz") async def healthz(): return {'status': 'ok'} @router.get('/dapr/config') async def dapr_config(): serialized = self._dapr_serializer.serialize(ActorRuntime.get_actor_config()) return _wrap_response(status.HTTP_200_OK, serialized) @router.delete('/actors/{actor_type_name}/{actor_id}') async def actor_deactivation(actor_type_name: str, actor_id: str): try: await ActorRuntime.deactivate(actor_type_name, actor_id) except DaprInternalError as ex: return _wrap_response( status.HTTP_500_INTERNAL_SERVER_ERROR, ex.as_dict()) except Exception as ex: return _wrap_response( status.HTTP_500_INTERNAL_SERVER_ERROR, repr(ex), ERROR_CODE_UNKNOWN) msg = f'deactivated actor: {actor_type_name}.{actor_id}' logger.debug(msg) return _wrap_response(status.HTTP_200_OK, msg) @router.put('/actors/{actor_type_name}/{actor_id}/method/{method_name}') async def actor_method( actor_type_name: str, actor_id: str, method_name: str, request: Request): try: # Read raw bytes from request stream req_body = await request.body() result = await ActorRuntime.dispatch( actor_type_name, actor_id, method_name, req_body) except DaprInternalError as ex: return _wrap_response( status.HTTP_500_INTERNAL_SERVER_ERROR, ex.as_dict()) except Exception as ex: return _wrap_response( status.HTTP_500_INTERNAL_SERVER_ERROR, repr(ex), ERROR_CODE_UNKNOWN) msg = f'called method. actor: {actor_type_name}.{actor_id}, method: {method_name}' logger.debug(msg) return _wrap_response(status.HTTP_200_OK, result) @router.put('/actors/{actor_type_name}/{actor_id}/method/timer/{timer_name}') async def actor_timer( actor_type_name: str, actor_id: str, timer_name: str, request: Request): try: # Read raw bytes from request stream req_body = await request.body() await ActorRuntime.fire_timer(actor_type_name, actor_id, timer_name, req_body) except DaprInternalError as ex: return _wrap_response( status.HTTP_500_INTERNAL_SERVER_ERROR, ex.as_dict()) except Exception as ex: return _wrap_response( status.HTTP_500_INTERNAL_SERVER_ERROR, repr(ex), ERROR_CODE_UNKNOWN) msg = f'called timer. actor: {actor_type_name}.{actor_id}, timer: {timer_name}' logger.debug(msg) return _wrap_response(status.HTTP_200_OK, msg) @router.put('/actors/{actor_type_name}/{actor_id}/method/remind/{reminder_name}') async def actor_reminder( actor_type_name: str, actor_id: str, reminder_name: str, request: Request): try: # Read raw bytes from request stream req_body = await request.body() await ActorRuntime.fire_reminder( actor_type_name, actor_id, reminder_name, req_body) except DaprInternalError as ex: return _wrap_response( status.HTTP_500_INTERNAL_SERVER_ERROR, ex.as_dict()) except Exception as ex: return _wrap_response( status.HTTP_500_INTERNAL_SERVER_ERROR, repr(ex), ERROR_CODE_UNKNOWN) msg = f'called reminder. actor: {actor_type_name}.{actor_id}, reminder: {reminder_name}' logger.debug(msg) return _wrap_response(status.HTTP_200_OK, msg) async def register_actor(self, actor: Type[Actor]) -> None: await ActorRuntime.register_actor(actor) logger.debug(f'registered actor: {actor.__class__.__name__}')
class DaprActor(object): def __init__(self, app=None): self._app = app self._dapr_serializer = DefaultJSONSerializer() if app is not None: self.init_routes(app) def init_routes(self, app): app.add_url_rule('/healthz', None, self._healthz_handler, methods=['GET']) app.add_url_rule('/dapr/config', None, self._config_handler, methods=['GET']) app.add_url_rule('/actors/<actor_type_name>/<actor_id>', None, self._deactivation_handler, methods=['DELETE']) app.add_url_rule( '/actors/<actor_type_name>/<actor_id>/method/<method_name>', None, self._method_handler, methods=['PUT']) app.add_url_rule( '/actors/<actor_type_name>/<actor_id>/method/timer/<timer_name>', None, self._timer_handler, methods=['PUT']) app.add_url_rule( '/actors/<actor_type_name>/<actor_id>/method/remind/<reminder_name>', None, self._reminder_handler, methods=['PUT']) def teardown(self, exception): self._app.logger.debug('actor service is shutting down.') def register_actor(self, actor: Type[Actor]) -> None: asyncio.run(ActorRuntime.register_actor(actor)) self._app.logger.debug(f'registered actor: {actor.__class__.__name__}') def _healthz_handler(self): return wrap_response(200, 'ok') def _config_handler(self): serialized = self._dapr_serializer.serialize( ActorRuntime.get_actor_config()) return wrap_response(200, serialized) def _deactivation_handler(self, actor_type_name, actor_id): try: asyncio.run(ActorRuntime.deactivate(actor_type_name, actor_id)) except DaprInternalError as ex: return wrap_response(500, ex.as_dict()) except Exception as ex: return wrap_response(500, repr(ex), ERROR_CODE_UNKNOWN) msg = f'deactivated actor: {actor_type_name}.{actor_id}' self._app.logger.debug(msg) return wrap_response(200, msg) def _method_handler(self, actor_type_name, actor_id, method_name): try: # Read raw bytes from request stream req_body = request.stream.read() result = asyncio.run( ActorRuntime.dispatch(actor_type_name, actor_id, method_name, req_body)) except DaprInternalError as ex: return wrap_response(500, ex.as_dict()) except Exception as ex: return wrap_response(500, repr(ex), ERROR_CODE_UNKNOWN) msg = f'called method. actor: {actor_type_name}.{actor_id}, method: {method_name}' self._app.logger.debug(msg) return wrap_response(200, result) def _timer_handler(self, actor_type_name, actor_id, timer_name): try: asyncio.run( ActorRuntime.fire_timer(actor_type_name, actor_id, timer_name)) except DaprInternalError as ex: return wrap_response(500, ex.as_dict()) except Exception as ex: return wrap_response(500, repr(ex), ERROR_CODE_UNKNOWN) msg = f'called timer. actor: {actor_type_name}.{actor_id}, timer: {timer_name}' self._app.logger.debug(msg) return wrap_response(200, msg) def _reminder_handler(self, actor_type_name, actor_id, reminder_name): try: # Read raw bytes from request stream req_body = request.stream.read() asyncio.run( ActorRuntime.fire_reminder(actor_type_name, actor_id, reminder_name, req_body)) except DaprInternalError as ex: return wrap_response(500, ex.as_dict()) except Exception as ex: return wrap_response(500, repr(ex), ERROR_CODE_UNKNOWN) msg = f'called reminder. actor: {actor_type_name}.{actor_id}, reminder: {reminder_name}' self._app.logger.debug(msg) return wrap_response(200, msg)