Skip to content

chore: solution brainstroming for ingres_expiry - #503

Draft
roman-nazaruk wants to merge 10 commits into
mainfrom
chore/solution-proposal
Draft

chore: solution brainstroming for ingres_expiry#503
roman-nazaruk wants to merge 10 commits into
mainfrom
chore/solution-proposal

Conversation

@roman-nazaruk

Copy link
Copy Markdown
Contributor

Motivation

Changes

Tests

Comment thread src/agent/custom-http-agent.ts Outdated
Comment thread src/agent/custom-http-agent.ts Outdated
Comment thread src/agent/custom-http-agent.ts Outdated
Comment thread src/agent/custom-http-agent.ts Outdated
Comment thread src/agent/custom-http-agent.ts Outdated
Comment thread src/utils/crypto.utils.ts Outdated
Comment thread src/agent/custom-http-agent.ts Outdated
// TODO: Should we try with a new expiry or reject the request if the timestamp is expired?
return (!existingExpiry || expiryToMs(existingExpiry) <= Date.now())
? this.createAndStoreNewExpiry(hash)
: expiryToMs(existingExpiry) - Date.now();

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is dangerous, because there is no guarantee that makeExpiryTransform will set the same expiry (it will call Date.now() again to convert back from delta to expiry, which might result in a slightly different value). We should implement our own HttpAgentRequestTransformFn that will directly receive an Expiry (instead of a delta) and sets it.

Comment thread src/agent/custom-http-agent.ts Outdated
private getIngressExpiry(hash: string): number {
const existingExpiry = this.#cache.get(hash);

// TODO: Should we try with a new expiry or reject the request if the timestamp is expired?

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

After thinking a bit more about it, it might be better to reject the request if the timestamp is expired instead of generating a new one (and also not removing expired timestamps from the cache), WDYT?

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I also rather like rejection. It's also easier/cleaner to implement.

Comment thread src/agent/custom-http-agent.ts Outdated
const ingressExpiry = hash ? this.getIngressExpiry(hash) : DEFAULT_EXPIRY_DURATION;

this.attachRequestNonce({nonce});
this.attachAddTransformExpiry(ingressExpiry);

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If we don't have to set a cached expiry, I would let agent-js set the expiry because they're doing some time sync vodoo.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we always need to set a transform because we cache the agent. If we don’t, we might make a call with the expiry of a previous call. Unless agent-js provides a way to remove a transformer or we re-create an instance—but I guess the first option doesn’t exist, and the second is less performant and also complicates the code.

@tmu0 tmu0 Mar 17, 2025

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I see, good point. With the same argument, the current implementation of attachRequestNonce() also shouldn't work because it conditionally sets the transform. WDYT of the following "creative" approach:

  1. We write a custom implementation of HttpAgentRequestTransformFn that takes care of setting the nonce and the expiry and manages the expiry cache. (Behavior described in step 4).
  2. In CustomHttpAgent.constructor(agent) we set it via agent.addTransform()
  3. In CustomHttpAgent.request() we append the nonce and the length of it to the method name. If no nonce is specified, we just append length 0.
  4. In our custom transform implementation, we remove the nonce and length from the method name.
    • If nonce length is 0, we're done.
    • Otherwise we set the chosen nonce in the request, extract the other request parameters necessary to construct the cache key and check the expiry cache.
      • On cache miss we add the expiry from the request to the cache.
      • On cache hit we replace the expiry in the request with the one from the cache.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

the current implementation of attachRequestNonce() also shouldn't work

We recently merged a PR to overcome this issue with the approach I mentioned (#502). Not that I like it—just sharing the information to let you know it should be fine for now.

following "creative" approach

I like the idea of implementing our custom version of HttpAgentRequestTransformFn. This way, both nonce and expiry handling can be scoped within the same function and module, improving maintainability and testing.

As for appending the nonce and its length to the method name—why not? However, if we can find a way to handle this in a less hacky manner (😉), not again, but fundamentally speaking sure yes, I think having one custom function is a good idea.

@tmu0 tmu0 left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

general approach LGTM, only found two minor issues

Comment thread src/agent/custom-http-agent.ts Outdated
this.#cache.set(hash, requestDetails.ingress_expiry);
}

this.cleanCacheAfterCall();

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we agreed on not removing entries from the cache, so this method can be deleted.

Comment thread src/agent/custom-http-agent.ts Outdated
'update',
makeNonceTransform((): Nonce => base64ToUint8Array(nonce) as Nonce)
);
private splitModifiedMethodName(modifiedMethodName: string) {

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this is not a safe way of extracting the nonce and hash if the original method name contains _nonce_ or _hash_

@roman-nazaruk
roman-nazaruk requested a review from tmu0 March 18, 2025 13:28
@roman-nazaruk
roman-nazaruk force-pushed the chore/solution-proposal branch from bf2858e to 6ee0427 Compare March 31, 2025 07:26
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants