From 4457e69c1e10e705b7c72b05561da46770b4a4e1 Mon Sep 17 00:00:00 2001 From: Serhii Snozyk Date: Tue, 1 Sep 2026 18:49:26 +0200 Subject: [PATCH] fix: do not notify watchers when deleting an absent key delete/2 broadcast {:deleted, bucket, key} unconditionally, so watchers were woken for keys that had never been in the bucket. This was also inconsistent with put_new/3, which stays quiet when it does not write. Use :ets.take/2 so the removal and the presence check are one atomic operation, and broadcast only when a key was actually removed. --- lib/rkv.ex | 7 ++++--- test/rkv_test.exs | 6 ++++++ 2 files changed, 10 insertions(+), 3 deletions(-) diff --git a/lib/rkv.ex b/lib/rkv.ex index 2b9357d..ec2bfd1 100644 --- a/lib/rkv.ex +++ b/lib/rkv.ex @@ -173,9 +173,10 @@ defmodule Rkv do """ @spec delete(bucket(), key()) :: :ok def delete(bucket, key) do - bucket |> ets() |> :ets.delete(key) - broadcast_delete(bucket, key) - :ok + case bucket |> ets() |> :ets.take(key) do + [_entry] -> broadcast_delete(bucket, key) + [] -> :ok + end end @doc """ diff --git a/test/rkv_test.exs b/test/rkv_test.exs index c5dda33..7e63610 100644 --- a/test/rkv_test.exs +++ b/test/rkv_test.exs @@ -99,6 +99,12 @@ defmodule RkvTest do assert Rkv.delete(bucket, :foo) == :ok assert Rkv.get(bucket, :foo) == nil end + + test "does not notify when the key does not exist", %{bucket: bucket} do + :ok = Rkv.watch_all(bucket) + assert Rkv.delete(bucket, :missing) == :ok + refute_received {:deleted, ^bucket, :missing} + end end describe "exists?" do