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

AsyncSeek trait bound on Reader may limit options to stream bytes #12880

Open
alice-i-cecile opened this issue Apr 4, 2024 · 4 comments
Open
Labels
A-Assets Load files from disk to use for things like images, models, and sounds C-Feature A new feature, making something new possible D-Complex Quite challenging from either a design or technical perspective. Ask for help! S-Needs-Design This issue requires design work to think about how it would best be accomplished X-Contentious There are nontrivial implications that should be thought through

Comments

@alice-i-cecile
Copy link
Member

alice-i-cecile commented Apr 4, 2024

I'm concerned that this will prevent us from writing AssetReaders (and therefore loaders) that truly "stream" the bytes. For example, the http reader used by WASM currently collects bytes into a VecReader, which is why this works. But if we wanted to skip the Vec to avoid the up front allocation of the entire asset bytes, we now literally cannot do that because AssetReader requires seek, which an http request does not support.

Originally posted by @cart in #12547 (comment)

@alice-i-cecile alice-i-cecile added this to the 0.14 milestone Apr 4, 2024
@alice-i-cecile alice-i-cecile added C-Feature A new feature, making something new possible A-Assets Load files from disk to use for things like images, models, and sounds S-Needs-Design This issue requires design work to think about how it would best be accomplished labels Apr 4, 2024
@alice-i-cecile
Copy link
Member Author

We need an async / streaming abstraction for assets, but Reader may not be the right design. I'm currently inclined to ship with this for now, and then build out the right one once the rough edges become clearer.

@mockersf mockersf changed the title AsyncSeek trait bound on Reader may limit options to stream bytes on web AsyncSeek trait bound on Reader may limit options to stream bytes Apr 4, 2024
@mockersf
Copy link
Member

mockersf commented Apr 4, 2024

this is true for any asset reader that could work on a stream, it could make sense for large files on native too

@BeastLe9enD
Copy link
Contributor

I'm just sharing my personal thoughts on it, maybe it will be interesting for others and exciting ideas will arise from it.

I see both sides, on the one hand it can of course limit options to stream bytes for example with an http request that does not support seek, on the other side I think it is really handy in some cases to have the AsyncSeek implementation, like seeking inside a file when only a specific region is needed.

I don't think AsyncSeek will be used often when loading assets in source format, but rather in processed assets. I think that in the future we also want to make it possible for different source assets to be processed with different asset processors, depending on which platform you are on. For example, on platforms that don't support seeking, we could split a large file into several files instead of seeking inside a big one.

Of course, we would still have the problem that all custom readers still have to implement the AsyncSeek trait. For me it feels wrong to have to implement dummy functions for all readers that don't support seeking. I think it would be good if the reader had a function from which you could possibly query optional seek functionality.

Maybe it's the wrong approach to have the seek functionality in the reader, but in my personal opinion it feels pretty intuitive :)

@alice-i-cecile alice-i-cecile removed this from the 0.14 milestone May 16, 2024
@alice-i-cecile alice-i-cecile added D-Complex Quite challenging from either a design or technical perspective. Ask for help! X-Contentious There are nontrivial implications that should be thought through labels May 16, 2024
@ldubos
Copy link
Contributor

ldubos commented Jul 1, 2024

Hi, I just wanted to share my thoughts on this subject. The new AsyncSeek trait bound on Reader has made my work more complicated for https://crates.io/crates/bevy-histrion-packer.

Since I "pack" assets together and support compression, it's not easy to allow seeking on compressed assets.

Currently, my workaround is to read the file into a temporary buffer to enable seeking. I chose this approach because I believe some "native" Bevy assets will likely take advantage of the seek feature, particularly meshlet meshes.

