<commit_before>﻿using System;
using System.Collections.Concurrent;
using DotJEM.Web.Host.Diagnostics;
using DotJEM.Web.Host.Diagnostics.Performance;
using DotJEM.Web.Host.Providers.Scheduler.Tasks;

namespace DotJEM.Web.Host.Providers.Scheduler
{
    public interface IWebScheduler
    {
        IScheduledTask Schedule(IScheduledTask task);
        IScheduledTask ScheduleTask(string name, Action<bool> callback, TimeSpan interval);
        IScheduledTask ScheduleCallback(string name, Action<bool> callback, TimeSpan? timeout = null);
        IScheduledTask ScheduleCron(string name, Action<bool> callback, string trigger);
    }

    public class WebScheduler : IWebScheduler
    {
        private readonly ConcurrentDictionary<Guid, IScheduledTask> tasks = new ConcurrentDictionary<Guid, IScheduledTask>();

        private readonly IPerformanceLogger perf;
        private readonly IDiagnosticsLogger logger;

        public WebScheduler(IDiagnosticsLogger logger, IPerformanceLogger perf)
        {
            this.logger = logger;
            this.perf = perf;
        }

        public IScheduledTask Schedule(IScheduledTask task)
        {
            task.TaskException += HandleTaskException;
            task.TaskCompleted += HandleTaskCompleted;
            tasks.TryAdd(task.Id, task);
            return task.Start();
        }

        public IScheduledTask ScheduleTask(string name, Action<bool> callback, TimeSpan interval)
        {
            return Schedule(new PeriodicScheduledTask(name, callback, interval, perf));
        }

        public IScheduledTask ScheduleCallback(string name, Action<bool> callback, TimeSpan? timeout)
        {
            return Schedule(new SingleFireScheduledTask(name, callback, timeout, perf));
        }

        public IScheduledTask ScheduleCron(string name, Action<bool> callback, string trigger)
        {
            return Schedule(new CronScheduledTask(name, callback, trigger, perf));
        }

        private void HandleTaskCompleted(object sender, TaskEventArgs args)
        {
            IScheduledTask task;
            tasks.TryRemove(args.Task.Id, out task);
        }

        private void HandleTaskException(object sender, TaskExceptionEventArgs args)
        {
            logger.LogException(args.Exception, new
            {
                TaskName = args.Task.Name,
                TaskId = args.Task.Id
            });
        }
    }
}<commit_msg>Bouncing exception could force applicaiton down.<commit_after>﻿using System;
using System.Collections.Concurrent;
using DotJEM.Web.Host.Diagnostics;
using DotJEM.Web.Host.Diagnostics.Performance;
using DotJEM.Web.Host.Providers.Scheduler.Tasks;

namespace DotJEM.Web.Host.Providers.Scheduler
{
    public interface IWebScheduler
    {
        IScheduledTask Schedule(IScheduledTask task);
        IScheduledTask ScheduleTask(string name, Action<bool> callback, TimeSpan interval);
        IScheduledTask ScheduleCallback(string name, Action<bool> callback, TimeSpan? timeout = null);
        IScheduledTask ScheduleCron(string name, Action<bool> callback, string trigger);
    }

    public class WebScheduler : IWebScheduler
    {
        private readonly ConcurrentDictionary<Guid, IScheduledTask> tasks = new ConcurrentDictionary<Guid, IScheduledTask>();

        private readonly IPerformanceLogger perf;
        private readonly IDiagnosticsLogger logger;

        public WebScheduler(IDiagnosticsLogger logger, IPerformanceLogger perf)
        {
            this.logger = logger;
            this.perf = perf;
        }

        public IScheduledTask Schedule(IScheduledTask task)
        {
            task.TaskException += HandleTaskException;
            task.TaskCompleted += HandleTaskCompleted;
            tasks.TryAdd(task.Id, task);
            return task.Start();
        }

        public IScheduledTask ScheduleTask(string name, Action<bool> callback, TimeSpan interval)
        {
            return Schedule(new PeriodicScheduledTask(name, callback, interval, perf));
        }

        public IScheduledTask ScheduleCallback(string name, Action<bool> callback, TimeSpan? timeout)
        {
            return Schedule(new SingleFireScheduledTask(name, callback, timeout, perf));
        }

        public IScheduledTask ScheduleCron(string name, Action<bool> callback, string trigger)
        {
            return Schedule(new CronScheduledTask(name, callback, trigger, perf));
        }

        private void HandleTaskCompleted(object sender, TaskEventArgs args)
        {
            IScheduledTask task;
            tasks.TryRemove(args.Task.Id, out task);
        }

        private void HandleTaskException(object sender, TaskExceptionEventArgs args)
        {
            try
            {
                logger.LogException(args.Exception, new
                {
                    TaskName = args.Task.Name,
                    TaskId = args.Task.Id
                });
            }
            catch (Exception)
            {
                //ignore
                //TODO: (jmd 2015-09-30) Ohh shit, log to the event log or something!. 
            }
        }
    }
}
{'fraction_non_alphanumeric': 0.07651869158878505, 'fraction_numerical': 0.001557632398753894, 'mean_word_length': 2.4361204013377926, 'pattern_counts': {'":': 0, '<': 19, '<?xml version=': 0, '>': 19, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '3131560', 'n_tokens_mistral': 1295, 'n_tokens_neox': 1275, 'n_words': 313}