Example #1
0
        protected void QueueImageLoadingTask(IImageLoaderTask task)
        {
            int position           = Interlocked.Increment(ref _currentPosition);
            var currentPendingTask = new PendingTask()
            {
                Position = position, ImageLoadingTask = task, FrameworkWrappingTask = CreateFrameworkTask(task)
            };

            PendingTask similarRunningTask = null;

            lock (_pendingTasksLock)
            {
                similarRunningTask = PendingTasks.FirstOrDefault(t => t.ImageLoadingTask.Key == task.Key);
                if (similarRunningTask == null)
                {
                    Interlocked.Increment(ref _statsTotalPending);
                    PendingTasks.Add(currentPendingTask);
                }
                else
                {
                    similarRunningTask.Position = position;
                }
            }

            if (similarRunningTask == null || !currentPendingTask.ImageLoadingTask.CanUseMemoryCache)
            {
                TakeFromPendingTasksAndRun();
            }
            else
            {
                WaitForSimilarTaskFinished(currentPendingTask, similarRunningTask);
            }
        }
Example #2
0
        private async Task QueueTaskAsync(PendingTask pendingTask, bool scheduleOnThreadPool)
        {
            if (_currentlyRunning.Count >= MaxParallelTasks)
            {
                return;
            }

            if (!_currentlyRunning.TryAdd(pendingTask, 1))
            {
                return; // If we can't add it it most likely means that it's already in
            }
            try
            {
                if (scheduleOnThreadPool)
                {
                    await Task.Run(pendingTask.ImageLoadingTask.RunAsync).ConfigureAwait(false);
                }
                else
                {
                    await pendingTask.ImageLoadingTask.RunAsync().ConfigureAwait(false);
                }
            }
            finally
            {
                byte dummy;
                if (!_currentlyRunning.TryRemove(pendingTask, out dummy))
                {
                    _logger.Error("WorkScheduler: Could not remove task from running tasks.");
                }
            }

            await RunAsync().ConfigureAwait(false);
        }
Example #3
0
        private void QueueAndGenerateImage(IImageLoaderTask task)
        {
            _logger.Debug(string.Format("Generating/retrieving image: {0}", task.GetKey()));

            int position           = Interlocked.Increment(ref _currentPosition);
            var currentPendingTask = new PendingTask()
            {
                Position = position, ImageLoadingTask = task
            };

            var alreadyRunningTaskForSameKey = FindSimilarPendingTask(task);

            if (alreadyRunningTaskForSameKey == null)
            {
                if (!AddTaskToPendingTasks(currentPendingTask))
                {
                    return;
                }
            }
            else
            {
                alreadyRunningTaskForSameKey.Position = position;
            }

            if (alreadyRunningTaskForSameKey == null || !currentPendingTask.ImageLoadingTask.CanUseMemoryCache())
            {
                Run(currentPendingTask);
            }
            else
            {
                WaitForSimilarTask(currentPendingTask, alreadyRunningTaskForSameKey);
            }
        }
        private void QueueAndGenerateImage(IImageLoaderTask task)
        {
            _logger.Debug(string.Format("Generating/retrieving image: {0}", task.GetKey()));

            int position           = Interlocked.Increment(ref _currentPosition);
            var currentPendingTask = new PendingTask()
            {
                Position = position, ImageLoadingTask = task, FrameworkWrappingTask = CreateFrameworkTask(task)
            };

            PendingTask alreadyRunningTaskForSameKey = null;

            lock (_pendingTasksLock)
            {
                alreadyRunningTaskForSameKey = FindSimilarPendingTask(task);
                if (alreadyRunningTaskForSameKey == null)
                {
                    Interlocked.Increment(ref _statsTotalPending);
                    _pendingTasks.Add(currentPendingTask);
                }
                else
                {
                    alreadyRunningTaskForSameKey.Position = position;
                }
            }

            if (alreadyRunningTaskForSameKey == null || !currentPendingTask.ImageLoadingTask.CanUseMemoryCache())
            {
                Run(currentPendingTask);
            }
            else
            {
                WaitForSimilarTask(currentPendingTask, alreadyRunningTaskForSameKey);
            }
        }
Example #5
0
        private void QueueAndGenerateImage(IImageLoaderTask task)
        {
            _logger.Debug(string.Format("Generating/retrieving image: {0}", task.GetKey()));

            var currentPendingTask = new PendingTask()
            {
                ImageLoadingTask = task
            };
            PendingTask alreadyRunningTaskForSameKey = null;

            lock (_pauseWorkLock)
            {
                lock (_pendingTasksLock)
                {
                    alreadyRunningTaskForSameKey = _pendingTasks.FirstOrDefault(t => t.ImageLoadingTask.GetKey() == task.GetKey() && (!t.ImageLoadingTask.IsCancelled));
                    if (alreadyRunningTaskForSameKey == null)
                    {
                        _pendingTasks.Add(currentPendingTask);
                    }
                }
            }

            if (alreadyRunningTaskForSameKey == null || !currentPendingTask.ImageLoadingTask.CanUseMemoryCache())
            {
                Run(currentPendingTask);
            }
            else
            {
                WaitForSimilarTask(currentPendingTask, alreadyRunningTaskForSameKey);
            }
        }
Example #6
0
        bool TryTakeNewTask()
        {
            Uri navigateTo;

            lock (syncRoot)
            {
                if (currentTask != null || browserState != BrowserState.Ready)
                {
                    return(false);
                }
                for (; tasks.Count > 0 && currentTask == null;)
                {
                    var task = tasks.Dequeue();
                    if (!CompletePromiseIfCancellationRequested(task))
                    {
                        currentTask = task;
                    }
                }
                if (currentTask == null)
                {
                    return(false);
                }
                tracer.Info("taking new task {0}", currentTask);
                currentTask.cancellationRegistration = currentTask.cancellation.Register(
                    OnTaskCancelled, useSynchronizationContext: false);
                currentTask.progressSink = currentTask.progress != null?currentTask.progress.CreateProgressSink() : null;

                navigateTo = currentTask.location;
                SetBroswerState(BrowserState.Busy);
            }
            downloaderFormNavigationTask = uiInvokeSynchronization.Invoke(() => downloaderForm.Navigate(navigateTo));
            return(true);
        }
 public void TearDown()
 {
     _taskScheduler.Dispose();
     PendingTask.GetActivePeriodicTimersCount().Should().Be(0);
     PendingTask.GetActivePeriodicSlTimersCount().Should().Be(0);
     PendingTask.GetExecutingActionsCount().Should().Be(0);
     PendingTask.GetActiveTimersCount().Should().Be(0);
 }
Example #8
0
        protected void QueueImageLoadingTask(IImageLoaderTask task)
        {
            int position           = Interlocked.Increment(ref _currentPosition);
            var currentPendingTask = new PendingTask()
            {
                Position = position, ImageLoadingTask = task, FrameworkWrappingTask = CreateFrameworkTask(task)
            };

            if (task.IsCancelled || task.IsCompleted || ExitTasksEarly)
            {
                task?.Dispose();
                return;
            }

            PendingTask similarRunningTask = null;

            lock (_pendingTasksLock)
            {
                if (!task.Parameters.Preload)
                {
                    foreach (var pendingTask in PendingTasks.ToList()) // FMT: here we need a copy since cancelling will trigger them to be removed, hence collection is modified during enumeration
                    {
                        if (pendingTask.ImageLoadingTask != null && pendingTask.ImageLoadingTask.UsesSameNativeControl(task))
                        {
                            pendingTask.ImageLoadingTask.CancelIfNeeded();
                        }
                    }

                    EvictStaleTasks();
                }

                similarRunningTask = PendingTasks.FirstOrDefault(t => t.ImageLoadingTask.Key == task.Key);
                if (similarRunningTask == null)
                {
                    Interlocked.Increment(ref _statsTotalPending);
                    PendingTasks.Add(currentPendingTask);
                }
                else
                {
                    similarRunningTask.Position = position;
                }
            }

            if (PauseWork)
            {
                return;
            }

            if (similarRunningTask == null || !currentPendingTask.ImageLoadingTask.CanUseMemoryCache)
            {
                TakeFromPendingTasksAndRun();
            }
            else
            {
                WaitForSimilarTaskFinished(currentPendingTask, similarRunningTask);
            }
        }
        public async Task ActiveTimerEndsTest()
        {
            PendingTask.GetActiveTimersCount().Should().Be(0);
            _taskScheduler.Schedule(() => { Thread.Sleep(100); }, 10);
            PendingTask.GetActiveTimersCount().Should().Be(1);
            await Task.Delay(200);

            PendingTask.GetActiveTimersCount().Should().Be(0);
        }
 /// <summary>
 ///     Enqueues the given task to this scheduler: It will be executed
 ///     once all previous tasks have finished or failed.
 /// </summary>
 /// <param name="fn"></param>
 /// <param name="completionSource"></param>
 public void QueueTask(Action fn, TaskCompletionSource <int> completionSource)
 {
     lock (_syncRoot)
     {
         var  pendingTask = new PendingTask(fn, completionSource);
         Task task        = pendingTask.Task;
         EnqueueTask(pendingTask, task);
         StarTaskIfNecessary();
     }
 }
Example #11
0
 bool CompletePromiseIfCancellationRequested(PendingTask task)
 {
     if (!task.cancellation.IsCancellationRequested)
     {
         return(false);
     }
     tracer.Info("completing task {0} with TaskCanceledException as its cancellation was requested", task);
     task.promise.SetException(new TaskCanceledException());
     task.Dispose();
     return(true);
 }
        private void CollectMemoryAndThreadsUsage()
        {
            Metrics.Measure.Histogram.Update(Gen0Collections, GC.CollectionCount(0));
            Metrics.Measure.Histogram.Update(Gen1Collections, GC.CollectionCount(1));
            Metrics.Measure.Histogram.Update(Gen2Collections, GC.CollectionCount(2));
            Metrics.Measure.Histogram.Update(GcTotalMemory, GC.GetTotalMemory(false));

            Metrics.Measure.Histogram.Update(PendingTasks, TaskScheduler.GetGlobalScheduledOnceTasksCount());
            Metrics.Measure.Histogram.Update(ExecutingTask, PendingTask.GetExecutingActionsCount());
            Metrics.Measure.Histogram.Update(ActiveTimers, PendingTask.GetActiveTimersCount());
            Metrics.Measure.Histogram.Update(ActivePeriodicTimers, PendingTask.GetActivePeriodicTimersCount());
            Metrics.Measure.Histogram.Update(ActivePeriodicSlTimers, PendingTask.GetActivePeriodicSlTimersCount());
        }
Example #13
0
        async Task <Stream> IDownloader.Download(DownloadParams downloadParams)
        {
            if (downloadParams.CacheMode == CacheMode.AllowCacheReading || downloadParams.CacheMode == CacheMode.DownloadFromCacheOnly)
            {
                var cachedValue = cache.GetValue(downloadParams.Location);
                if (cachedValue != null)
                {
                    tracer.Info("found in cache content for location='{0}'", downloadParams.Location);
                    return(cachedValue);
                }
                if (downloadParams.CacheMode == CacheMode.DownloadFromCacheOnly)
                {
                    return(null);
                }
            }
            var task = new PendingTask()
            {
                location         = downloadParams.Location,
                expectedMimeType = downloadParams.ExpectedMimeType,
                cancellation     = downloadParams.Cancellation,
                progress         = downloadParams.Progress,
                isLoginUrl       = downloadParams.IsLoginUrl,
                stream           = new MemoryStream(),
                promise          = new TaskCompletionSource <Stream>(),
            };

            lock (syncRoot)
            {
                tracer.Info("new task {0} added for location='{1}'", task, task.location);
                tasks.Enqueue(task);
            }
            TryTakeNewTask();
            var stream = await task.promise.Task;

            if (stream != null)
            {
                bool setCache = true;
                if (downloadParams.AllowCacheWriting != null)
                {
                    stream.Position = 0;
                    setCache        = downloadParams.AllowCacheWriting(stream);
                }
                if (setCache)
                {
                    stream.Position = 0;
                    await cache.SetValue(downloadParams.Location, stream);
                }
                stream.Position = 0;
            }
            return(stream);
        }
        public void TestActionExecutionCounting()
        {
            using (var taskScheduler2 = new TaskScheduler(Mock.Of <IShamanLogger>()))
            {
                _taskScheduler.Schedule(() => { Thread.Sleep(100); }, 10);
                _taskScheduler.Schedule(() => { Thread.Sleep(100); }, 10);
                taskScheduler2.Schedule(() => { Thread.Sleep(100); }, 10);
                Thread.Sleep(20);

                // schedulers tasks triggers only in second
                PendingTask.GetExecutingActionsCount().Should().Be(3);
            }
            Thread.Sleep(100);// wait task ends
        }
Example #15
0
        public static string ToColor(this PendingTask pendingTask, Priority priority)
        {
            switch (priority)
            {
            case Priority.Urgent: return("#f00");

            case Priority.High: return("#f80");

            case Priority.Normal: return("#0c0");

            case Priority.Low: return("#0f8");

            default: return("transparent");
            }
        }
Example #16
0
 void IViewEvents.OnAborted()
 {
     lock (syncRoot)
     {
         tracer.Info("OnAborted. current task={0}", currentTask);
         if (currentTask != null)
         {
             currentTask.promise.SetException(new TaskCanceledException());
             currentTask.Dispose();
             currentTask = null;
         }
     }
     ResetBrowser();
     TryTakeNewTask();
 }
Example #17
0
        protected async Task RunImageLoadingTaskAsync(PendingTask pendingTask)
        {
            var key = pendingTask.ImageLoadingTask.Key;

            lock (_pendingTasksLock)
            {
                if (RunningTasks.ContainsKey(key))
                    return;

                RunningTasks.Add(key, pendingTask);
                Interlocked.Increment(ref _statsTotalRunning);
            }

            try
            {
                if (Configuration.VerbosePerformanceLogging)
                {
                    LogSchedulerStats();
                    var stopwatch = Stopwatch.StartNew();

                    await Task.Run(pendingTask.ImageLoadingTask.RunAsync).ConfigureAwait(false);

                    stopwatch.Stop();

                    Logger.Debug(
                        string.Format(
                            "[PERFORMANCE] RunAsync - NetManagedThreadId: {0}, NativeThreadId: {1}, Execution: {2} ms, Key: {3}",
                            Performance.GetCurrentManagedThreadId(),
                            Performance.GetCurrentSystemThreadId(),
                            stopwatch.Elapsed.Milliseconds,
                            key));
                }
                else
                {
                    await Task.Run(pendingTask.ImageLoadingTask.RunAsync).ConfigureAwait(false);
                }
            }
            finally
            {
                lock (_pendingTasksLock)
                {
                    RunningTasks.Remove(key);
                }
                pendingTask?.ImageLoadingTask?.Dispose();

                await TakeFromPendingTasksAndRunAsync().ConfigureAwait(false);
            }
        }
Example #18
0
        public void AddPendingTask(PendingTask pendingTask)
        {
            if (pendingTask == null)
            {
                throw new NullReferenceException("Null Task Provided");
            }

            if (!_shouldSchedule)
            {
                pendingTask.Invoke();
            }
            else
            {
                _pendingTasks.Add(pendingTask);
            }
        }
        public void TaskCountingDelayedTasksTest()
        {
            using (var taskScheduler2 = new TaskScheduler(Mock.Of <IShamanLogger>()))
            {
                _taskScheduler.Schedule(() => { Thread.Sleep(100); }, 10);
                _taskScheduler.Schedule(() => { Thread.Sleep(100); }, 10);
                _taskScheduler.Schedule(() => { Thread.Sleep(100); }, 10);
                _taskScheduler.Schedule(() => { Thread.Sleep(100); }, 10);

                PendingTask.GetActiveTimersCount().Should().Be(4);

                taskScheduler2.Schedule(() => { Thread.Sleep(100); }, 10);

                PendingTask.GetActiveTimersCount().Should().Be(5);
            }
        }
Example #20
0
        public static string EffortForDisplay(this PendingTask pendingTask)
        {
            var effort = ""; if (pendingTask.Status == Status.Completed)

            {
                if (pendingTask.StartDate.HasValue && pendingTask.CompletionDate.HasValue)
                {
                    var ts = pendingTask.CompletionDate.Value - pendingTask.StartDate.Value; if (ts.Days <= 0)
                    {
                        return("Less than a day");
                    }
                    effort = String.Format("{0} day(s)", ts.Days);
                }
            }
            return(effort);
        }
Example #21
0
        private async void WaitForSimilarTask(PendingTask currentPendingTask, PendingTask alreadyRunningTaskForSameKey)
        {
            string key = alreadyRunningTaskForSameKey.ImageLoadingTask.GetKey();

            Action forceLoad = () =>
            {
                lock (_pauseWorkLock)
                {
                    lock (_pendingTasksLock)
                    {
                        _pendingTasks.Add(currentPendingTask);
                    }
                }

                Run(currentPendingTask);
            };

            if (alreadyRunningTaskForSameKey.FrameworkWrappingTask == null)
            {
                _logger.Debug(string.Format("No C# Task defined for key: {0}", key));
                forceLoad();
                return;
            }

            _logger.Debug(string.Format("Wait for similar request for key: {0}", key));
            // This will wait for the pending task or if it is already finished then it will just pass
            await alreadyRunningTaskForSameKey.FrameworkWrappingTask.ConfigureAwait(false);

            // Now our image should be in the cache
            var cacheResult = await currentPendingTask.ImageLoadingTask.TryLoadingFromCacheAsync().ConfigureAwait(false);

            if (cacheResult != FFImageLoading.Cache.CacheResult.Found)
            {
                _logger.Debug(string.Format("Similar request finished but the image is not in the cache: {0}", key));
                forceLoad();
            }
            else
            {
                var task = currentPendingTask.ImageLoadingTask;
                if (task.Parameters.OnFinish != null)
                {
                    task.Parameters.OnFinish(task);
                }

                task.Dispose();
            }
        }
Example #22
0
        protected async void WaitForSimilarTaskFinished(PendingTask currentPendingTask, PendingTask taskForSimilarKey)
        {
            Interlocked.Increment(ref _statsTotalWaiting);

            if ((taskForSimilarKey?.FrameworkWrappingTask == null)
                || taskForSimilarKey.FrameworkWrappingTask.IsCanceled
                || taskForSimilarKey.FrameworkWrappingTask.IsFaulted)
            {
                lock (_pendingTasksLock)
                {
                    Interlocked.Increment(ref _statsTotalPending);
                    PendingTasks.Add(currentPendingTask);
                }

                TakeFromPendingTasksAndRun();
                return;
            }

            Logger.Debug(string.Format("Wait for similar request for key: {0}", taskForSimilarKey.ImageLoadingTask.Key));
            await taskForSimilarKey.FrameworkWrappingTask.ConfigureAwait(false);

            if ((currentPendingTask?.ImageLoadingTask == null) || currentPendingTask.ImageLoadingTask.IsCancelled)
                return;

            // Now our image should be in the cache
            var cacheFound =
                await currentPendingTask.ImageLoadingTask.TryLoadFromMemoryCacheAsync().ConfigureAwait(false);

            if (!cacheFound)
            {
                if ((currentPendingTask?.ImageLoadingTask == null) || currentPendingTask.ImageLoadingTask.IsCancelled)
                    return;

                lock (_pendingTasksLock)
                {
                    Interlocked.Increment(ref _statsTotalPending);
                    PendingTasks.Add(currentPendingTask);
                }

                TakeFromPendingTasksAndRun();
            }
            else
            {
                currentPendingTask?.ImageLoadingTask?.Dispose();
            }
        }