However, this hack (mainly due to time constraints on this part, which isn't my main priority at the moment) completely negates the benefits of asynchronous reading, as I first need to move all the data to a buffer.

This could be soblved with a custom trait like AsyncSeekForward instead of AsyncSeek. This more constrained trait would allow moving the cursor forward but not backward. It would enable "stream-based" readers and readers like mine to handle it properly without having to involves hack or simply not implements it and returning an error or worst, silently failing. The most probable use case for seeking in this context is moving forward directly to the sub-resource we need to load after reading some sort of entry table.

github-merge-queue bot pushed a commit that referenced this issue Oct 1, 2024
#12880 (#14194)

# Objective

The primary motivation behind this PR is to (partially?) address the
limitations imposed by the recently added `AsyncSeek` trait bound
discussed in issue #12880. While the `AsyncSeek` trait add some
flexibility to the reader, it inadvertently restricts the ability to
write asset readers that can truly stream bytes, particularly in
scenarios like HTTP requests where backward seeking is not supported. It
is also challenging in contexts where assets are stored in compressed
formats or require other kinds of transformations.

The logic behind this change is that currently, with `AsyncSeek`, an
asset Reader based on streamed data will either 1) fail silently, 2)
return an error, or 3) use a buffer to satisfy the trait constraint. I
believe that being able to advance in the file without having to "read"
it is a good thing. The only issue here is the ability to seek backward.
It is highly likely that in this context, we only need to seek forward
in the file because we would have already read an entry table upstream
and just want to access one or more resources further in the file. I
understand that in some cases, this may not be applicable, but I think
it is more beneficial not to constrain `Reader`s that want to stream
than to allow "Assets" to read files in a completely arbitrary order.

## Solution

Replace the current `AsyncSeek` trait with `AsyncSeekForward` on asset
`Reader`

## Changelog

- Introduced a new custom trait, `AsyncSeekForward`, for the asset
Reader.
- Replaced the current `AsyncSeek` trait with `AsyncSeekForward` for all
asset `Reader` implementations.

## Migration Guide

Replace all instances of `AsyncSeek` with `AsyncSeekForward` in your
asset reader implementations.
robtfm pushed a commit to robtfm/bevy that referenced this issue Oct 4, 2024
bevyengine#12880 (bevyengine#14194)

# Objective

The primary motivation behind this PR is to (partially?) address the
limitations imposed by the recently added `AsyncSeek` trait bound
discussed in issue bevyengine#12880. While the `AsyncSeek` trait add some
flexibility to the reader, it inadvertently restricts the ability to
write asset readers that can truly stream bytes, particularly in
scenarios like HTTP requests where backward seeking is not supported. It
is also challenging in contexts where assets are stored in compressed
formats or require other kinds of transformations.

The logic behind this change is that currently, with `AsyncSeek`, an
asset Reader based on streamed data will either 1) fail silently, 2)
return an error, or 3) use a buffer to satisfy the trait constraint. I
believe that being able to advance in the file without having to "read"
it is a good thing. The only issue here is the ability to seek backward.
It is highly likely that in this context, we only need to seek forward
in the file because we would have already read an entry table upstream
and just want to access one or more resources further in the file. I
understand that in some cases, this may not be applicable, but I think
it is more beneficial not to constrain `Reader`s that want to stream
than to allow "Assets" to read files in a completely arbitrary order.

## Solution

Replace the current `AsyncSeek` trait with `AsyncSeekForward` on asset
`Reader`

## Changelog

- Introduced a new custom trait, `AsyncSeekForward`, for the asset
Reader.
- Replaced the current `AsyncSeek` trait with `AsyncSeekForward` for all
asset `Reader` implementations.

## Migration Guide

Replace all instances of `AsyncSeek` with `AsyncSeekForward` in your
asset reader implementations.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-Assets Load files from disk to use for things like images, models, and sounds C-Feature A new feature, making something new possible D-Complex Quite challenging from either a design or technical perspective. Ask for help! S-Needs-Design This issue requires design work to think about how it would best be accomplished X-Contentious There are nontrivial implications that should be thought through
Projects
None yet
Development

No branches or pull requests

4 participants