Skip to content

Commit

Permalink
Merge pull request #482 from nats-io/kv-create-after-del
Browse files Browse the repository at this point in the history
[FEAT] [KV] create now re-attempts if the last entry in the KV is deleted or purged
  • Loading branch information
aricart authored Feb 21, 2023
2 parents 2f81d4d + b1a79b3 commit 78451a9
Show file tree
Hide file tree
Showing 3 changed files with 42 additions and 3 deletions.
25 changes: 23 additions & 2 deletions nats-base-client/kv.ts
Original file line number Diff line number Diff line change
Expand Up @@ -460,8 +460,29 @@ export class Bucket implements KV, KvRemove {
} as KvEntry;
}

create(k: string, data: Uint8Array): Promise<number> {
return this.put(k, data, { previousSeq: 0 });
async create(k: string, data: Uint8Array): Promise<number> {
let firstErr;
try {
const n = await this.put(k, data, { previousSeq: 0 });
return Promise.resolve(n);
} catch (err) {
firstErr = err;
if (err?.api_error?.err_code !== 10071) {
return Promise.reject(err);
}
}
let rev = 0;
try {
const e = await this.get(k);
if (e?.operation === "DEL" || e?.operation === "PURGE") {
rev = e !== null ? e.revision : 0;
return this.update(k, data, rev);
} else {
return Promise.reject(firstErr);
}
} catch (err) {
return Promise.reject(err);
}
}

update(k: string, data: Uint8Array, version: number): Promise<number> {
Expand Down
3 changes: 2 additions & 1 deletion nats-base-client/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2787,7 +2787,8 @@ export interface RoKV {

export interface KV extends RoKV {
/**
* Creates a new entry ensuring that the entry does not exist.
* Creates a new entry ensuring that the entry does not exist (or
* the current version is deleted or the key is purged)
* If the entry already exists, this operation fails.
* @param k
* @param data
Expand Down
17 changes: 17 additions & 0 deletions tests/kv_test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1681,3 +1681,20 @@ Deno.test("kv - mirror cross domain", async () => {

await cleanup(lns, lnc);
});

Deno.test("kv - create after delete", async () => {
const { ns, nc } = await setup(jetstreamServerConf({}, true));

const js = nc.jetstream();
const kv = await js.views.kv("K");
await kv.create("a", Empty);

await assertRejects(async () => {
await kv.create("a", Empty);
});
await kv.delete("a");
await kv.create("a", Empty);
await kv.purge("a");
await kv.create("a", Empty);
await cleanup(ns, nc);
});

0 comments on commit 78451a9

Please sign in to comment.