NG: StorageDriver.WriteStream shouldn't require size argument #781
Comments
On Mon, Nov 24, 2014 at 01:22:30PM -0800, Stephen Day wrote:
+1
+1
Why not? Can't the storage driver check how much it received and
That's fine inside Go, but it would make it hard if the storage driver |
There is no way for the caller of
Generally, we won't actually know the size beforehand. This function may be passed an io.Reader directly from an http request. While the "Content-Length" header may provide a hint, the actual read may be shorter or longer. From a security perspective, it can't really be trusted. If the driver does actually require the size, to support block allocation or sized http pushes, it has the option to buffer the data in memory or local disk. The new proposed interface effectively passes on the lack of knowledge from incoming http requests. The returned write size can be checked against incoming "Content-Length" to validate the write. |
On Tue, Dec 02, 2014 at 08:16:55PM -0800, Stephen Day wrote:
The storage driver is isn't calling WriteStream, the registry is
I'd consider either case (shorter or longer) reads an error. In the event of a short read, I'd return the ‘partial write’ error, In the event of a long read, I'd just drop the whole thing, and
Why is this a trust issue? If the client says “I'm uploading 100
Sure, but that seems wasteful to me. Why not push the nominal size |
None of the driver implementations even use the size parameter or use it inconsistently. It's not needed and it makes error handling more complex. It's also confusing in places where its assumed to be the total size of the target content at path rather than the write chunk size. |
On Wed, Dec 03, 2014 at 12:21:42AM -0800, Stephen Day wrote:
That's just a documentation/testing issue.
It doesn't seem simpler to me to handle some errors in the driver, but
That's also a documentation/testing issue. It should be the size of For chunked transfer encoding (where Content-Length isn't set), I'm |
I think the confusion here is that This puts buffering and data acceptance into the hands of the driver, which has the best chance of correct and performant handling. It also separates accepted bytes from the error type, allowing the driver to control whether partial, full or chunked writes are accepted, transparent to the caller. I'll be posting PRs for this over the next couple of days. You'll see that it simplifies the write flow and makes error handling a lot cleaner. I'd recommend you read up on the [ |
On Wed, Dec 03, 2014 at 10:44:28AM -0800, Stephen Day wrote:
I'm still not clear on how you distinguish between successfully
Why would you want to do that?
If you pass an explicit expected size, the driver can still decide if
Is that a decision we want to make on a per-driver level?
Ok. Getting something more concrete to talk about will probably help |
On Wed, Dec 03, 2014 at 10:44:28AM -0800, Stephen Day wrote:
Looking at #820, it seems like the test suite now has (with 2037b1d, nn, err := suite.StorageDriver.WriteStream(filename, 0, bytes.NewReader(contentsChunk1)) instead of: err := suite.StorageDriver.WriteStream(filename, 0, 3*chunkSize, ioutil.NopCloser(bytes.NewReader(contentsChunk1))) When I'd prefer: err := suite.StorageDriver.WriteStream(filename, 0, chunkSize, bytes.NewReader(contentsChunk1)) The approach in 2037b1d doesn't seem a lot cleaner to me. Maybe the Looking at ab9570f (Migrate filesystem driver to new storagedriver |
Furthermore, these changes aren't about preference. They are about consistency. It's inconsistent to both pass in an |
On Fri, Dec 05, 2014 at 09:48:16AM -0800, Stephen Day wrote:
The point of ‘size’ is that sometimes you do know ahead of time how
If all you're looking at is EOF, you can't do any of that.
I'm just trying to keep the storage-driver API clean, and the returned |
@wking The issue with We have the same goals. API cleanliness is very important. You're feedback is detailed but if there is specific action you'd like me to take based on your feedback, please say so. While I do have the best visibility into this problem at this time, ignoring your feedback would be unacceptable. With this change and additions described in #814, based on what I understand you are after, we really are getting the right behavior while avoiding confusion. |
Also, I'm not sure if you noticed when quoting this, but the chunkSize argument changed from |
On Fri, Dec 05, 2014 at 11:24:57AM -0800, Stephen Day wrote:
But the driver may have more information on why the sizes don't match,
Not if you're enforcing consistent behaviour in the test suite.
This is not a complicated check, and I've expressed my preference for
I'm still not clear on how anyone detects broken cnked uploads in Go
Then how are they returning the number of bytes written? I'm just c.Assert(nn, check.Equals, size) check happen in the driver instead of the core. It's not a huge
That's 3? That looks like an issue with the previous length of the
My feedback is to keep ‘size’ in the API and move the short/long write Fri, Dec 05, 2014 at 11:26:52AM -0800, Stephen Day:
Yeah, that was intentional 4. And confusion is easily avoided |
@stevvooe reached out to me on IRC and we kicked this around some We'll want to revist if we find a backend that needs the |
@wking Thank you! We'll proceed with this for now and definitely revisit later. |
Addressed in #820. |
The current storagedriver.WriteStream call is as follows:
This has a few problems:
io.ReadCloser
is unnecessary. The lifecycle of reader should be dictated by the caller.size
andio.EOF
presents several, overlapping errors. Only one should dictate the course of the write.Generally, in Go, its more idiomatic to have a method such as this take a reader and write until it returns
io.EOF
. A function signature as follows would solve the problems above and make the call more idiomatic:The text was updated successfully, but these errors were encountered: