Можно ли запросить очередь веб-заданий Azure?
В моем веб-приложении Azure запущены две веб-задания Azure:
- Задание А - работает непрерывно
- Задание B - сработало
Задача задания A состоит в том, чтобы вызвать задание B на основе двух вещей:
- Задание B не выполнялось в течение последнего часа для указанного номера учетной записи (переданного в задание B как параметр из задания A.
- Некоторая другая бизнес-логика, определенная из базы данных
№ 2 легко. Это № 1, о котором у меня есть вопрос. Возможно ли, чтобы Задание A запрашивало очередь веб-заданий, чтобы увидеть, выполнено ли Задание B?
Вот работа B (сработала):
public class Functions
{
public static void ProcessQueueMessage([QueueTrigger("triggeredqueue")] string message, TextWriter log)
{
var accountId = message;
//DO STUFF WITH accountId HERE...
}
}
И вот работа А (работает непрерывно). Я добавил код в комментарии, чтобы показать, что я хотел бы сделать:
class Program
{
static void Main()
{
while (true)
{
var accounts = getAccounts();
foreach (var account in accounts) {
if (testOtherBusinessLogic(account)) {
CloudStorageAccount storageAccount = CloudStorageAccount.Parse(ConnectionStringHelper.StorageConnectionString);
CloudQueueClient queueClient = storageAccount.CreateCloudQueueClient();
CloudQueue queue = queueClient.GetQueueReference("triggeredqueue");
queue.CreateIfNotExists();
//THIS IS WHAT IT IS DOING NOW:
CloudQueueMessage message = new CloudQueueMessage(account.AccountId);
queue.AddMessage(message);
//THIS IS WHAT I WOULD LIKE IT TO DO:
/*
if (!queue.Any(x => x.RunDate > (DateTime.Now.AddMinutes(-60)) && x.Message == account.AccountId.ToString()) {
CloudQueueMessage message = new CloudQueueMessage(account.AccountId);
queue.AddMessage(message);
}
*/
}
}
System.Threading.Thread.Sleep(7000);
}
}
}
1 ответ
Очередь хранилища Azure не поддерживает операции запросов. И обратите внимание, что как только ваш queuetrigger запустится, сообщение сработает, оно не будет больше в очереди. Кроме того, ваш JobB также должен работать непрерывно для прослушивания изменений в очереди.
Я рекомендую вам использовать хранилище таблиц для хранения даты выполнения. Попробуйте с кодом ниже.
// Add table entity class in JobA Program class and JobB Functions class
class MyEntity : TableEntity
{
public DateTime ExecutionTime { get; set; }
}
//In JobA, achieve what you would like to do
var accountId = account.AccountId;
CloudTableClient tableClient = storageAccount.CreateCloudTableClient();
CloudTable table = tableClient.GetTableReference("execution");
table.CreateIfNotExists();
// table entity use combination of partionkey and rowkey as entity identifier, so I set both of them to accountId
TableOperation retriveOperation = TableOperation.Retrieve<MyEntity>(accountId, accountId);
MyEntity retriveEntity = (MyEntity)table.Execute(retriveOperation).Result;
if (retriveEntity != null)
{
if (retriveEntity.ExecutionTime> DateTime.UtcNow.AddMinutes(-60))
{
CloudQueueMessage message = new CloudQueueMessage(accountId);
queue.AddMessage(message);
}
}else
{
CloudQueueMessage message = new CloudQueueMessage(accountId);
queue.AddMessage(message);
}
//In JobB, add operations to store execution time after business logic
//Connection operations omitted, please add by yourself.
CloudTable table = tableClient.GetTableReference("execution");
table.CreateIfNotExists();
TableOperation retriveOperation = TableOperation.Retrieve<MyEntity>(accountId, accountId);
MyEntity retriveEntity = (MyEntity)table.Execute(retriveOperation).Result;
if (retriveEntity != null)
{
retriveEntity.ExecutionTime = DateTime.UtcNow;
TableOperation updateOperation = TableOperation.Replace(retriveEntity);
table.Execute(updateOperation);
}
else
{
retriveEntity = new MyEntity
{
ExecutionTime = DateTime.UtcNow,
PartitionKey = accountId,
RowKey = accountId
};
TableOperation insertOperation = TableOperation.Insert(retriveEntity);
table.Execute(insertOperation);
}
Последнее предложение, кажется, нет необходимости использовать queuetrigger, вы можете использовать только JobA для достижения своей цели (DO STUFF WITH accountId
прямо в JobA).