Whenever presence is updated, it is updated by the server triggering a "leave" event and a "join" event at the same time for the same key. The stale presence is in the "leaves" array and the new updated presence is in the "joins" array. The should still be in the presence cache even though there was a leaves array because we are just saying the old presence is leaving and being updated with new data.
The current behavior presenceChangeFlow causes any update to presence to be cancelled out because the cache key is removed after joins events are added.
Here are some sample logs of this behaviour which causes an empty received presence data array every update
2024-05-26 14:04:13.302 5890-6846 SupabaseRe...Repository osacky.ridemeter D Sending presence: FleetLocationPresence(fleet_location=osacky.ridemeter.models.Location@fb77c94, is_taxi_for_hire=true, profile_id=aefeb7d7-32f4-4fc1-be3e-2cce85907001)
2024-05-26 14:04:13.342 5890-6846 Supabase-Realtime osacky.ridemeter D Received message {"event":"phx_reply","payload":{"response":{},"status":"ok"},"ref":"47","topic":"realtime:2505cc83-cc7f-46c5-8e7d-1c57f676d74a"}
2024-05-26 14:04:13.342 5890-6846 Supabase-Realtime osacky.ridemeter D Received event phx_reply for channel realtime:2505cc83-cc7f-46c5-8e7d-1c57f676d74a
2024-05-26 14:04:13.343 5890-6846 Supabase-Realtime osacky.ridemeter D Received system reply: {"response":{},"status":"ok"}.
2024-05-26 14:04:13.344 5890-6846 Supabase-Realtime osacky.ridemeter D Received message {"event":"presence_diff","payload":{"joins":{"5677164e-1b8a-11ef-81fe-0a58a9feac02":{"metas":[{"phx_ref":"F9Mb_Fz_TyQsUDsE","phx_ref_prev":"F9Mb-irL_UwsUNSF","fleet_location":{"lat":37.7847119,"lon":-122.424579},"is_taxi_for_hire":true,"profile_id":"aefeb7d7-32f4-4fc1-be3e-2cce85907001"}]}},"leaves":{"5677164e-1b8a-11ef-81fe-0a58a9feac02":{"metas":[{"phx_ref":"F9Mb-irL_UwsUNSF","fleet_location":{"lat":37.784711,"lon":-122.4245791},"is_taxi_for_hire":true,"profile_id":"aefeb7d7-32f4-4fc1-be3e-2cce85907001"}]}}},"ref":null,"topic":"realtime:2505cc83-cc7f-46c5-8e7d-1c57f676d74a"}
2024-05-26 14:04:13.344 5890-6846 Supabase-Realtime osacky.ridemeter D Received event presence_diff for channel realtime:2505cc83-cc7f-46c5-8e7d-1c57f676d74a
2024-05-26 14:04:13.346 5890-6846 SupabaseRe...Repository osacky.ridemeter D Received presence data: []
What is the new behavior?
The new behavior processes leave events before join events so that the cache is accurate when updates happen.
as you can see Received presence data is accurate after an update event
Sending presence: FleetLocationPresence(fleet_location=osacky.ridemeter.models.Location@d8f39b1, is_taxi_for_hire=true, profile_id=aefeb7d7-32f4-4fc1-be3e-2cce85907001)
2024-05-26 14:39:02.906 8044-8291 Supabase-Realtime osacky.ridemeter D Received message {"event":"phx_reply","payload":{"response":{},"status":"ok"},"ref":"186","topic":"realtime:2505cc83-cc7f-46c5-8e7d-1c57f676d74a"}
2024-05-26 14:39:02.906 8044-8291 Supabase-Realtime osacky.ridemeter D Received event phx_reply for channel realtime:2505cc83-cc7f-46c5-8e7d-1c57f676d74a
2024-05-26 14:39:02.906 8044-8291 Supabase-Realtime osacky.ridemeter D Received system reply: {"response":{},"status":"ok"}.
2024-05-26 14:39:02.908 8044-8291 Supabase-Realtime osacky.ridemeter D Received message {"event":"presence_diff","payload":{"joins":{"9ecd5e6a-1b8c-11ef-84f5-0a58a9feac02":{"metas":[{"phx_ref":"F9Md4uG8FL8sUP0G","phx_ref_prev":"F9Md4I9aVMgsUF7N","fleet_location":{"lat":37.7845099,"lon":-122.4245548},"is_taxi_for_hire":true,"profile_id":"aefeb7d7-32f4-4fc1-be3e-2cce85907001"}]}},"leaves":{"9ecd5e6a-1b8c-11ef-84f5-0a58a9feac02":{"metas":[{"phx_ref":"F9Md4I9aVMgsUF7N","phx_ref_prev":"F9Md3jhBDZ4sUNXH","fleet_location":{"lat":37.7845071,"lon":-122.4245545},"is_taxi_for_hire":true,"profile_id":"aefeb7d7-32f4-4fc1-be3e-2cce85907001"}]}}},"ref":null,"topic":"realtime:2505cc83-cc7f-46c5-8e7d-1c57f676d74a"}
2024-05-26 14:39:02.908 8044-8291 Supabase-Realtime osacky.ridemeter D Received event presence_diff for channel realtime:2505cc83-cc7f-46c5-8e7d-1c57f676d74a
2024-05-26 14:39:02.911 8044-8291 SupabaseRe...Repository osacky.ridemeter D Received presence data: [FleetLocationPresence(fleet_location=osacky.ridemeter.models.Location@712ee04, is_taxi_for_hire=true, profile_id=aefeb7d7-32f4-4fc1-be3e-2cce85907001)]
What kind of change does this PR introduce?
Bug fix
What is the current behavior?
Whenever presence is updated, it is updated by the server triggering a "leave" event and a "join" event at the same time for the same key. The stale presence is in the "leaves" array and the new updated presence is in the "joins" array. The should still be in the presence cache even though there was a leaves array because we are just saying the old presence is leaving and being updated with new data.
The current behavior presenceChangeFlow causes any update to presence to be cancelled out because the cache key is removed after joins events are added.
Here are some sample logs of this behaviour which causes an empty received presence data array every update
What is the new behavior?
The new behavior processes leave events before join events so that the cache is accurate when updates happen.
as you can see
Received presence data
is accurate after an update eventAdditional context
Relevant discussions / issues this fixes: https://github.com/orgs/supabase/discussions/13971 https://github.com/orgs/supabase/discussions/26748 https://github.com/supabase/realtime/issues/1030