Skip to content

Commit

Permalink
Merge pull request #2464 from dbluhm/fix/did-resolver-timeouts
Browse files Browse the repository at this point in the history
feat: add timeout to did resolver resolve method
  • Loading branch information
dbluhm authored Sep 6, 2023
2 parents 294919d + 6ea611f commit fc7f748
Showing 1 changed file with 22 additions and 10 deletions.
32 changes: 22 additions & 10 deletions aries_cloudagent/resolver/did_resolver.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
retrieving did's from different sources provided by the method type.
"""

import asyncio
from datetime import datetime
from itertools import chain
import logging
Expand All @@ -29,6 +30,8 @@
class DIDResolver:
"""did resolver singleton."""

DEFAULT_TIMEOUT = 30

def __init__(self, resolvers: Optional[List[BaseDIDResolver]] = None):
"""Create DID Resolver."""
self.resolvers = resolvers or []
Expand All @@ -42,20 +45,28 @@ async def _resolve(
profile: Profile,
did: Union[str, DID],
service_accept: Optional[Sequence[Text]] = None,
*,
timeout: Optional[int] = None,
) -> Tuple[BaseDIDResolver, dict]:
"""Retrieve doc and return with resolver."""
# TODO Cache results
"""Retrieve doc and return with resolver.
This private method enables the public resolve and resolve_with_metadata
methods to share the same logic.
"""
if isinstance(did, DID):
did = str(did)
else:
DID.validate(did)
for resolver in await self._match_did_to_resolver(profile, did):
try:
LOGGER.debug("Resolving DID %s with %s", did, resolver)
document = await resolver.resolve(
profile,
did,
service_accept,
document = await asyncio.wait_for(
resolver.resolve(
profile,
did,
service_accept,
),
timeout if timeout is not None else self.DEFAULT_TIMEOUT,
)
return resolver, document
except DIDNotFound:
Expand All @@ -68,18 +79,20 @@ async def resolve(
profile: Profile,
did: Union[str, DID],
service_accept: Optional[Sequence[Text]] = None,
*,
timeout: Optional[int] = None,
) -> dict:
"""Resolve a DID."""
_, doc = await self._resolve(profile, did, service_accept)
_, doc = await self._resolve(profile, did, service_accept, timeout=timeout)
return doc

async def resolve_with_metadata(
self, profile: Profile, did: Union[str, DID]
self, profile: Profile, did: Union[str, DID], *, timeout: Optional[int] = None
) -> ResolutionResult:
"""Resolve a DID and return the ResolutionResult."""
resolution_start_time = datetime.utcnow()

resolver, doc = await self._resolve(profile, did)
resolver, doc = await self._resolve(profile, did, timeout=timeout)

time_now = datetime.utcnow()
duration = int((time_now - resolution_start_time).total_seconds() * 1000)
Expand Down Expand Up @@ -120,7 +133,6 @@ async def dereference(
document: Optional[BaseDIDDocument] = None,
) -> Resource:
"""Dereference a DID URL to its corresponding DID Doc object."""
# TODO Use cached DID Docs when possible
try:
parsed = DIDUrl.parse(did_url)
if not parsed.did:
Expand Down

0 comments on commit fc7f748

Please sign in to comment.