Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Dedupe acked packets from TwccSendRegister::apply_report() #601

Merged
merged 7 commits into from
Jan 8, 2025

Conversation

alexlapa
Copy link
Collaborator

Fixes #599

The missing invariant here, at least as far as BWE is concerned, is that we don't want to process the same packet(as indicated by transport-cc sequence number) more than one time. We can achieve this either by apply_report to not return a range or, preferably, by changing send_records to only return "new" reports. Alternatively, and perhaps preferably, we add a new layer between TwccSendRegister and the BWE subsystem inspired by libWebRTC's TransportFeedbackAdapter construct as you suggest.

So here is a deduplicating adapter between TwccSendRegister and the insides of SendSideBandwithEstimator. It should do the job but looks kinda awkward to me. I would probably prefer encapsulating this inside of TwccSendRegister by simply removing TwccSendRecords from the storage like libwebrtc does. But anyway, if that works for you then it works for me too.

A good first step might be a failing test based on such a sequence of TWCC feedbacks.

I've also added a test from libwebrtc captured data. It fails right now to demonstrate whats wrong, I'l fix it before merge.

@alexlapa
Copy link
Collaborator Author

ack @k0nserv

@alexlapa alexlapa marked this pull request as draft December 24, 2024 11:38
src/packet/bwe/mod.rs Outdated Show resolved Hide resolved
src/packet/bwe/mod.rs Outdated Show resolved Hide resolved
src/packet/bwe/mod.rs Outdated Show resolved Hide resolved
src/packet/bwe/mod.rs Outdated Show resolved Hide resolved
src/packet/bwe/mod.rs Outdated Show resolved Hide resolved
src/packet/bwe/mod.rs Outdated Show resolved Hide resolved
src/packet/bwe/mod.rs Outdated Show resolved Hide resolved
@k0nserv
Copy link
Collaborator

k0nserv commented Dec 27, 2024

I would probably prefer encapsulating this inside of TwccSendRegister by simply removing TwccSendRecords from the storage like libwebrtc does. But anyway, if that works for you then it works for me too.

Under the current code this would break some stats reporting, which relies these records too; egress packet loss would falsely report packets lost when they were in fact delivered.

@alexlapa alexlapa requested review from k0nserv and algesten December 31, 2024 07:56
src/packet/bwe/mod.rs Outdated Show resolved Hide resolved
src/packet/bwe/mod.rs Outdated Show resolved Hide resolved
@alexlapa alexlapa marked this pull request as ready for review January 6, 2025 09:27
@algesten
Copy link
Owner

algesten commented Jan 6, 2025

@alexlapa thanks!

I just had a phone call with @k0nserv to discuss this. We're coming down on the side that we should fix this in TwccSendRegister.

The code in question from session.rs is this:

                let range = self.twcc_tx_register.apply_report(twcc, now);

                if let Some(bwe) = &mut self.bwe {
                    let records = range.and_then(|range| self.twcc_tx_register.send_records(range));

                    if let Some(records) = records {
                        bwe.update(records, now);
                    }
                }

The range returned from .apply_report() is only used to get .send_records() that are pushed into the BWE component. It seems weird this returns something that is "incorrect" for the BWE, and that we compensate in BWE for that being wrong by doing what this PR is doing.

We sugggest that we instead change .apply_report() to return an -> impl Iterator<Item = TwccSendRecord, and that this iterator is already adjusted to omit the records that have been reported before.

One way to solve that would be to have a counter that is increased by one for every .apply_records(). When we mark a TwccSendRecord as received, we set the counter-number of the "current" apply_records(). That way we can build an iterator that only looks for the current number. This would ensure there is no additional allocation for this operation.

@algesten
Copy link
Owner

algesten commented Jan 6, 2025

I'm sorry we're only talking about this now, after you made efforts going down the route in this PR. I didn't have my mind up-to-date on what was going on, and only saw the issues by talking it through.

@algesten
Copy link
Owner

algesten commented Jan 8, 2025

@alexlapa isn't this commit necessary too? cb09b86

It seems to me we are marking things as received even if they have PacketStatus that is not received.

@alexlapa alexlapa changed the title Deduplicate acked packets in BWE Dedupe acked packets from TwccSendRegister::apply_report() Jan 8, 2025
@alexlapa
Copy link
Collaborator Author

alexlapa commented Jan 8, 2025

@algesten ,

It seems to me we are marking things as received even if they have PacketStatus that is not received.

Not really. TwccSendRecord.recv_report = Some means that packet was included into received Twcc (acked or nacked), it is TwccSendRecord.recv_report.remote_recv_time = Some that actually means that packet was received by the remote.

And from what I see this (TwccSendRecord.recv_report = Some( TwccRecvReport{ remote_recv_time: None } )) invariant is currently being used in egress packet loss calculation right here, so it will break with cb09b86 (as it actually did in related CI run).

We can definitely make it work, but only after packet loss calculation is moved somewhere else. And this will actually make current PR much more simple, cause then we will just remove TwccSendRecords from the TwccSendRegister at the moment when they are acked. It's already been mentioned in this PR.

@alexlapa alexlapa requested a review from k0nserv January 8, 2025 11:24
@algesten
Copy link
Owner

algesten commented Jan 8, 2025

Not really. TwccSendRecord.recv_report = Some means that packet was included into received Twcc (acked or nacked), it is TwccSendRecord.recv_report.remote_recv_time = Some that actually means that packet was received by the remote.

Ah of course. Thanks!

@algesten algesten merged commit 052e74f into algesten:main Jan 8, 2025
25 checks passed
@k0nserv
Copy link
Collaborator

k0nserv commented Jan 8, 2025

Thanks for all the hard work and sorry again for the mix up earlier. Appreciate it!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Egress packets reordering seem to break BWE sometimes
3 participants