public bool IsRunnable(IWhenDoJob job, IWhenDoMessage message)
        {
            if (job.Disabled)
            {
                return(false);
            }
            if (job.DisabledFrom.HasValue && job.DisabledTill.HasValue)
            {
                var time = dtp.CurrentTime;
                if (time > job.DisabledFrom.Value && time < job.DisabledTill.Value)
                {
                    return(false);
                }
            }

            if (message != null && !job.Condition.RequiresMessage(message))
            {
                return(false);
            }

            var providers = GetExpressionProviderInstancesForDelegate(job.Condition, message);

            if (!(bool)job.Condition.DynamicInvoke(providers.ToArray()))
            {
                return(false);
            }
            return(true);
        }
示例#2
0
        public bool GetMessage(out IWhenDoMessage message)
        {
            var success = queue.TryDequeue(out IWhenDoMessage result);

            message = result;
            return(success);
        }
 public static bool RequiresMessage(this Delegate del, IWhenDoMessage message)
 {
     foreach (var parameter in del.Method.GetParameters())
     {
         if (parameter.ParameterType.Name == message.GetType().Name)
         {
             return(true);
         }
     }
     return(false);
 }
 public async Task SaveAsync(IWhenDoMessage context)
 {
     try
     {
         var message = (MySensorsDataMessage)context;
         await sensorDataService.SaveAsync(message.ToStorage());
     }
     catch (Exception ex)
     {
         logger.LogError(ex, $"Error storing sensor data message in storage {sensorDataService.Id}", context);
     }
 }
示例#5
0
        public async Task ExecuteAsync(IWhenDoMessage context, string jobId, string commandId)
        {
            var job = await repository.GetByIdAsync(jobId);

            if (job == null)
            {
                throw new ArgumentException($"Job {jobId} not found in repository.");
            }
            var command = job.Commands.Where(x => x.Id == commandId).FirstOrDefault();

            if (command == null)
            {
                throw new ArgumentException($"Job {jobId} does not contain command {commandId}");
            }

            var commandHandler = registry.GetCommandHandler(command.Type);

            try
            {
                var method = FindMethod(commandHandler, command.MethodName, command.Parameters == null ? 0 : command.Parameters.Count);

                if (method == null)
                {
                    throw new InvalidCommandException($"Could not find method {command.MethodName} in type {command.Type}"
                                                      + " with {command.Parameters.Count} parameters", command.Parameters.Keys);
                }

                var invocationParams = new List <object>();
                var methodParams     = method.GetParameters();

                foreach (var param in methodParams)
                {
                    if (param.ParameterType.Equals(typeof(IWhenDoMessage)))
                    {
                        invocationParams.Add(context);
                    }
                    else
                    {
                        invocationParams.Add(command.Parameters[param.Name]);
                    }
                }

                await(Task) method.Invoke(commandHandler, invocationParams.ToArray());

                logger.LogTrace($"Succesfully executed {command.Type}");
            }
            catch (KeyNotFoundException ex)
            {
                throw new InvalidCommandException("Invalid command, could not find required parameters", command.Parameters.Keys, ex);
            }
        }
        public async Task HandleAsync(IWhenDoMessage message)
        {
            try
            {
                var jobs = await jobRepository.GetAsync(x => x.Type == JobType.Message && IsRunnable(x, message));

                if (jobs.Any())
                {
                    foreach (var job in jobs)
                    {
                        ExecuteJob(job, message);
                    }
                }
                else
                {
                    logger.LogInformation("No jobs to be executed for message {message}", message);
                }
            }
            catch (Exception ex)
            {
                logger.LogError(ex, "Error processing queue message: {error}", message);
            }
        }
        public void ExecuteJob(IWhenDoJob job, IWhenDoMessage context)
        {
            if (job.Commands.Count() == 0)
            {
                logger.LogWarning("Will not execute job {id} as it does not contain any commands", job.Id);
                return;
            }

            if (job.Type == JobType.Scheduled)
            {
                job.SetNextRun(dtp.Now);
            }
            job.LastRun = dtp.Now;
            jobRepository.SaveAsync(job);

            foreach (var command in job.Commands)
            {
                try
                {
                    switch (command.ExecutionStrategy.Mode)
                    {
                    //case ExecutionMode.Default:
                    //    var commandExecutor = serviceProvider.GetRequiredService<IWhenDoCommandExecutor>();
                    //    await commandExecutor.ExecuteAsync(context, command.Type, command.MethodName, command.Parameters);
                    //    break;

                    case ExecutionMode.Default:
                    case ExecutionMode.Reliable:
                    {
                        hangfireClient.Enqueue <IWhenDoCommandExecutor>(x => x.ExecuteAsync(context, job.Id, command.Id));
                        logger.LogInformation($"Set command {command.Type} for immediate execution");
                    }
                    break;

                    case ExecutionMode.Delayed:
                    {
                        var providers = GetExpressionProviderInstancesForDelegate(command.ExecutionStrategy.Time, null).ToArray();
                        var time      = (TimeSpan)command.ExecutionStrategy.Time.DynamicInvoke(providers);
                        hangfireClient.Schedule <IWhenDoCommandExecutor>(x => x.ExecuteAsync(context, job.Id, command.Id), time);
                        logger.LogInformation($"Delayed command {command.Type} with {time.ToString()}");
                    }
                    break;

                    case ExecutionMode.Scheduled:
                    {
                        var providers = GetExpressionProviderInstancesForDelegate(command.ExecutionStrategy.Time, null).ToArray();

                        var today         = DateTimeOffset.Now.Date;
                        var time          = (TimeSpan)command.ExecutionStrategy.Time.DynamicInvoke(providers);
                        var executionTime = (today + time > DateTime.Now) ? today + time : today.AddDays(1) + time;
                        hangfireClient.Schedule <IWhenDoCommandExecutor>(x => x.ExecuteAsync(context, job.Id, command.Id), executionTime);
                        logger.LogInformation($"Scheduled command {command.Type} at {executionTime.ToString()}");
                    }
                    break;
                    }
                }
                catch (Exception ex)
                {
                    logger.LogError(ex, $"Error when executing command {command.Id}: {ex.Message}");
                }
            }
        }
        private List <IWhenDoExpressionProvider> GetExpressionProviderInstancesForDelegate(Delegate del, IWhenDoMessage message)
        {
            var providers = new List <IWhenDoExpressionProvider>();
            var fullNames = del.ExtractProviderFullNames();

            foreach (var name in fullNames)
            {
                if (message != null && name.Equals(message.GetType().Name))
                {
                    providers.Add(message);
                }
                else
                {
                    var instance = registry.GetExpressionProviderInstance(name);
                    if (instance != null)
                    {
                        providers.Add(instance);
                    }
                }
            }
            return(providers);
        }
示例#9
0
 public void EnqueueMessage(IWhenDoMessage message)
 {
     queue.Enqueue(message);
 }