Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add support for KV mirrors and sources #167

Open
8 of 10 tasks
marthaCP opened this issue Oct 25, 2022 · 0 comments
Open
8 of 10 tasks

Add support for KV mirrors and sources #167

marthaCP opened this issue Oct 25, 2022 · 0 comments
Assignees
Labels
client Client related work enhancement New feature or request

Comments

@marthaCP
Copy link
Contributor

marthaCP commented Oct 25, 2022

Write test and fix, if needed

Related to Go issue, nats-io/nats.go#1112

Go test Example: https://github.com/nats-io/nats.go/blob/main/test/kv_test.go#L867

The edits for mirrors and sources introduce some nuances in how KV keys are edited or read.

In a nutshell, edits are performed on the source KV, but read from a mirror.
This means that the subjects used to address or identify the keys depend on prefixes which have to be calculated on the stream info where the KV is attached.

  • By default the prefix for KV is $KV.<bucket>
  • For edit operations (put, delete, purge) the operation will require the prefix for the domain where the source KV is located (local JS is $JS.API)
  • If attached KV is mirroring another KV, the name of the bucket will be the name of the source of the mirror. This means for those operations, the JS prefix, will not be the one in the JS context, but the JS prefix of the mirror.

Initialization of the prefix must be done with the StreamInfo of the KV stream where the API is attaching - this is what it looks like in JavaScript:

  initializePrefixes(info: StreamInfo) {
    // this is a shortcut to calculating the prefix used on reads, which gets initialized 
    // when the first read happens to the length of the `prefix` below
    this._prefixLen = 0;
    this.prefix = `$KV.${this.bucket}`;
    // if the client is accessing a different KV via a domain we require a prefix
    this.useJsPrefix =
      (this.js as JetStreamClientImpl).opts.apiPrefix !== "$JS.API";

    // now if we have a mirror things can be different than expected
    const { mirror } = info.config;
    if (mirror) {
      // the KV for puts, is the one where the mirror is sourced
      let n = mirror.name;
      if (n.startsWith(kvPrefix)) {
        n = n.substring(kvPrefix.length);
      }
      // if the mirror configuration has an API set (it is coming from yet another context)
      //  the prefix required for all the edits
      // we use the name of the mirror without any `KV_` prefix
      if (mirror.external && mirror.external.api !== "") {
        const mb = mirror.name.substring(kvPrefix.length);
        // and because we are targetting the source of the mirror, we use that prefix instead
        // and ignore the context's prefix when doing any edit (PUT, DELETE, PURGE)
        this.useJsPrefix = false;
        this.prefix = `$KV.${mb}`;
        this.editPrefix = `${mirror.external.api}.$KV.${n}`;
      } else {
        // if the mirror doesn't have an API, we'll use the one of the context
        this.editPrefix = this.prefix;
      }
    }
  }

The go client duplicates the logic for the subject calculation for a key, in the javascript client,
there's a method on the KV that calculates it for all the operations - operations that modify the
KV set edit to true:

  subjectForKey(k: string, edit = false): string {
    const builder: string[] = [];
    if (edit) {
      if (this.useJsPrefix) {
        builder.push((this.js as JetStreamClientImpl).apiPrefix);
      }
      if (this.editPrefix !== "") {
        builder.push(this.editPrefix);
      } else {
        builder.push(this.prefix);
      }
    } else {
      if (this.prefix) {
        builder.push(this.prefix);
      }
    }
    builder.push(k);
    return builder.join(".");
  }

Clients and Tools

Other Tasks

  • Update client features spreadsheet

Client authors please update with your progress. If you open issues in your own repositories as a result of this request, please link them to this one by pasting the issue URL in a comment or main issue description.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
client Client related work enhancement New feature or request
Projects
None yet
Development

No branches or pull requests