public void BasicTest()
        {
            var ts = TaskSource.New <int>(TaskCreationOptions.None);

            ts.Task.IsCompleted.Should().BeFalse();
            ts.SetResult(1);
            ts.TrySetResult(2).Should().BeFalse();
            ts.Task.IsCompletedSuccessfully().Should().BeTrue();
            ts.Task.Result.Should().Be(1);

            ts = TaskSource.New <int>(TaskCreationOptions.None);
            ts.Task.IsCompleted.Should().BeFalse();
            var e = new InvalidOperationException();

            ts.SetException(e);
            ts.TrySetException(new InvalidOperationException()).Should().BeFalse();
            ts.Task.IsCompleted.Should().BeTrue();
            ts.Task.IsFaulted.Should().BeTrue();
            ts.Task.Exception.Should().NotBeNull();

            ts = TaskSource.New <int>(TaskCreationOptions.None);
            ts.Task.IsCompleted.Should().BeFalse();
            using var cts = new CancellationTokenSource();
            ts.SetCanceled();
            ts.TrySetCanceled(cts.Token).Should().BeFalse();
            ts.Task.IsCompleted.Should().BeTrue();
            ts.Task.IsFaulted.Should().BeFalse();
            ts.Task.IsCanceled.Should().BeTrue();
        }
Beispiel #2
0
 private void Reset()
 {
     _nextMessageTask = TaskSource.New <RedisValue>(true).Task;
     if (IsDisposeStarted)
     {
         TaskSource.For(_nextMessageTask).TrySetCanceled();
     }
 }
Beispiel #3
0
        public static Task InvalidatedAsync <T>(this IComputed <T> computed, CancellationToken cancellationToken = default)
        {
            if (computed.State == ComputedState.Invalidated)
            {
                return(Task.CompletedTask);
            }
            var ts = TaskSource.New <Unit>(true);

            computed.Invalidated += c => ts.SetResult(default);
Beispiel #4
0
 public StateSnapshot(IState <T> state, IComputed <T> computed)
 {
     State    = state;
     Computed = computed;
     LatestNonErrorComputed = computed;
     WhenUpdatingSource     = TaskSource.New <Unit>(true);
     WhenUpdatedSource      = TaskSource.New <Unit>(true);
     UpdateCount            = 0;
     ErrorCount             = 0;
     RetryCount             = 0;
 }
Beispiel #5
0
        protected async ValueTask <Releaser> FastInternalLockAsync(
            ReentryCounter?reentryCounter, CancellationToken cancellationToken = default)
        {
            var newLockSrc       = TaskSource.New <Unit>(_taskCreationOptions);
            var cancellationTask = (Task?)null;

            while (true)
            {
                cancellationToken.ThrowIfCancellationRequested();
                if (reentryCounter?.TryReenter(ReentryMode) == true)
                {
                    return(new Releaser(this, default, reentryCounter));
Beispiel #6
0
        protected static void EndDelay(ref Task <Unit> task, TimeSpan withDelay = default)
        {
            var newTask = TaskSource.New <Unit>(true).Task;
            var oldTask = Interlocked.Exchange(ref task, newTask);

            if (oldTask == null)
            {
                return;
            }
            if (withDelay == default)
            {
                TaskSource.For(oldTask).SetResult(default);
Beispiel #7
0
    // ToTask (typed)

    public static Disposable <Task <T>, CancellationTokenRegistration> ToTask <T>(
        this CancellationToken token,
        TaskCreationOptions taskCreationOptions = default)
    {
        var ts = TaskSource.New <T>(taskCreationOptions);
        var r  = token.Register(() => ts.SetCanceled(token));

#if NETSTANDARD
        return(Disposable.New(ts.Task, r, (_, r1) => r1.Dispose()));
#else
        return(Disposable.New(ts.Task, r, (_, r1) => r1.Unregister()));
#endif
    }
Beispiel #8
0
        protected async ValueTask <Releaser> FastInternalLock(
            ReentryCounter?reentryCounter, CancellationToken cancellationToken = default)
        {
            var newLockSrc             = TaskSource.New <Unit>(_taskCreationOptions);
            var dCancellationTokenTask = new Disposable <Task, CancellationTokenRegistration>();

            try {
                for (;;)
                {
                    cancellationToken.ThrowIfCancellationRequested();
                    if (reentryCounter?.TryReenter(ReentryMode) == true)
                    {
                        return(new Releaser(this, default, reentryCounter));
        public void CancelDelays(bool immediately = false)
        {
            if (!immediately)
            {
                Clock
                .DelayAsync(CancelDelaysDelay, CancellationToken.None)
                .ContinueWith(_ => CancelDelays(true));
                return;
            }
            var newTask = TaskSource.New <Unit>(true).Task;
            var oldTask = Interlocked.Exchange(ref _cancelDelaysTask, newTask);

            if (oldTask != null)
            {
                TaskSource.For(oldTask).SetResult(default);
Beispiel #10
0
        public void CancelDelays(TimeSpan?cancellationDelay = null)
        {
            var delay = Math.Max(0, (cancellationDelay ?? CancellationDelay).TotalSeconds);

            if (delay > 0)
            {
                Clock.DelayAsync(TimeSpan.FromSeconds(delay)).ContinueWith(_ => CancelDelays(TimeSpan.Zero));
                return;
            }
            var newTask = TaskSource.New <Unit>(true).Task;
            var oldTask = Interlocked.Exchange(ref _cancelDelaysTask, newTask);

            if (oldTask != null)
            {
                TaskSource.For(oldTask).SetResult(default);
Beispiel #11
0
    public async Task BasicTest()
    {
        if (TestRunnerInfo.IsBuildAgent())
        {
            return; // No Redis on build agent for now
        }
        var db       = GetRedisDb();
        var started  = TaskSource.New <Unit>(true);
        var streamer = db.GetStreamer <int>("s");
        await streamer.Remove();

        var streamerCopy = db.GetStreamer <int>("s");

        var writeTask = streamer.Write(
            Delays(new[] { 0.1, 0.2, 0.3, 0.1 }),
            _ => started.SetResult(default));
Beispiel #12
0
    public static Disposable <Task, CancellationTokenRegistration> ToTask(
        this CancellationToken token,
        Exception exceptionWhenCancelled,
        TaskCreationOptions taskCreationOptions = default)
    {
        // ReSharper disable once HeapView.PossibleBoxingAllocation
        var ts = TaskSource.New <Unit>(exceptionWhenCancelled, taskCreationOptions);
        var r  = token.Register(arg => {
            var ts1 = TaskSource.For((Task <Unit>)arg !);
            ts1.SetException((Exception)ts1.Task.AsyncState !);
        }, ts.Task);

#if NETSTANDARD
        return(Disposable.New((Task)ts.Task, r, (_, r1) => r1.Dispose()));
#else
        return(Disposable.New((Task)ts.Task, r, (_, r1) => r1.Unregister()));
#endif
    }
Beispiel #13
0
    protected virtual async Task Run(TimeSpan duration, CancellationToken cancellationToken)
    {
        Counters.Clear();
        var startTaskSource = TaskSource.New <Unit>(true);
        var tasks           = Enumerable.Range(0, ConcurrencyLevel)
                              .Select(async i => {
            await startTaskSource.Task.ConfigureAwait(false);
            return(await Benchmark(i, duration, cancellationToken).ConfigureAwait(false));
        })
                              .ToArray();
        await Task.Delay(100, cancellationToken).ConfigureAwait(false); // Wait to make sure all the tasks are created & scheduled

        if (ForceGCCollect)
        {
            GC.Collect();
        }

        Stopwatch = Stopwatch.StartNew();
        startTaskSource.SetResult(default);
 public PublicationState(IPublication <T> publication, IComputed <T> computed, Moment createdAt, bool isDisposed,
                         TaskSource <Unit> whenInvalidatedSource = default,
                         TaskSource <Unit> whenOutdatedSource    = default)
 {
     if (whenInvalidatedSource.IsEmpty)
     {
         whenInvalidatedSource = TaskSource.New <Unit>(true);
     }
     if (whenOutdatedSource.IsEmpty)
     {
         whenOutdatedSource = TaskSource.New <Unit>(true);
     }
     Publication           = publication;
     CreatedAt             = createdAt;
     IsDisposed            = isDisposed;
     WhenInvalidatedSource = whenInvalidatedSource;
     WhenOutdatedSource    = whenOutdatedSource;
     Computed              = computed;
     computed.Invalidated += _ => WhenInvalidatedSource.TrySetResult(default);
Beispiel #15
0
 protected override ILiveState <T> CreateState()
 => StateFactory.NewLive <T>(ConfigureState, async(_, ct) => {
     // Default CreateState synchronizes ComputeStateAsync call
     // as per https://github.com/servicetitan/Stl.Fusion/issues/202
     // You can override it to implement a version w/o sync.
     var ts = TaskSource.New <T>(false);
     await InvokeAsync(async() => {
         try {
             ts.TrySetResult(await ComputeStateAsync(ct));
         }
         catch (OperationCanceledException) {
             ts.TrySetCanceled();
         }
         catch (Exception e) {
             ts.TrySetException(e);
         }
     });
     return(await ts.Task.ConfigureAwait(false));
 }, this);
        public static async Task <FileSystemEventArgs> FirstAsync(
            this FileSystemWatcher watcher,
            TaskCreationOptions taskCreationOptions,
            CancellationToken cancellationToken = default)
        {
            var ts      = TaskSource.New <FileSystemEventArgs>(taskCreationOptions);
            var handler = (FileSystemEventHandler)((sender, args) => ts.TrySetResult(args));

            try {
                watcher.Changed += handler;
                watcher.Created += handler;
                watcher.Deleted += handler;
                return(await ts.Task.WithFakeCancellation(cancellationToken).ConfigureAwait(false));
            }
            finally {
                watcher.Changed -= handler;
                watcher.Created -= handler;
                watcher.Deleted -= handler;
            }
        }
Beispiel #17
0
 public StateSnapshot(StateSnapshot <T> prevSnapshot, IComputed <T> computed)
 {
     State              = prevSnapshot.State;
     Computed           = computed;
     WhenUpdatingSource = TaskSource.New <Unit>(true);
     WhenUpdatedSource  = TaskSource.New <Unit>(true);
     if (computed.HasValue)
     {
         LatestNonErrorComputed = computed;
         UpdateCount            = 1 + prevSnapshot.UpdateCount;
         ErrorCount             = prevSnapshot.ErrorCount;
         RetryCount             = 0;
     }
     else
     {
         LatestNonErrorComputed = prevSnapshot.LatestNonErrorComputed;
         UpdateCount            = 1 + prevSnapshot.UpdateCount;
         ErrorCount             = 1 + prevSnapshot.ErrorCount;
         RetryCount             = 1 + prevSnapshot.RetryCount;
     }
 }
Beispiel #18
0
 protected override ILiveState <T> CreateState()
 => 0 != (Options & LiveComponentOptions.SynchronizeComputeState)
         ? StateFactory.NewLive <T>(ConfigureState,
                                    async(_, ct) => {
     // Synchronizes ComputeStateAsync call as per:
     // https://github.com/servicetitan/Stl.Fusion/issues/202
     var ts = TaskSource.New <T>(false);
     await InvokeAsync(async() => {
         try {
             ts.TrySetResult(await ComputeStateAsync(ct));
         }
         catch (OperationCanceledException) {
             ts.TrySetCanceled();
         }
         catch (Exception e) {
             ts.TrySetException(e);
         }
     });
     return(await ts.Task.ConfigureAwait(false));
 }, this)
         : StateFactory.NewLive <T>(ConfigureState,
                                    (_, ct) => ComputeStateAsync(ct), this);