Reputation: 5085
I am trying to use Azure service bus to pass messages between multiple azure functions. I am creating topic and subscription in code. But not sure how to add filter query from code. I want to filter messages by id . e.g SqlFilter($"'id' ='{id}'")
. I don't want to create one subscription for each message because of this filter.
Is it possible to have different filter for a subscription?
This issue can be fixed by creating one subscription for each request and deleting it afterwards. But i don't want to create so many subscriptions. My aim is to just change the filter each time the function is called.
Sample code:
var connectionString = ConfigurationManager.AppSettings["ServiceBus_CONNECTION_STRING"];
var namespaceManager =
NamespaceManager.CreateFromConnectionString(connectionString);
if (!await namespaceManager.TopicExistsAsync(topicName))
{
// Configure Topic Settings.
var topic = new TopicDescription(topicName)
{
MaxSizeInMegabytes = 1024,
DefaultMessageTimeToLive = TimeSpan.FromMinutes(5)
};
await namespaceManager.CreateTopicAsync(topic);
}
if (!await namespaceManager.SubscriptionExistsAsync(topicName, subscription))
{
await namespaceManager.CreateSubscriptionAsync(topicName, subscription);
}
var cts = new TaskCompletionSource<T>();
var subClient =
SubscriptionClient.CreateFromConnectionString(connectionString, topicName,
subscription);
var ruleDescription = new RuleDescription($"RequestIdRule{id}", new SqlFilter($"'id' ='{id}'"));
await subClient.AddRuleAsync(ruleDescription);
var options = new OnMessageOptions();
subClient.OnMessage(m =>
{
try
{
var body = m.GetBody<T>();
cts.SetResult(body);
}
catch (Exception ex)
{
m.Abandon();
}
},
options);
return await cts.Task;
}
catch (Exception ex)
{
throw;
}
Upvotes: 2
Views: 1850
Reputation: 25994
Is it possible to have different filter for a subscription?
Yes. A single topics with all its subscriptions can have up to 2,000 SQL filters (100,000 for correlation filters). See documentation here.
You can't update a filter. You'd need to delete the old rule and replace it with a new one by creating one. But I question the efficiency of this approach if you do it frequently at run-time.
I am trying to use Azure service bus to pass messages between multiple azure functions.
Alternatively, you could have each function have its input queue, where chaining those functions would be sending a message to the appropriate Azure Service Bus input queue.
And finally,
My aim is to just change the filter each time the function is called.
If you have a spike of messages, your function would be scaled out. That means, you could execute the same function for different messages. Each message would require creation of a different rule under the same subscription. Not only it feels off, but it will create a contention over the subscription to update the rule which will lead to either a failure or incorrect behavior.
Upvotes: 2