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

Investigate if timing out continuations can be mixed with async protocol methods #403

Open
michaelklishin opened this issue Apr 6, 2018 · 4 comments
Assignees
Labels
next-gen-todo If a rewrite happens, address this issue. usability
Milestone

Comments

@michaelklishin
Copy link
Member

michaelklishin commented Apr 6, 2018

This is recurring question that pops up every year or two, most recently in #402.

The protocol has two types of methods:

  • Synchronous: require a response, e.g. queue.declare
  • Asynchronous: don't have a response, e.g. basic.publish or basic.ack

Currently continuations that hit a failure (e.g. a timeout) can't be mixed with asynchronous methods in practice. It would be nice to investigate whether that'd be possible without significant implementation changes that carry the risk of subtle concurrency semantics changes.

Specifically the following two scenarios:

 * A synchronous method that fails
 * An asynchronous method
 * An asynchronous method that fails
 * A synchronous method

Note that in practice many types of continuation failure will result in a connection recovery sequence, and thus newly opened channel(s), so a way to test this in isolation would be highly desired.

We may want to make up our mind and investigate #83, #356 first.

@YulerB
Copy link
Contributor

YulerB commented Sep 10, 2018

Not sure I fully understand, but the blockingCell can expose a WaitForValueAsync like below:

    public class BlockingCellNew<T>
    {
        private readonly TaskCompletionSource<T> taskCompletionSource = new TaskCompletionSource<T>();

        public void ContinueWithValue(T value)
        {
            taskCompletionSource.SetResult(value);
        }

        public async Task<T> WaitForValueAsync(TimeSpan timeout)
        {
            if (taskCompletionSource.Task != await Task.WhenAny(taskCompletionSource.Task, Task.Delay(timeout)))
                taskCompletionSource.SetException(new TimeoutException());
            return taskCompletionSource.Task.Result;
        }
        ///<summary>Retrieve the cell's value, waiting for the given
        ///timeout if no value is immediately available.</summary>
        ///<remarks>
        ///<para>
        /// If a value is present in the cell at the time the call is
        /// made, the call will return immediately. Otherwise, the
        /// calling thread blocks until either a value appears, or
        /// operation times out.
        ///</para>
        ///<para>
        /// If no value was available before the timeout, an exception
        /// is thrown.
        ///</para>
        ///</remarks>
        /// <exception cref="TimeoutException" />
        public T WaitForValue(TimeSpan timeout)
        {
            if (!taskCompletionSource.Task.Wait(timeout))
                taskCompletionSource.SetException(new TimeoutException());
            return taskCompletionSource.Task.Result;
        }
        ///<summary>Retrieve the cell's value, waiting for the given
        ///timeout if no value is immediately available.</summary>
        ///<remarks>
        ///<para>
        /// If a value is present in the cell at the time the call is
        /// made, the call will return immediately. Otherwise, the
        /// calling thread blocks until either a value appears, or
        /// operation times out.
        ///</para>
        ///<para>
        /// If no value was available before the timeout, an exception
        /// is thrown.
        ///</para>
        ///</remarks>
        /// <exception cref="TimeoutException" />
        public T WaitForValue(int timeout)
        {
            return WaitForValue(TimeSpan.FromMilliseconds(timeout));
        }
        ///<summary>Retrieve the cell's value, blocking if none exists
        ///at present, or supply a value to an empty cell, thereby
        ///filling it.</summary>
        /// <exception cref="TimeoutException" />
        public T WaitForValue()
        {
            return WaitForValue(TimeSpan.FromMinutes(60));
        }

        ///<summary>Return valid timeout value</summary>
        ///<remarks>If value of the parameter is less then zero, return 0
        ///to mean infinity</remarks>
        public static int validatedTimeout(int timeout)
        {
            return (timeout != Timeout.Infinite) && (timeout < 0) ? 0 : timeout;
        }
    }

@lukebakken
Copy link
Contributor

Is this an issue that should be evaluated for version 6.0 or left alone for now? @michaelklishin @kjnilsson

@lukebakken
Copy link
Contributor

Moving to version 7.0.0 milestone.

@lukebakken lukebakken added this to the 7.0.0 milestone Mar 14, 2020
@lukebakken lukebakken modified the milestones: 8.0.0, 7.0.0 Mar 8, 2022
@lukebakken lukebakken self-assigned this Jan 11, 2024
@lukebakken lukebakken removed this from the 7.0.0 milestone May 9, 2024
@lukebakken lukebakken added this to the 8.0.0 milestone May 23, 2024
@lukebakken lukebakken added next-gen-todo If a rewrite happens, address this issue. and removed not-enough-information labels May 23, 2024
@lukebakken
Copy link
Contributor

#1368

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
next-gen-todo If a rewrite happens, address this issue. usability
Projects
None yet
Development

No branches or pull requests

3 participants