fix: replace duplicate spatial registrations
This commit is contained in:
parent
f1c68fbcfc
commit
7c0861f216
2 changed files with 42 additions and 2 deletions
|
|
@ -85,14 +85,17 @@ defmodule Aprsme.SpatialPubSub do
|
|||
# Create a unique topic for this client
|
||||
topic = "spatial:#{client_id}"
|
||||
|
||||
state = replace_existing_client(state, client_id)
|
||||
|
||||
# Monitor the client process
|
||||
Process.monitor(pid)
|
||||
ref = Process.monitor(pid)
|
||||
|
||||
# Update client info
|
||||
client_info = %{
|
||||
bounds: normalize_bounds(bounds),
|
||||
topic: topic,
|
||||
pid: pid
|
||||
pid: pid,
|
||||
monitor_ref: ref
|
||||
}
|
||||
|
||||
# Update spatial index
|
||||
|
|
@ -353,6 +356,14 @@ defmodule Aprsme.SpatialPubSub do
|
|||
nil ->
|
||||
state
|
||||
|
||||
%{bounds: bounds, monitor_ref: ref} ->
|
||||
Process.demonitor(ref, [:flush])
|
||||
|
||||
state
|
||||
|> remove_from_spatial_index(client_id, bounds)
|
||||
|> update_in([:clients], &Map.delete(&1, client_id))
|
||||
|> update_in([:stats, :clients_count], &max(0, &1 - 1))
|
||||
|
||||
%{bounds: bounds} ->
|
||||
state
|
||||
|> remove_from_spatial_index(client_id, bounds)
|
||||
|
|
@ -361,6 +372,13 @@ defmodule Aprsme.SpatialPubSub do
|
|||
end
|
||||
end
|
||||
|
||||
defp replace_existing_client(state, client_id) do
|
||||
case Map.get(state.clients, client_id) do
|
||||
nil -> state
|
||||
_client_info -> remove_client(state, client_id)
|
||||
end
|
||||
end
|
||||
|
||||
defp calculate_avg_clients_per_cell(spatial_index) do
|
||||
non_nil_cells =
|
||||
spatial_index
|
||||
|
|
|
|||
|
|
@ -34,6 +34,28 @@ defmodule Aprsme.SpatialPubSubTest do
|
|||
|
||||
SpatialPubSub.unregister_client(client_id)
|
||||
end
|
||||
|
||||
test "re-registering an existing client replaces the old viewport without inflating counts" do
|
||||
client_id = "test_reregister_#{:rand.uniform(100_000)}"
|
||||
bounds_1 = %{north: 41.0, south: 40.0, east: -73.0, west: -74.0}
|
||||
bounds_2 = %{north: 36.0, south: 35.0, east: -79.0, west: -80.0}
|
||||
|
||||
before_stats = SpatialPubSub.get_stats()
|
||||
|
||||
assert {:ok, _topic} = SpatialPubSub.register_viewport(client_id, bounds_1)
|
||||
mid_stats = SpatialPubSub.get_stats()
|
||||
assert mid_stats.clients_count == before_stats.clients_count + 1
|
||||
|
||||
assert {:ok, _topic} = SpatialPubSub.register_viewport(client_id, bounds_2)
|
||||
after_stats = SpatialPubSub.get_stats()
|
||||
|
||||
assert after_stats.clients_count == before_stats.clients_count + 1
|
||||
|
||||
state = :sys.get_state(SpatialPubSub)
|
||||
assert state.clients[client_id].bounds == bounds_2
|
||||
|
||||
SpatialPubSub.unregister_client(client_id)
|
||||
end
|
||||
end
|
||||
|
||||
describe "duplicate packet prevention" do
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue