-
Notifications
You must be signed in to change notification settings - Fork 8
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
Proposal: add offset
to pull()
#23
Comments
Example in fs-source: Fishrock123/fs-source#1 |
For QUIC, the pattern will be:
To illustrate a different way: Imagine a Source with a 50 byte buffer of data available to send. Sink performs five pulls of 10 bytes each. Within 1 second, Sink receives Acks for 0-29 and 40-49, but no Ack for range 30-39. The Sink would then re-pull 30-39 and send it again, but any attempt to send from an already acknowledged range would ideally be an error. To simplify this case, it is acceptable to say that pulls for any range larger than the lowest unacknowledged range are ok to read from again... that is, given the above scenario, even tho we already have an Ack for range 40-49, it is ok for the Sink to pull that range again. This allows for a more naive retransmission approach. It must be possible to repeatedly pull a unacknowledged chunks as many times as necessary.
In this case, the ACK is an explicit statement that that chunk of data was successfully received and processed and can be discarded. I'm not sure I follow the idea that |
I misunderstood That would require something else other than just offset... Could that be an extension? (If you even think the idea of extensions is reasonable!) - i.e. Is this applicable to other stream types? |
e.g.
|
This could be implemented with an additional flag parameter on class Base {
public:
typedef enum PullFlags {
BOB_FLAG_CLEAR = 0; // Source may clear the data once read
BOB_FLAG_RETAIN = 1; // Source should retain the data once read
BOB_FLAG_IGNORE = 2; // Sink will not be waiting for the pushed data
};
virtual ~Base() = 0;
virtual Base* BindSource(Base* source) = 0;
virtual void BindSink(Base* sink) = 0;
virtual void Next(
int status,
void** error,
char* data,
size_t bytes,
uint64_t offset) = 0;
virtual void Pull(
void** error,
char* data,
size_t size,
uint64_t offset,
int flags = 0) = 0;
}; Given this definition if I call: source->Pull(&err, &buf, 10, 0) It continues to act exactly as it does today... But if I call: source->Pull(&err, &buf, 10, 0, BOB_FLAG_RETAIN) The Source [edited] is being instructed to hold on to that chunk of data. To Ack (and release the chunk) without having to wait for it to be delivered, I would call source->Pull(&err, &buf, 10, 0, BOB_FLAG_CLEAR | BOB_FLAG_IGNORE) The Source implementation would determine for itself if ranges can be cleared out of order, or whether it even supports the retain and ignore flags. If it doesn't, then a simple error can be returned. |
(I assume you mean source.) The source may not support that - i.e. it may not buffer - what happens then? Also I made a slight mistake for 3. - we would need some extra, probably optional, parameter to |
Yes, I meant Source. And if the Source does not support retaining the data, then upon seeing the |
From the collab summit, after talking with @jasnell extensively about QUIC, I think it would be useful to have pull support an offset to ask the source to read from (the source may choose to still return whatever data it chooses).
This should allow for
ACK
s in a network implementation (i.e. if you need toACK
, you just request the last / desired offset again).It also would support a level of content-addressability. A sink or downstream intermediate could be the one to inform a file source of where to read from.
Relatedly, this may also make disk-based sources require less state...
The text was updated successfully, but these errors were encountered: