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

Getting Rid of 'static #3

Open
anlumo opened this issue Aug 19, 2020 · 1 comment
Open

Getting Rid of 'static #3

anlumo opened this issue Aug 19, 2020 · 1 comment

Comments

@anlumo
Copy link

anlumo commented Aug 19, 2020

Hi,

Right now the signature for the future is

pub fn future<TFn, TOutput>(&self, job: TFn) -> impl Future<Output=Result<TOutput, oneshot::Canceled>>+Send
    where   TFn:        'static+Send+for<'a> FnOnce(&'a mut T) -> BoxFuture<'a, TOutput>,
            TOutput:    'static+Send;

However, it should be possible to have this instead:

pub fn future<'a, TFn, TOutput>(&'a self, job: TFn) -> impl 'a + Future<Output=Result<TOutput, oneshot::Canceled>>+Send
    where   TFn:        'a+Send+FnOnce(&'a mut T) -> BoxFuture<'a, TOutput>,
            TOutput:    'a+Send;

because using my_desync.future(…).await makes sure that the Desync stays alive until the passed closure is dropped (either because it was run or because it was canceled).

This would allow using local variables inside the closure passed to the future without capturing them.

Now, I've looked into the desync code and I can see how that's hard to implement, but I created this issue to point out that this would be nice to have in the future (no pun intended).

@Logicalshift
Copy link
Owner

Hi, it's been a while but I've finally found some time to implement this. The latest revision on the 0.7.0 branch splits future into future_sync and future_desync. future_sync() has the following declaration:

pub fn future_sync<'a, TFn, TOutput>(&'a self, job: TFn) -> impl 'a+Future<Output=Result<TOutput, oneshot::Canceled>>+Send
where   TFn:        'a+Send+for<'b> FnOnce(&'b mut T) -> BoxFuture<'b, TOutput>,
        TOutput:    'a+Send {

Note the difference here is the lifetime 'b which is how long the data in the Desync is borrowed for. ('b is within 'a and is shorter but Rust can't express this at the moment). This is a slightly annoying limitation: the data is only available while the returned future is running as other tasks on the same queue might be using it in the meantime.

Another difference from the original is that if the returned future is dropped, its execution will be cancelled.

future_desync() is the original implementation. It differs from future_sync() in that its future will complete even if the return value is dropped (so it can be used in situations where an executor is not available), and a 'desync' future can run in the background even if the thread that's awaiting it is blocked.

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

No branches or pull requests

2 participants