Example #1
0
        public TareaProgramada UpdateIsActive(TareaProgramada entity, bool?isActive)
        {
            Check.NotNull(entity, nameof(entity));


            return(isActive.HasValue && isActive.Value ? entity.Activar() : entity.Desactivar());
        }
Example #2
0
        /// <summary>
        /// Programa finalizado
        /// </summary>
        /// <param name="prg"></param>
        void FinServicio(TareaProgramada prg, Exception ex)
        {
            lock (bloqueo)
            {
                log.Info($"Finalizando tarea {prg.ID}");

                // Avisamos que ha terminado
                OnFinTarea(prg.ID, prg.Tarea, ex);
                // Si es Auto borramos la tarea en si. No importa hacer dispose porque las tareas se registras como scoped
                if (prg.AutoCrear)
                {
                    prg.Tarea = null;
                }

                prg.Task            = null;
                prg.SiguienteInicio = prg.Programacion.SiguienteEjecucion(DateTime.Now);
                if (prg.SiguienteInicio == DateTime.MinValue)                                           // Si no es periodico, lo borramos
                {
                    log.Info($"Tarea {prg.ID} eliminada");
                    DesprogramaTarea(prg);
                }
                else
                {
                    log.Info($"Tarea {prg.ID} reprogramado para {prg.SiguienteInicio.FechaServidorFechaUsuario()}");
                }
                // Liberamos, la proxima llamada creara otro
                prg.CancellationTokenSource = null;
            }
            EscaneaTareas();
        }
Example #3
0
        /// <summary>
        /// Programa una tarea
        /// </summary>
        /// <param name="id"></param>
        /// <param name="tarea"></param>
        /// <param name="tarea"></param>
        /// <param name="tipoTarea"></param>
        /// <param name="procesosIncompatibles">Coleccion de IDs de tareas incompatibles</param>
        void ProgramaTarea(string id, ITarea tarea, Type tipoTarea, IProgramador programacion, IEnumerable <string> procesosIncompatibles = null)
        {
            if ((tarea == null && tipoTarea == null) || programacion == null)
            {
                throw new ArgumentException("La tarea y la programación deben especificarse");
            }

            if (tarea != null && tipoTarea != null)
            {
                throw new ArgumentException("Solo se puede especificar la tarea o su tipo");
            }

            if (tipoTarea != null && container == null)
            {
                throw new ArgumentException($"El contenedor es nulo y la tarea tipo {tipoTarea.Name} lo necesita");
            }

            if (tipoTarea != null && container.GetRegistration(tipoTarea) == null)
            {
                throw new ArgumentException($"El contenedor no conoce a {tipoTarea.Name}");
            }

            if (string.IsNullOrWhiteSpace(id))
            {
                throw new ArgumentException($"La tarea debe tener un Id unico");
            }

            log.Info($"Programando tarea {id} con el programador {programacion.GetType()}");

            DateTime primeraEjecucion = programacion.PrimeraEjecucion(DateTime.Now);

            if (primeraEjecucion < DateTime.Now.AddSeconds(-5))
            {
                log.Warn($"La tarea {id} ha caducado antes de iniciarse");
                return;
            }
            log.Info($"Servicio periodico registrado {id} en fecha {primeraEjecucion:g}");
            TareaProgramada prog = new TareaProgramada();

            prog.ID              = id;
            prog.Programacion    = programacion;
            prog.Tarea           = tarea;
            prog.TipoTarea       = tipoTarea;
            prog.SiguienteInicio = primeraEjecucion;
            if (procesosIncompatibles != null)
            {
                prog.ProcesosIncompatibles.AddRange(procesosIncompatibles);
            }
            lock (bloqueo)
            {
                if (tareasProgramadas.Where(x => x.ID == id).FirstOrDefault() != null)
                {
                    log.Warn($"La tarea {id} está duplicada");
                    return;
                }
                tareasProgramadas.Add(prog);
            }
            EscaneaTareas();
        }
Example #4
0
        public async Task <IScheduledTask> Create(ScheduledTaskDto dto)
        {
            TareaProgramada tarea = TareasProgramadaFactory.CrearTareaProgramada(dto.Name, dto.Identifier, dto.Cron).WithTimeout(dto.Timeout);

            UpdateIsActive(tarea, dto.IsActive);


            return(await this.Repository.InsertAsync(tarea));
        }
Example #5
0
        /// <summary>
        /// Elimina una tarea de la lista y si implementa IDisposable lo ejecuta sobre la tarea
        /// </summary>
        /// <param name="prg"></param>
        private void DesprogramaTarea(TareaProgramada prg)
        {
            IDisposable dsp = prg.Tarea as IDisposable;

            if (dsp != null)
            {
                dsp.Dispose();
            }
            tareasProgramadas.Remove(prg);
        }
