Secure your code as it's written. Use Snyk Code to scan source code in minutes - no build needed - and fix issues immediately.
def test_valid_state(self):
# bytes type state data
reminder = ActorReminderData(
'test_reminder',
b'reminder_state',
timedelta(seconds=1),
timedelta(seconds=1))
self.assertEqual(b'reminder_state', reminder.state)
def test_as_dict(self):
reminder = ActorReminderData(
'test_reminder',
b'reminder_state',
timedelta(seconds=1),
timedelta(seconds=1))
expected = {
'name': 'test_reminder',
'dueTime': timedelta(seconds=1),
'period': timedelta(seconds=1),
'data': 'cmVtaW5kZXJfc3RhdGU=',
}
self.assertDictEqual(expected, reminder.as_dict())
def test_invalid_state(self):
with self.assertRaises(ValueError):
ActorReminderData(
'test_reminder',
123, # int type
timedelta(seconds=1),
timedelta(seconds=1))
ActorReminderData(
'test_reminder',
'reminder_state', # string type
timedelta(seconds=1),
timedelta(seconds=1))
def test_invalid_state(self):
with self.assertRaises(ValueError):
ActorReminderData(
'test_reminder',
123, # int type
timedelta(seconds=1),
timedelta(seconds=1))
ActorReminderData(
'test_reminder',
'reminder_state', # string type
timedelta(seconds=1),
timedelta(seconds=1))
def from_dict(cls, reminder_name: str, obj: Dict[str, Any]) -> 'ActorReminderData':
"""Creates :class:`ActorReminderData` object from dict object."""
b64encoded_state = obj.get('data')
state_bytes = None
if b64encoded_state is not None and len(b64encoded_state) > 0:
state_bytes = base64.b64decode(b64encoded_state)
return ActorReminderData(reminder_name, state_bytes, obj['dueTime'], obj['period'])
async def fire_reminder(
self, actor_id: ActorId,
reminder_name: str, request_body: bytes) -> None:
if not self._runtime_ctx.actor_type_info.is_remindable():
raise ValueError(
f'{self._runtime_ctx.actor_type_info.type_name} does not implment Remindable.')
request_obj = self._message_serializer.deserialize(request_body, object)
if isinstance(request_obj, dict):
reminder_data = ActorReminderData.from_dict(reminder_name, request_obj)
# ignore if request_obj is not dict
async def invoke_reminder(actor: Actor) -> Optional[bytes]:
reminder = getattr(actor, REMINDER_METHOD_NAME)
if reminder is not None:
await reminder(reminder_data.name, reminder_data.state,
reminder_data.due_time, reminder_data.period)
return None
await self._dispatch_internal(actor_id, self._reminder_method_context, invoke_reminder)
Their functionality is similar to timers. But unlike timers, reminders are triggered under
all circumstances until the actor explicitly unregisters them or the actor is explicitly
deleted. Specifically, reminders are triggered across actor deactivations and failovers
because the Actors runtime persists information about the actor's reminders using actor
state provider. Also existing reminders can be updated by calling this registration method
again using the same reminderName.
Args:
name (str): the name of the reminder to register. the name must be unique per actor.
state (bytes): the user state passed to the reminder invocation.
due_time (datetime.timedelta): the amount of time to delay before invoking the reminder
for the first time.
period (datetime.timedelta): the time interval between reminder invocations after
the first invocation.
"""
reminder = ActorReminderData(name, state, due_time, period)
req_body = self._runtime_ctx.message_serializer.serialize(reminder.as_dict())
await self._runtime_ctx.dapr_client.register_reminder(
self._runtime_ctx.actor_type_info.type_name, self.id.id, name, req_body)