Example #23
0
        public void Handle(TaskCreatedEvent message)
        {
            var task = new PendingTask
            {
                TaskId      = message.TaskId,
                Title       = message.Title,
                Description = message.Description,
                DueDate     = message.DueDate,
                Priority    = message.Priority,
                Status      = Status.ToDo   // Default status for new tasks (by design)
            };

            using (var context = new TaskContext())
            {
                context.PendingTasks.Add(task);
                context.SaveChanges();
            }
        }
        public void TaskCountingPeriodShortLivingTasksTest()
        {
            using (var taskScheduler2 = new TaskScheduler(Mock.Of <IShamanLogger>()))
            {
                _taskScheduler.ScheduleOnInterval(() => { Thread.Sleep(100); }, 10, 10, true);
                _taskScheduler.ScheduleOnInterval(() => { Thread.Sleep(100); }, 10, 10, true);
                _taskScheduler.ScheduleOnInterval(() => { Thread.Sleep(100); }, 10, 10, true);
                _taskScheduler.ScheduleOnInterval(() => { Thread.Sleep(100); }, 10, 10, true);

                PendingTask.GetActivePeriodicTimersCount().Should().Be(TaskSchedulerInternalPeriodicTimersCount);
                PendingTask.GetActivePeriodicSlTimersCount().Should().Be(4);

                taskScheduler2.ScheduleOnInterval(() => { Thread.Sleep(100); }, 10, 10, true);

                PendingTask.GetActivePeriodicTimersCount().Should().Be(TaskSchedulerInternalPeriodicTimersCount);
                PendingTask.GetActivePeriodicSlTimersCount().Should().Be(5);
            }
        }
Example #25
0
        private bool AddTaskToPendingTasks(PendingTask task)
        {
            if (!_pendingTasks.TryAdd(task.ImageLoadingTask.GetKey(), task))
            {
                _logger.Error("Unable to schedule image task: task cannot be added to pending tasks queue.");
                return(false);
            }

            // Try adding the task by raw key, since many tasks can share the same raw key this may fail
            string rawKey = task.ImageLoadingTask.GetKey(raw: true);

            if (!_pendingTasksByRawKey.TryAdd(rawKey, task))
            {
                _logger.Debug("There is already a task in pendingTasksByRawKey with this raw key.");
            }

            return(true);
        }
 void IViewModel.OnFormSubmitted(IReadOnlyList <KeyValuePair <string, string> > values)
 {
     lock (syncRoot)
     {
         tracer.Info("OnFormSubmitted. current task={0}", currentTask);
         if (currentTask is UploadFormTask uploadFormTask)
         {
             uploadFormTask.promise.SetResult(values);
             currentTask.Dispose();
             currentTask = null;
         }
         else
         {
             return;
         }
     }
     ResetBrowser();
     TryTakeNewTask();
 }
        public async Task TestPendingTaskStopping()
        {
            _loggerMock.Setup(c => c.Error(It.Is <string>(v => v.Contains("SHORT-LIVING"))));

            var counter = 0;

            try
            {
                PendingTask.DurationMonitoringTime(TimeSpan.FromMilliseconds(200));
                var task = _taskScheduler.ScheduleOnInterval(() => counter++, 0, 100, true);

                await Task.Delay(500);

                _loggerMock.Verify(c => c.Error(It.Is <string>(v => v.Contains("SHORT-LIVING"))), Times.Once);
            }
            finally
            {
                PendingTask.DurationMonitoringTime(TimeSpan.FromMinutes(15));
            }

            counter.Should().Be(2);
        }
Example #28
0
        private async void Run(PendingTask pendingTask)
        {
            if (MaxParallelTasks <= 0)
            {
                pendingTask.FrameworkWrappingTask = pendingTask.ImageLoadingTask.RunAsync();                 // FMT: threadpool will limit concurrent work
                await pendingTask.FrameworkWrappingTask.ConfigureAwait(false);

                return;
            }

            var tcs = new TaskCompletionSource <bool>();

            var successCallback = pendingTask.ImageLoadingTask.Parameters.OnSuccess;

            pendingTask.ImageLoadingTask.Parameters.Success((size, result) =>
            {
                tcs.TrySetResult(true);

                if (successCallback != null)
                {
                    successCallback(size, result);
                }
            });

            var finishCallback = pendingTask.ImageLoadingTask.Parameters.OnFinish;

            pendingTask.ImageLoadingTask.Parameters.Finish(sw =>
            {
                tcs.TrySetResult(false);

                if (finishCallback != null)
                {
                    finishCallback(sw);
                }
            });

            pendingTask.FrameworkWrappingTask = tcs.Task;
            await RunAsync().ConfigureAwait(false);             // FMT: we limit concurrent work using MaxParallelTasks
        }