Example #6
0
        /// <summary>
        /// Escanea las tareas y si hay programa el timer para la proxima en el tiempo
        /// </summary>
        private void EscaneaTareas()
        {
            // ¿Esta parado el servicio?
            if (!funcionando)
            {
                return;
            }

            log.Debug("Escaneando tareas en el programador");
            lock (bloqueo)
            {
                if (timer != null)
                {
                    timer.Dispose();
                    timer = null;
                }
                DateTime actuales  = DateTime.Now;
                var      siguiente = new TareaProgramada(); // Para simplificar la busqueda
                siguiente.SiguienteInicio = DateTime.MaxValue;
                foreach (TareaProgramada cls in tareasProgramadas)
                {
                    if (cls.SiguienteInicio <= actuales && !cls.Funcionando)
                    {
                        log.Warn($"Llegamos tarde a la tarea {cls.ID} y la lanzamos ahora");
                        Task.Run(() => EjecutaPrograma(cls));   // ¿Llegamos tarde? arrancamos ahora
                    }
                    else
                    {
                        if (cls.SiguienteInicio < siguiente.SiguienteInicio && !cls.Funcionando)
                        {
                            siguiente = cls;
                        }
                    }
                }
                if (siguiente.SiguienteInicio < DateTime.MaxValue)      // Si hemos encontrado algo, programamos el timer
                {
                    TimeSpan arranque = siguiente.SiguienteInicio - DateTime.Now;
                    if (arranque < TimeSpan.Zero)
                    {
                        arranque = TimeSpan.FromMilliseconds(50);       // Se ejecuta dentro de 50 ms
                    }
                    timer = new Timer(new TimerCallback(LanzadoTimer), siguiente, arranque, new TimeSpan(-1));
                }

                if (timer == null)
                {
                    log.Info("No hay mas servicios a programar");
                }
                else
                {
                    log.Info($"Proximo servicio nombre {siguiente.ID} programado para {siguiente.SiguienteInicio}");
                }
            }
        }
Example #7
0
        public async Task Delete(int id)
        {
            TareaProgramada tarea = await this.Repository.GetAsync(id);

            if (tarea == null)
            {
                throw new DataException("No existe la tarea programada con id: " + id);
            }


            await this.Repository.DeleteAsync(tarea);
        }
Example #8
0
        /// <summary>
        /// Hace la ejecucion de la tarea
        /// </summary>
        /// <param name="cls"></param>
        /// <param name="bloqueado"></param>
        /// <returns></returns>
        private async Task HazEjecutaTarea(TareaProgramada cls, bool bloqueado)
        {
            if (!bloqueado)
            {
                log.Info("La tarea no se ha podido bloquear, simulamos su ejecución por coherencia");
            }
            var scope = AseguraTarea(cls);

            try
            {
                OnInicioTarea(cls.ID, cls.Tarea);

                try
                {
                    log.Info($"Ejecutando {cls.ID}. Tarea bloqueada: {bloqueado}");

                    if (cls.Tarea != null)
                    {
                        if (bloqueado)
                        {
                            await cls.Tarea.Ejecutar(cls.CancellationTokenSource.Token).ConfigureAwait(false);
                        }
                    }
                    else
                    {
                        log.Error($"La tarea con ID {cls.ID} no se ha creado correctamente");
                    }

                    log.Info($"Fin de ejecucion {cls.ID}");

                    // Avisamos del fin de la tarea
                    FinServicio(cls, null);
                }
                catch (Exception ex)
                {
                    log.Error(ex, $"Error al ejecutar la tarea {cls.ID}");
                    FinServicio(cls, ex);
                }
            }
            finally
            {
                if (scope != null)
                {
                    scope.Dispose();
                }
            }
        }
Example #9
0
 Scope AseguraTarea(TareaProgramada cls)
 {
     if (cls.AutoCrear)
     {
         try
         {
             var scope = AsyncScopedLifestyle.BeginScope(container);
             cls.Tarea = container.GetInstance(cls.TipoTarea) as ITarea;
             return(scope);
         }
         catch (Exception ex)
         {
             log.Error(ex, $"Error creando la tarea con ID {cls.ID}");
         }
     }
     return(null);
 }
Example #10
0
        private void EjecutaPrograma(TareaProgramada cls)
        {
            lock (bloqueo)
            {
                log.Info($"Lanzando programa {cls.ID}");
                log.Debug("Comprobando si es incompatible con otra tarea en funcionamiento");

                if (cls.ProcesosIncompatibles.Count > 0)
                {
                    bool incompatibles = tareasProgramadas.Any(q => q.Funcionando && cls.ProcesosIncompatibles.Contains(q.ID));
                    if (incompatibles)
                    {
                        log.Warn($"Tarea {cls.ID} ha sido pospuesta");
                        cls.SiguienteInicio = DateTime.Now.AddMinutes(1);    // Posponemos un minuto
                        Task.Run(() => EscaneaTareas());                     // Buscamos otras posibles tareas a lanzar o simplemente reprogramamos
                        return;
                    }
                }

                var cs          = cls.CancellationTokenSource;
                var tareaActual = cls.Task = Task.Run(async() =>
                {
                    var bloqueado = await BlindaAsync(() => bloqueoTarea.BloqueaTareaAsync(cls.ID)).ConfigureAwait(false);
                    try
                    {
                        await HazEjecutaTarea(cls, bloqueado).ConfigureAwait(false);
                    }
                    finally
                    {
                        if (bloqueado)
                        {
                            await BlindaAsync(() => bloqueoTarea.DesBloqueaTareaAsync(cls.ID)).ConfigureAwait(false);
                        }
                    }
                }, cls.CancellationTokenSource.Token);
                // Cuando acabe, liberamos memoria
                cls.Task.ContinueWith((t) => {
                    // Liberamos el cancellation token
                    cs.Dispose();
                    // Liberamos recursos
                    tareaActual.Dispose();
                });
            }
        }
Example #11
0
        public async Task <IScheduledTask> Update(ScheduledTaskDto dto)
        {
            TareaProgramada entity = await this.Repository.GetAsync(dto.Id);

            if (entity == null)
            {
                throw new DataException("No existe la tarea programada con id : " + dto.Id);
            }

            entity.ConCron(dto.Cron);
            entity.ConIdentificador(dto.Identifier);
            entity.ConNombre(dto.Name);
            entity.WithTimeout(dto.Timeout);

            UpdateIsActive(entity, dto.IsActive);


            return(await this.Repository.UpdateAsync(entity));
        }