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

Saving websocket RTT samples #232

Merged
merged 5 commits into from
Jan 20, 2020
Merged

Conversation

darkk
Copy link
Contributor

@darkk darkk commented Jan 14, 2020

That's WIP for #192

I have a few questions I'm unsure about:

  • is it okay to carry start around the way it's implemented? It looks a bit messy to me, but I'm quite okay with that.
  • does it make sense to send WSInfo messages to client in /upload and /download? I feel like those may be eventually useful, those datapoints feed my curiosity about queuing, but I have no immediate use for the data.
  • should WSInfo be a separate optional sub-message in the spec or should it extend AppInfo with optional fields?
  • there is a feedback loop between the goroutines: sender (sends ping to) → [conn] (eventually delivers pong to) → receiver (sends RTT estimate back to client) → sender. The current implementation uses buffered channel for RTT estimates to avoid blocking on pongch <- rtt while sender is blocked on conn.send(hugeBlob) feeding the pipe with data. I don't like 14kB being allocated just to handle the worst-case, but I did not come up with a more elegant solution.

WIP:

  • ensure that at least one websocket ping is sent ahead of the blob in download.sender to get one unbiased sample of L7 RTT for each /download for "free"
  • update spec/ndt7-protocol.md

This change is Reviewable

darkk added 2 commits January 13, 2020 14:27
L7 ping may be significantly different from L4 pings and separate
endpoint `/ping` is used to keep spec intact till further discussion
happens.

See 3520181 and m-lab#192
Also, move that measurement data into to WSInfo sub-object as it's
currently unclear if AppInfo should be extended or not. It's part of
ndt7 spec :)

TODO: squash this commit into previous one
@bassosimone bassosimone merged commit f792464 into m-lab:master Jan 20, 2020
@bassosimone
Copy link
Contributor

bassosimone commented Jan 20, 2020

I am sorry, @darkk, I meant to update this PR to master but the end result was that I merged this PR to master, which I didn't want. Can you reopen/reissue it? My apologies 🙏

@bassosimone
Copy link
Contributor

bassosimone commented Jan 20, 2020

(Weirdly enough, I could merge a PR with broken CI in master without any prompt like "hey, you want merge this, you sure? You can override if you wish", which is what I'd expect @pboothe)

@darkk
Copy link
Contributor Author

darkk commented Jan 20, 2020

@bassosimone I'll reopen it, but I'd like to clean the code up a bit first. I've not found a good reason to send each and every WSInfo to the client. I think that the way to go is to send one sample for /download (the very first one) and every sample for /ping. It also solves the questionable buffer size for the rtt-passing pipe.

@bassosimone
Copy link
Contributor

Let me take a look at the existing code and provide further feedback.

@darkk darkk mentioned this pull request Jan 21, 2020
1 task
@darkk
Copy link
Contributor Author

darkk commented Jan 21, 2020

@bassosimone okay, it's #234. Keep in mind that I've not finished uprooting of the inelegant 14kb channel buffer yet, so that part is yet to be refactored.

Copy link
Contributor

@bassosimone bassosimone left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Did read the diff, asked clarifying questions! (I think I have a slight preference for opening a new PR, because I'd rather have the discussion happen on a live PR rather than on a dead one, for future clarify.)

}
}
}
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I am ignoring the JavaScript part for now.

runSomething('ping', callback)
}

runPing(function() { runDownload(function() { runUpload(); }); })
</script>
</body>
</html>
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I am ignoring the JavaScript part for now.

func Do(ctx context.Context, conn *websocket.Conn, resultfp *results.File) {
// arguments are owned by the caller of this function. The start argument is
// the test start time used to calculate ElapsedTime and deadlines.
func Do(ctx context.Context, conn *websocket.Conn, resultfp *results.File, start time.Time) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Passing in the start time is very useful to start ensuring the same zero is used everywhere.

@@ -8,4 +8,5 @@ type Measurement struct {
ConnectionInfo *ConnectionInfo `json:",omitempty" bigquery:"-"`
BBRInfo *BBRInfo `json:",omitempty"`
TCPInfo *TCPInfo `json:",omitempty"`
WSInfo *WSInfo `json:",omitempty"`
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This looks like PingInfo to me.

package model

// WSInfo contains an application level (websocket) ping measurement data.
// It may be melded into AppInfo.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No, I'd rather actually keep them separate

receiverch := receiver.StartDownloadReceiver(wholectx, conn)
measurerch := measurer.Start(wholectx, conn, resultfp.Data.UUID, start)
receiverch, pongch := receiver.StartDownloadReceiver(wholectx, conn, start, measurerch)
senderch := sender.Start(conn, measurerch, start, pongch)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I am confused by the fact that a new channel has been introduced. Isn't it possible to use the measurerch for passing around information? I understood that the PING is another nullable pointer within a Measurement.

LastRTT: int64(rtt / time.Microsecond),
MinRTT: int64(minRTT / time.Microsecond),
}
pongch <- wsinfo // Liveness: buffered (sender)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So, here I believe it should be possible to use dst to emit a measurement containing PingInfo, right?

Copy link
Contributor

@bassosimone bassosimone left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Asked some questions

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

Successfully merging this pull request may close these issues.

2 participants