Example #29
0
        /// <summary>
        /// Constructors accepts the IP and port to listen for requests
        /// on and the instance that will process requests.
        /// </summary>
        public KernelWebHost(IWebRequestHandler handler, string listenIP, int listenPort)
        {
            ListenIP   = IPAddress.Parse(listenIP);
            ListenPort = listenPort;
            Handler    = handler;


            _server = new TcpListener(ListenIP, ListenPort);
            _server.Start();

            // start infinite continuation of checking the web server
#if DISABLE_WEB_TASK
#warning Web Server Task is DISABLED!!!!
#else
            _pendingTask = new PendingTask()
            {
                Parent = this
            };
#endif

            /*
             #warning I hate this thread.
             * new SingleThread()
             * {
             *  Name = "Restart web host scheduler",
             *  Step = () =>
             *  {
             *      if ((DateTime.Now - _pendingTask.LastRan).TotalSeconds > 2.5)
             *      {
             *          Session.UserSession.Current.Console.Add("Had to restart scheduler");
             *          _pendingTask.ScheduleTask();
             *      }
             *      Thread.Sleep(2500);
             *  },
             *  SleepAfterStep = true
             * }
             * .Start();
             */
        }
Example #30
0
 void OnTaskCancelled()
 {
     lock (syncRoot)
     {
         tracer.Info("task cancelled callback received");
         var cpy = tasks.ToArray();
         tasks.Clear();
         foreach (var task in cpy)
         {
             if (!CompletePromiseIfCancellationRequested(task))
             {
                 tasks.Enqueue(task);
             }
         }
         if (currentTask != null)
         {
             if (CompletePromiseIfCancellationRequested(currentTask))
             {
                 currentTask = null;
             }
         }
     }
 }
Example #31
0
		private async void Run(PendingTask pendingTask)
		{
			if (MaxParallelTasks <= 0)
			{
				pendingTask.FrameworkWrappingTask = pendingTask.ImageLoadingTask.RunAsync(); // FMT: threadpool will limit concurrent work
				await pendingTask.FrameworkWrappingTask.ConfigureAwait(false);
				return;
			}

			var tcs = new TaskCompletionSource<bool>();

			var successCallback = pendingTask.ImageLoadingTask.Parameters.OnSuccess;
			pendingTask.ImageLoadingTask.Parameters.Success((size, result) =>
			{
				tcs.TrySetResult(true);

				if (successCallback != null)
					successCallback(size, result);
			});

			var finishCallback = pendingTask.ImageLoadingTask.Parameters.OnFinish;
			pendingTask.ImageLoadingTask.Parameters.Finish(sw =>
			{
				tcs.TrySetResult(false);

				if (finishCallback != null)
					finishCallback(sw);
			});

			pendingTask.FrameworkWrappingTask = tcs.Task;
			await RunAsync().ConfigureAwait(false); // FMT: we limit concurrent work using MaxParallelTasks
		}
Example #32
0
		private async void WaitForSimilarTask(PendingTask currentPendingTask, PendingTask alreadyRunningTaskForSameKey)
		{
			string key = alreadyRunningTaskForSameKey.ImageLoadingTask.GetKey();

			Action forceLoad = () =>
			{
				lock (_pauseWorkLock)
				{
					lock(_pendingTasksLock)
					{
						_pendingTasks.Add(currentPendingTask);
					}
				}

				Run(currentPendingTask);
			};

			if (alreadyRunningTaskForSameKey.FrameworkWrappingTask == null)
			{
				_logger.Debug(string.Format("No C# Task defined for key: {0}", key));
				forceLoad();
				return;
			}

			_logger.Debug(string.Format("Wait for similar request for key: {0}", key));
			// This will wait for the pending task or if it is already finished then it will just pass
			await alreadyRunningTaskForSameKey.FrameworkWrappingTask.ConfigureAwait(false);

			// Now our image should be in the cache
			var cacheResult = await currentPendingTask.ImageLoadingTask.TryLoadingFromCacheAsync().ConfigureAwait(false);
			if (cacheResult != FFImageLoading.Cache.CacheResult.Found)
			{
				_logger.Debug(string.Format("Similar request finished but the image is not in the cache: {0}", key));
				forceLoad();
			}
			else
			{
				var task = currentPendingTask.ImageLoadingTask;
				if (task.Parameters.OnFinish != null)
					task.Parameters.OnFinish(task);

				task.Dispose();
			}
		}
