supabase-community / supabase-kt

A Kotlin Multiplatform Client for Supabase.
https://supabase.com/docs/reference/kotlin/introduction
MIT License
327 stars 33 forks source link

bug: fix presenceDataFlow extension for realtime updates #607

Closed JOsacky closed 1 month ago

JOsacky commented 1 month ago

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

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)]

Additional 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

JOsacky commented 1 month ago

Great work on identifying and fixing this issue!

Aww thanks. I appreciate the quick review and merge