Esempio n. 1
0
    public async Task Handle(PublishExpiredTasksCommand command)
    {
        DateTime after = DateTime.Now.AddMinutes(-1);
        IQueryable <PublishedTask> query =
            from task in Databases.Snittlistan.PublishedTasks.Include(x => x.Tenant)
            where task.PublishDate < after && task.HandledDate == null
            select task;

        PublishedTask[] expiredTasks = await query.ToArrayAsync();

        if (expiredTasks.Length == 0)
        {
            return;
        }

        using MsmqGateway msmqGateway = MsmqFactory.Create();
        using MsmqGateway.MsmqTransactionScope scope = msmqGateway.Create();
        foreach (PublishedTask publishedTask in expiredTasks)
        {
            MessageEnvelope message = new(
                publishedTask.Task,
                publishedTask.TenantId,
                publishedTask.Tenant.Hostname,
                publishedTask.CorrelationId,
                publishedTask.CausationId,
                publishedTask.MessageId);
            scope.Send(message);
        }

        scope.Commit();
        Logger.InfoFormat("published {length} expired messages", expiredTasks.Length);
    }
Esempio n. 2
0
        public void Run(string[] args)
        {
            bool force = args.Length == 2 && args[1] == "--force";

            using (MsmqGateway.MsmqTransactionScope scope = MsmqGateway.AutoCommitScope())
            {
                foreach (System.Uri apiUrl in CommandLineTaskHelper.AllApiUrls())
                {
                    scope.PublishMessage(new MessageEnvelope(new VerifyMatchesMessage(force), apiUrl));
                }

                scope.Commit();
            }
        }
Esempio n. 3
0
    public void PublishTask(TaskBase task, string createdBy)
    {
        Logger.Info("{createdBy} publish task {@task}", createdBy, task);
        PublishedTask publishedTask = databases.Snittlistan.PublishedTasks.Add(
            PublishedTask.CreateImmediate(
                task,
                currentTenant.TenantId,
                correlationId,
                causationId,
                createdBy));

        try
        {
            HostingEnvironment.QueueBackgroundWorkItem(ct =>
                                                       PublishMessage(currentTenant, publishedTask.MessageId, ct));
        }
        catch (Exception ex)
        {
            Logger.Error(
                ex,
                "QueueBackgroundWorkItem failed, using fallback (publish immediately)");
            try
            {
                DoPublishMessage(currentTenant, publishedTask);
            }
            catch (Exception ex2)
            {
                Logger.Error(ex2);
            }
        }

        async void PublishMessage(Tenant tenant, Guid messageId, CancellationToken ct)
        {
            const int MaxTries = 10;

            using IDisposable logScope       = NestedDiagnosticsLogicalContext.Push("QueueBackgroundWork");
            using SnittlistanContext context = new();
            try
            {
                for (int i = 0; i < MaxTries; i++)
                {
                    Logger.Info("try #{try}", i);
                    PublishedTask?publishedTask =
                        await context.PublishedTasks.SingleOrDefaultAsync(x => x.MessageId == messageId);

                    if (publishedTask == null)
                    {
                        Logger.Warn("message not found: {messageId}", messageId);
                        await Task.Delay(300);
                    }
                    else
                    {
                        DoPublishMessage(tenant, publishedTask);
                        return;
                    }
                }

                throw new Exception($"max tries reached: {MaxTries}");
            }
            catch (Exception ex)
            {
                Logger.Error(ex, "failed to publish message");
            }
        }

        void DoPublishMessage(Tenant tenant, PublishedTask publishedTask)
        {
            using MsmqGateway msmqGateway = msmqFactory.Create();
            using MsmqGateway.MsmqTransactionScope scope = msmqGateway.Create();
            MessageEnvelope message = new(
                publishedTask.Task,
                publishedTask.TenantId,
                tenant.Hostname,
                publishedTask.CorrelationId,
                publishedTask.CausationId,
                publishedTask.MessageId);

            scope.Send(message);
            scope.Commit();
            Logger.Info("published message {@message}", message);
        }
    }