Example #33
0
		private void QueueAndGenerateImage(IImageLoaderTask task)
		{
			_logger.Debug(string.Format("Generating/retrieving image: {0}", task.GetKey()));

			var currentPendingTask = new PendingTask() { ImageLoadingTask = task };
			PendingTask alreadyRunningTaskForSameKey = null;
			lock (_pauseWorkLock)
			{
				lock (_pendingTasksLock)
				{
					alreadyRunningTaskForSameKey = _pendingTasks.FirstOrDefault(t => t.ImageLoadingTask.GetKey() == task.GetKey() && (!t.ImageLoadingTask.IsCancelled));
					if (alreadyRunningTaskForSameKey == null)
						_pendingTasks.Add(currentPendingTask);
				}
			}

			if (alreadyRunningTaskForSameKey == null || !currentPendingTask.ImageLoadingTask.CanUseMemoryCache())
			{
				Run(currentPendingTask);
			}
			else
			{
				WaitForSimilarTask(currentPendingTask, alreadyRunningTaskForSameKey);
			}
		}
Example #34
0
        private void QueueAndGenerateImage(IImageLoaderTask task)
        {
            _logger.Debug(string.Format("Generating/retrieving image: {0}", task.GetKey()));

            int position = Interlocked.Increment(ref _currentPosition);
            var currentPendingTask = new PendingTask() { Position = position, ImageLoadingTask = task, FrameworkWrappingTask = CreateFrameworkTask(task) };

            PendingTask alreadyRunningTaskForSameKey = null;
            lock (_pendingTasksLock)
            {
                alreadyRunningTaskForSameKey = FindSimilarPendingTask(task);
                if (alreadyRunningTaskForSameKey == null)
                {
                    Interlocked.Increment(ref _statsTotalPending);
                    _pendingTasks.Add(currentPendingTask);
                }
                else
                {
                    alreadyRunningTaskForSameKey.Position = position;
                }
            }

            if (alreadyRunningTaskForSameKey == null || !currentPendingTask.ImageLoadingTask.CanUseMemoryCache())
            {
                Run(currentPendingTask);
            }
            else
            {
                WaitForSimilarTask(currentPendingTask, alreadyRunningTaskForSameKey);
            }
        }
Example #35
0
 private async void Run(PendingTask pendingTask)
 {
     await RunAsync().ConfigureAwait(false); // FMT: we limit concurrent work using MaxParallelTasks
 }
