Skip to content
This repository has been archived by the owner on Jul 23, 2022. It is now read-only.

Example with rusoto #39

Open
alu opened this issue Jan 4, 2019 · 4 comments
Open

Example with rusoto #39

alu opened this issue Jan 4, 2019 · 4 comments

Comments

@alu
Copy link

alu commented Jan 4, 2019

I am in creating ftp server with rusto.

get_object() function of rusto returns content body as ByteStream, so i want to return it as stream in get() function.
The function returns impl trait, but StorageBackend requires associate type File, so I can't these types be mached.

Can I get several examples or hints?

Thanks ;D

@koenw
Copy link
Owner

koenw commented Jan 17, 2019

Thanks for your interest in firetrap!

It's not entirely clear to me what you're trying to do, but I'll try to help anyway.

If you're interested in writing your own StorageBackend, you can do this by using ByteStream directly as the associated type.

If you want to use the existing Filesystem backend, you could probably wrap around the tokio::fs::File that it uses, and create a ByteStream from it.

Does this help you achieve what you want?

@alu
Copy link
Author

alu commented Jan 18, 2019

Thank you for reply!

If you're interested in writing your own StorageBackend, you can do this by using ByteStream directly as the associated type.

We can't specify ByteStream to File association type because Byte Stream have not implemented AsyncRead.

@koenw
Copy link
Owner

koenw commented Feb 14, 2019

We can't specify ByteStream to File association type because Byte Stream have not implemented AsyncRead.

Hmm, to be honest I'm not sure what the best approach is then. The way the StorageBackend is used now, it really needs AsyncRead (by design, or the threads could block). Perhaps you could somehow write an Async wrapper around the sync Bytestream, but I'm not really sure how I would go around doing that. Perhaps you could look at some examples from how the standard library implements Async types on top of Sync types?

@alu
Copy link
Author

alu commented Feb 15, 2019

My example is here.

fn get<P: AsRef<Path>>(
    &self,
    path: P,
) -> Box<Future<Item = Self::File, Error = Self::Error> + Send> {
    let client = Arc::clone(&self.client);
    let bucket = "xxxx";

    let future = future::result(self.key(path))
        .and_then(move |key| {
            client
                .get_object(rusoto_s3::GetObjectRequest {
                    bucket: bucket.into(),
                    key: key,
                    ..Default::default()
                })
                .map_err(|_| ErrorKind::Unknown)
        })
        .and_then(|object| {
            let body = object
                .body
                .unwrap_or_else(|| rusoto_core::ByteStream::from(vec![]));

            tokio::codec::FramedRead::new(
                body.into_async_read(),
                tokio::codec::BytesCodec::new(),
            )
            .concat2()
            .map_err(|_| ErrorKind::Unknown)
        })
        .map(|body| std::io::Cursor::new(body.to_vec()));

    Box::new(future)
}

I convert into std::io::Cursor from ByteStream because Cursor have implimented AsyncRead.
ByteStream -> tokio::codec::FramedRead -> BytesMut -> Vec<u8> -> Cursor.

But we will lost advantage async programing when we convert into BytesMut.

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

No branches or pull requests

2 participants