generated from TBD54566975/tbd-project-template
-
Notifications
You must be signed in to change notification settings - Fork 57
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
In some cases, specifically when more than one identity exists, the `connect()` method can take over a minute to load. This is because DHT resolution takes places for each identity in the system when calling `identities.list()`. I won't go into the details of why resolution happens, but it's part of getting the signer to the DWN tenant for each identity. This PR implements @csuwildcat's cache implementation on the `AgentDidApi` class which takes into account which DIDs are managed by the agent (or the agent's own DID). These DIDs are never evicted from the cache, only updated versions are inserted after a successful resolution occurs. Other DIDs are evicted as usual. In addition to this I have increased the `recordId` reference storage cache to 21 days instead of 2 hours. These values don't change, so we should cache them for as long as possible. The max items is 1,000 and it will evict items based on last seen. 21 days was chosen because the maximum allowed timeout in Node is 24 days, I reduced it as a buffer. This should speed up `connect()` time and all signing of messages throughout the system.
- Loading branch information
1 parent
7347438
commit 5ac4fe5
Showing
16 changed files
with
281 additions
and
35 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
--- | ||
"@web5/user-agent": patch | ||
"@web5/agent": patch | ||
"@web5/dids": patch | ||
"@web5/identity-agent": patch | ||
"@web5/proxy-agent": patch | ||
--- | ||
|
||
Implement DidResolverCache thats specific to Agent usage |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -6,6 +6,7 @@ | |
"mysql2", | ||
"braces", | ||
"GHSA-rv95-896h-c2vc", | ||
"GHSA-952p-6rrq-rcjv" | ||
"GHSA-952p-6rrq-rcjv", | ||
"GHSA-4vvj-4cpr-p986" | ||
] | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,72 @@ | ||
import { DidResolutionResult, DidResolverCache, DidResolverCacheLevel, DidResolverCacheLevelParams } from '@web5/dids'; | ||
import { Web5PlatformAgent } from './types/agent.js'; | ||
|
||
|
||
/** | ||
* AgentDidResolverCache keeps a stale copy of the Agent's managed Identity DIDs and only evicts and refreshes upon a successful resolution. | ||
* This allows for quick and offline access to the internal DIDs used by the agent. | ||
*/ | ||
export class AgentDidResolverCache extends DidResolverCacheLevel implements DidResolverCache { | ||
|
||
/** | ||
* Holds the instance of a `Web5PlatformAgent` that represents the current execution context for | ||
* the `AgentDidApi`. This agent is used to interact with other Web5 agent components. It's vital | ||
* to ensure this instance is set to correctly contextualize operations within the broader Web5 | ||
* Agent framework. | ||
*/ | ||
private _agent?: Web5PlatformAgent; | ||
|
||
/** A map of DIDs that are currently in-flight. This helps avoid going into an infinite loop */ | ||
private _resolving: Map<string, boolean> = new Map(); | ||
|
||
constructor({ agent, db, location, ttl }: DidResolverCacheLevelParams & { agent?: Web5PlatformAgent }) { | ||
super ({ db, location, ttl }); | ||
this._agent = agent; | ||
} | ||
|
||
get agent() { | ||
if (!this._agent) { | ||
throw new Error('Agent not initialized'); | ||
} | ||
return this._agent; | ||
} | ||
|
||
set agent(agent: Web5PlatformAgent) { | ||
this._agent = agent; | ||
} | ||
|
||
/** | ||
* Get the DID resolution result from the cache for the given DID. | ||
* | ||
* If the DID is managed by the agent, or is the agent's own DID, it will not evict it from the cache until a new resolution is successful. | ||
* This is done to achieve quick and offline access to the agent's own managed DIDs. | ||
*/ | ||
async get(did: string): Promise<DidResolutionResult | void> { | ||
try { | ||
const str = await this.cache.get(did); | ||
const cachedResult = JSON.parse(str); | ||
if (!this._resolving.has(did) && Date.now() >= cachedResult.ttlMillis) { | ||
this._resolving.set(did, true); | ||
if (this.agent.agentDid.uri === did || 'undefined' !== typeof await this.agent.identity.get({ didUri: did })) { | ||
try { | ||
const result = await this.agent.did.resolve(did); | ||
if (!result.didResolutionMetadata.error) { | ||
this.set(did, result); | ||
} | ||
} finally { | ||
this._resolving.delete(did); | ||
} | ||
} else { | ||
this._resolving.delete(did); | ||
this.cache.nextTick(() => this.cache.del(did)); | ||
} | ||
} | ||
return cachedResult.value; | ||
} catch(error: any) { | ||
if (error.notFound) { | ||
return; | ||
} | ||
throw error; | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.