Skip to content

Commit 7e238ff

Browse files
committed
Allow retrieve entity metadata from client
1 parent 901c63d commit 7e238ff

File tree

2 files changed

+72
-0
lines changed

2 files changed

+72
-0
lines changed

durabletask/client.py

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
from google.protobuf import wrappers_pb2
1313

1414
from durabletask.entities import EntityInstanceId
15+
from durabletask.entities.entity_metadata import EntityMetadata
1516
import durabletask.internal.helpers as helpers
1617
import durabletask.internal.orchestrator_service_pb2 as pb
1718
import durabletask.internal.orchestrator_service_pb2_grpc as stubs
@@ -241,3 +242,15 @@ def signal_entity(self, entity_instance_id: EntityInstanceId, operation_name: st
241242
)
242243
self._logger.info(f"Signaling entity '{entity_instance_id}' operation '{operation_name}'.")
243244
self._stub.SignalEntity(req, None) # TODO: Cancellation timeout?
245+
246+
def get_entity(self,
247+
entity_instance_id: EntityInstanceId,
248+
include_state: bool = True
249+
) -> Optional[EntityMetadata]:
250+
req = pb.GetEntityRequest(instanceId=str(entity_instance_id), includeState=include_state)
251+
self._logger.info(f"Getting entity '{entity_instance_id}'.")
252+
res: pb.GetEntityResponse = self._stub.GetEntity(req)
253+
if not res.exists:
254+
return None
255+
256+
return EntityMetadata.from_entity_response(res, include_state)
Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
from datetime import datetime
2+
from typing import Any, Optional
3+
from durabletask.entities.entity_instance_id import EntityInstanceId
4+
from durabletask.internal.helpers import get_string_value
5+
6+
import durabletask.internal.orchestrator_service_pb2 as pb
7+
8+
9+
class EntityMetadata:
10+
"""Class representing the metadata of a durable entity.
11+
12+
This class encapsulates the metadata information of a durable entity, allowing for
13+
easy access and manipulation of the entity's metadata within the Durable Task
14+
Framework.
15+
16+
Attributes:
17+
id (EntityInstanceId): The unique identifier of the entity instance.
18+
last_modified (datetime): The timestamp of the last modification to the entity.
19+
backlog_queue_size (int): The size of the backlog queue for the entity.
20+
locked_by (str): The identifier of the worker that currently holds the lock on the entity.
21+
includes_state (bool): Indicates whether the metadata includes the state of the entity.
22+
state (Optional[Any]): The current state of the entity, if included.
23+
"""
24+
25+
def __init__(self,
26+
id: EntityInstanceId,
27+
last_modified: datetime,
28+
backlog_queue_size: int,
29+
locked_by: str,
30+
includes_state: bool,
31+
state: Optional[Any]):
32+
"""Initializes a new instance of the EntityState class.
33+
34+
Args:
35+
value: The initial state value of the entity.
36+
"""
37+
self.id = id
38+
self.last_modified = last_modified
39+
self.backlog_queue_size = backlog_queue_size
40+
self.locked_by = locked_by
41+
self.includes_state = includes_state
42+
self.state = state
43+
44+
@staticmethod
45+
def from_entity_response(entity_response: pb.GetEntityResponse, includes_state: bool):
46+
entity_id = EntityInstanceId.parse(entity_response.entity.instanceId)
47+
if not entity_id:
48+
raise ValueError("Invalid entity instance ID in entity response.")
49+
entity_state = None
50+
if includes_state:
51+
entity_state = str(entity_response.entity.serializedState)
52+
return EntityMetadata(
53+
id=entity_id,
54+
last_modified=entity_response.entity.lastModifiedTime.ToDatetime(),
55+
backlog_queue_size=entity_response.entity.backlogQueueSize,
56+
locked_by=str(entity_response.entity.lockedBy),
57+
includes_state=includes_state,
58+
state=entity_state
59+
)

0 commit comments

Comments
 (0)