def resolve_context( self, integration: typing.Union[IntegrationEvent, IntegrationRecord]) -> None: if isinstance(integration, IntegrationEvent): record = typing.cast(IntegrationRecord, self.mapper.serialize(integration)) elif isinstance(integration, IntegrationRecord): record = integration if record.trace_id not in self.traces: raise TraceNotFound() trace = self.traces[record.trace_id] if record.context in trace.contexts_resolutions: trace.contexts_resolutions[ record.context].resolution = record.resolve else: trace.contexts_resolutions_unexpected[ record.context] = ContextResolution( context=record.context, resolution=record.resolve, error=record.error, timestamp=None, ) trace.integrations.append(record) self._safe_try_to_resolve_trace(record.trace_id)
def get_resolution(self, trace_id: str) -> TraceResolution: item = { "TableName": self.table_name, "Key": {"trace_id": serialize(trace_id)}, "ProjectionExpression": "resolution, contexts_resolutions", "ConsistentRead": True, } result = self.client.get_item(**item) if "Item" not in result: raise TraceNotFound() resolution = deserialize(result["Item"]["resolution"]) contexts_resolutions = deserialize( result["Item"]["contexts_resolutions"] ) return TraceResolution( resolution=resolution, expected=len(contexts_resolutions), completed=sum( 1 for rc in contexts_resolutions.values() if rc["resolution"] != TraceResolution.Resolutions.pending ), errors=tuple( [ cr["error"] for cr in contexts_resolutions.values() if cr["error"] is not None ] ), )
def get_integrations( self, trace_id: str) -> typing.Generator[IntegrationEvent, None, None]: if trace_id not in self.traces: raise TraceNotFound() trace = self.traces[trace_id] return (typing.cast(IntegrationEvent, self.mapper.deserialize(i)) for i in trace.integrations)
def get_resolution(self, trace_id: str) -> TraceResolution: if trace_id not in self.traces: raise TraceNotFound() trace = self.traces[trace_id] return TraceResolution( resolution=trace.resolution, expected=len(trace.contexts_resolutions), completed=sum( 1 for rc in trace.contexts_resolutions.values() if rc.resolution != TraceResolution.Resolutions.pending), errors=tuple([ rc.error for rc in trace.contexts_resolutions.values() if rc.error is not None ]), )
def get_resolution( self, trace_id: str, topic: str, context: typing.Optional[str] = None) -> typing.Optional[str]: subject = topic if context is not None: subject = f"{context}:{topic}" trace_segment_id = self._get_trace_segment_id(trace_id, subject) if trace_segment_id not in self.segments: raise TraceNotFound() trace_segment = self.segments[trace_segment_id] return trace_segment.resolution
def resolve_trace_segment_failure(self, request: InfrastructureMessage, exc: typing.Type[Exception]) -> None: record = self.mapper.serialize(request) subject = record.topic if isinstance(record, EventRecord): subject = f"{record.context}:{record.topic}" trace_segment_id = self._get_trace_segment_id(record.trace_id, subject) if trace_segment_id not in self.segments: raise TraceNotFound() epoch = datetime.datetime.utcnow().timestamp() trace_segment = self.segments[trace_segment_id] trace_segment.resolution = TraceResolution.Resolutions.failure trace_segment.error = str(exc) trace_segment.timestamp_resolution = epoch
def resolve_context( self, integration: typing.Union[IntegrationEvent, IntegrationRecord] ) -> None: if isinstance(integration, IntegrationEvent): integration_record = typing.cast( IntegrationRecord, self.mapper.serialize(integration) ) elif isinstance(integration, IntegrationRecord): integration_record = integration try: self._try_update_with_expected_context(integration_record) except self.client.exceptions.ConditionalCheckFailedException: try: # Unexpected context self._try_update_with_unexpected_context(integration_record) except ( self.client.exceptions.ConditionalCheckFailedException ) as error: raise TraceNotFound() from error self._safe_try_to_resolve_trace(integration_record.trace_id)
def get_integrations( self, trace_id: str ) -> typing.Generator[IntegrationEvent, None, None]: item = { "TableName": self.table_name, "Key": {"trace_id": serialize(trace_id)}, "ProjectionExpression": "integrations", "ConsistentRead": True, } result = self.client.get_item(**item) if "Item" not in result: raise TraceNotFound() integrations = deserialize(result["Item"]["integrations"]) return typing.cast( typing.Generator[IntegrationEvent, None, None], ( self.mapper.deserialize(record_fromdict(i)) for i in integrations ), )