Example #36
0
        private async Task QueueTaskAsync(PendingTask pendingTask, bool scheduleOnThreadPool)
        {
            lock (_pendingTasksLock)
            {
                if (_currentlyRunning.Count >= _maxParallelTasks)
                    return;
            }

            string key = pendingTask.ImageLoadingTask.GetKey();

            try
            {
                PendingTask alreadyRunningTask = null;

                lock (_pendingTasksLock)
                {
                    if (!_currentlyRunning.ContainsKey(key))
                    {
                        _currentlyRunning.Add(key, pendingTask);
                        Interlocked.Increment(ref _statsTotalRunning);
                    }
                    else
                    {
                        alreadyRunningTask = _currentlyRunning[key];

                        // duplicate - return
                        if (pendingTask == alreadyRunningTask)
                            return;
                    }
                }

                if (alreadyRunningTask != null)
                {
                    WaitForSimilarTask(pendingTask, alreadyRunningTask);
                    return;
                }

                if (_verbosePerformanceLogging)
                {
                    Stopwatch stopwatch = Stopwatch.StartNew();

                    if (scheduleOnThreadPool)
                    {
                        await Task.Run(pendingTask.ImageLoadingTask.RunAsync).ConfigureAwait(false);
                    }
                    else
                    {
                        await pendingTask.ImageLoadingTask.RunAsync().ConfigureAwait(false);
                    }

                    stopwatch.Stop();

                    LogSchedulerStats();
                    _logger.Debug(string.Format("[PERFORMANCE] RunAsync - NetManagedThreadId: {0}, NativeThreadId: {1}, Execution: {2} ms, ThreadPool: {3}, Key: {4}",
                                                _performance.GetCurrentManagedThreadId(),
                                                _performance.GetCurrentSystemThreadId(),
                                                stopwatch.Elapsed.Milliseconds,
                                                scheduleOnThreadPool,
                                                key));
                }
                else
                {
                    if (scheduleOnThreadPool)
                    {
                        await Task.Run(pendingTask.ImageLoadingTask.RunAsync).ConfigureAwait(false);
                    }
                    else
                    {
                        await pendingTask.ImageLoadingTask.RunAsync().ConfigureAwait(false);
                    }
                }
            }
            finally
            {
                lock (_pendingTasksLock)
                {
                    _currentlyRunning.Remove(key);
                }

                await RunAsync().ConfigureAwait(false);
            }
        }
        protected void QueueImageLoadingTask(IImageLoaderTask task)
        {
            int position = Interlocked.Increment(ref _currentPosition);
            var currentPendingTask = new PendingTask() { Position = position, ImageLoadingTask = task, FrameworkWrappingTask = CreateFrameworkTask(task) };

            if (task.IsCancelled || task.IsCompleted || ExitTasksEarly)
            {
                task?.Dispose();
                return;
            }

            PendingTask similarRunningTask = null;
            lock (_pendingTasksLock)
            {
                if (!task.Parameters.Preload)
                {
                    foreach (var pendingTask in PendingTasks.ToList()) // FMT: here we need a copy since cancelling will trigger them to be removed, hence collection is modified during enumeration
                    {
                        if (pendingTask.ImageLoadingTask != null && pendingTask.ImageLoadingTask.UsesSameNativeControl(task))
                            pendingTask.ImageLoadingTask.CancelIfNeeded();
                    }

                    EvictStaleTasks();
                }

                similarRunningTask = PendingTasks.FirstOrDefault(t => t.ImageLoadingTask.Key == task.Key);
                if (similarRunningTask == null)
                {
                    Interlocked.Increment(ref _statsTotalPending);
                    PendingTasks.Add(currentPendingTask);
                }
                else
                {
                    similarRunningTask.Position = position;
                }
            }

            if (PauseWork)
                return;

            if (similarRunningTask == null || !currentPendingTask.ImageLoadingTask.CanUseMemoryCache)
            {
                TakeFromPendingTasksAndRun();
            }
            else
            {
                WaitForSimilarTaskFinished(currentPendingTask, similarRunningTask);
            }
        }
        protected async void WaitForSimilarTaskFinished(PendingTask currentPendingTask, PendingTask taskForSimilarKey)
        {
            Interlocked.Increment(ref _statsTotalWaiting);

            if (taskForSimilarKey.FrameworkWrappingTask == null)
            {
                lock (_pendingTasksLock)
                {
                    Interlocked.Increment(ref _statsTotalPending);
                    PendingTasks.Add(currentPendingTask);
                }

                TakeFromPendingTasksAndRun();
                return;
            }

            Logger.Debug(string.Format("Wait for similar request for key: {0}", taskForSimilarKey.ImageLoadingTask.Key));
            await taskForSimilarKey.FrameworkWrappingTask.ConfigureAwait(false);

            // Now our image should be in the cache
            var cacheFound = await currentPendingTask.ImageLoadingTask.TryLoadFromMemoryCacheAsync().ConfigureAwait(false);
            if (!cacheFound)
            {
                lock (_pendingTasksLock)
                {
                    Interlocked.Increment(ref _statsTotalPending);
                    PendingTasks.Add(currentPendingTask);
                }

                TakeFromPendingTasksAndRun();
                return;
            }
            else
            {
                currentPendingTask?.ImageLoadingTask?.Dispose();
            }
        }
        protected async Task RunImageLoadingTaskAsync(PendingTask pendingTask, bool scheduleOnThreadPool)
        {
            var key = pendingTask.ImageLoadingTask.Key;

            lock (_pendingTasksLock)
            {
                if (RunningTasks.ContainsKey(key))
                    return;
                
                RunningTasks.Add(key, pendingTask);
                Interlocked.Increment(ref _statsTotalRunning);
            }

            try
            {
                if (Configuration.VerbosePerformanceLogging)
                {
                    LogSchedulerStats();
                    Stopwatch stopwatch = Stopwatch.StartNew();

                    if (scheduleOnThreadPool)
                    {
                        await Task.Run(pendingTask.ImageLoadingTask.RunAsync).ConfigureAwait(false);
                    }
                    else
                    {
                        await pendingTask.ImageLoadingTask.RunAsync().ConfigureAwait(false);
                    }

                    stopwatch.Stop();

                    Logger.Debug(string.Format("[PERFORMANCE] RunAsync - NetManagedThreadId: {0}, NativeThreadId: {1}, Execution: {2} ms, ThreadPool: {3}, Key: {4}",
                                                Performance.GetCurrentManagedThreadId(),
                                                Performance.GetCurrentSystemThreadId(),
                                                stopwatch.Elapsed.Milliseconds,
                                                scheduleOnThreadPool,
                                                key));
                }
                else
                {
                    if (scheduleOnThreadPool)
                    {
                        await Task.Run(pendingTask.ImageLoadingTask.RunAsync).ConfigureAwait(false);
                    }
                    else
                    {
                        await pendingTask.ImageLoadingTask.RunAsync().ConfigureAwait(false);
                    }
                }
            }
            finally
            {
                lock (_pendingTasksLock)
                {
                    RunningTasks.Remove(key);
                }
                pendingTask?.ImageLoadingTask?.Dispose();

                await TakeFromPendingTasksAndRunAsync().ConfigureAwait(false);
            }
        }