Commit 5cdf7bc
authored
fix: send-message pending task race condition (#3538)
## 🎯 Goal
This PR resolves a very long standing race condition that has evaded me
for quite a while.
Whenever we queue up send message requests while we're offline, they are
to be executed when we regain connection. However, the UI SDK takes care
of failed messages in the sense of re-adding them in case they weren't
resolved or saved in the LLC. This is done so that when a resync happens
of the channel, the state is preserved and the failed messages do not
disappear.
However, since our state layer is not LLC only fully, we have 2 vectors
of resyncing the SDK:
- One that comes from the LLC (i.e `channel.watch()` being called)
- One that comes from the SDK itself (re-adding those failed messages)
When `send-message` pending tasks are executed, the LLC takes care of
upserting the state immediately so that the UI SDK can simply consume
it. This is fine, except for the fact that for the UI SDK to also
resolve its own state, we rely on WS events (which might be a bit late,
especially for the last 1-2 messages, which is when this bug would
mostly happen).
So the flow would look something like this:
- We regain connection
- Pending tasks are executed, `channel.state.messages` are updated (from
the pending task execution)
- After this, the `onSyncStatusChange` callback is invoked
- The `channel` is actually resynced
- `channel.watch()` is called
- We also upsert all failed messages once again
- For any `message` for which we did not receive a WS event of the
successful pending task execution on time, both the failed `message` and
the actual (serverside) one appear in the list
To fix this, we deem messages eligible for recovery if they:
- are `FAILED`
- are not already present in `channel.state`
This makes sure that the race condition never happens when the state is
already up to date. If it's not, we anyway have to do it.
## 🛠 Implementation details
<!-- Provide a description of the implementation -->
## 🎨 UI Changes
<!-- Add relevant screenshots -->
<details>
<summary>iOS</summary>
<table>
<thead>
<tr>
<td>Before</td>
<td>After</td>
</tr>
</thead>
<tbody>
<tr>
<td>
<!--<img src="" /> -->
</td>
<td>
<!--<img src="" /> -->
</td>
</tr>
</tbody>
</table>
</details>
<details>
<summary>Android</summary>
<table>
<thead>
<tr>
<td>Before</td>
<td>After</td>
</tr>
</thead>
<tbody>
<tr>
<td>
<!--<img src="" /> -->
</td>
<td>
<!--<img src="" /> -->
</td>
</tr>
</tbody>
</table>
</details>
## 🧪 Testing
<!-- Explain how this change can be tested (or why it can't be tested)
-->
## ☑️ Checklist
- [ ] I have signed the [Stream
CLA](https://docs.google.com/forms/d/e/1FAIpQLScFKsKkAJI7mhCr7K9rEIOpqIDThrWxuvxnwUq2XkHyG154vQ/viewform)
(required)
- [ ] PR targets the `develop` branch
- [ ] Documentation is updated
- [ ] New code is tested in main example apps, including all possible
scenarios
- [ ] SampleApp iOS and Android
- [ ] Expo iOS and Android1 parent 369c785 commit 5cdf7bc
File tree
2 files changed
+136
-8
lines changed- package/src
- __tests__/offline-support
- components/Channel
2 files changed
+136
-8
lines changedLines changed: 125 additions & 0 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
720 | 720 | | |
721 | 721 | | |
722 | 722 | | |
| 723 | + | |
| 724 | + | |
| 725 | + | |
| 726 | + | |
| 727 | + | |
| 728 | + | |
| 729 | + | |
| 730 | + | |
| 731 | + | |
| 732 | + | |
| 733 | + | |
| 734 | + | |
| 735 | + | |
| 736 | + | |
| 737 | + | |
| 738 | + | |
| 739 | + | |
| 740 | + | |
| 741 | + | |
| 742 | + | |
| 743 | + | |
| 744 | + | |
| 745 | + | |
| 746 | + | |
| 747 | + | |
| 748 | + | |
| 749 | + | |
| 750 | + | |
| 751 | + | |
| 752 | + | |
| 753 | + | |
| 754 | + | |
| 755 | + | |
| 756 | + | |
| 757 | + | |
| 758 | + | |
| 759 | + | |
| 760 | + | |
| 761 | + | |
| 762 | + | |
| 763 | + | |
| 764 | + | |
| 765 | + | |
| 766 | + | |
| 767 | + | |
| 768 | + | |
| 769 | + | |
| 770 | + | |
| 771 | + | |
| 772 | + | |
| 773 | + | |
| 774 | + | |
| 775 | + | |
| 776 | + | |
| 777 | + | |
| 778 | + | |
| 779 | + | |
| 780 | + | |
| 781 | + | |
| 782 | + | |
| 783 | + | |
| 784 | + | |
| 785 | + | |
| 786 | + | |
| 787 | + | |
| 788 | + | |
| 789 | + | |
| 790 | + | |
| 791 | + | |
| 792 | + | |
| 793 | + | |
| 794 | + | |
| 795 | + | |
| 796 | + | |
| 797 | + | |
| 798 | + | |
| 799 | + | |
| 800 | + | |
| 801 | + | |
| 802 | + | |
| 803 | + | |
| 804 | + | |
| 805 | + | |
| 806 | + | |
| 807 | + | |
| 808 | + | |
| 809 | + | |
| 810 | + | |
| 811 | + | |
| 812 | + | |
| 813 | + | |
| 814 | + | |
| 815 | + | |
| 816 | + | |
| 817 | + | |
| 818 | + | |
| 819 | + | |
| 820 | + | |
| 821 | + | |
| 822 | + | |
| 823 | + | |
| 824 | + | |
| 825 | + | |
| 826 | + | |
| 827 | + | |
| 828 | + | |
| 829 | + | |
| 830 | + | |
| 831 | + | |
| 832 | + | |
| 833 | + | |
| 834 | + | |
| 835 | + | |
| 836 | + | |
| 837 | + | |
| 838 | + | |
| 839 | + | |
| 840 | + | |
| 841 | + | |
| 842 | + | |
| 843 | + | |
| 844 | + | |
| 845 | + | |
| 846 | + | |
| 847 | + | |
723 | 848 | | |
724 | 849 | | |
725 | 850 | | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
1167 | 1167 | | |
1168 | 1168 | | |
1169 | 1169 | | |
| 1170 | + | |
| 1171 | + | |
| 1172 | + | |
| 1173 | + | |
| 1174 | + | |
| 1175 | + | |
| 1176 | + | |
| 1177 | + | |
| 1178 | + | |
1170 | 1179 | | |
1171 | 1180 | | |
1172 | 1181 | | |
| |||
1181 | 1190 | | |
1182 | 1191 | | |
1183 | 1192 | | |
1184 | | - | |
1185 | | - | |
1186 | | - | |
| 1193 | + | |
1187 | 1194 | | |
1188 | 1195 | | |
1189 | 1196 | | |
| |||
1192 | 1199 | | |
1193 | 1200 | | |
1194 | 1201 | | |
1195 | | - | |
1196 | | - | |
1197 | | - | |
1198 | | - | |
1199 | | - | |
| 1202 | + | |
1200 | 1203 | | |
1201 | 1204 | | |
1202 | 1205 | | |
| |||
0 commit comments