RedisPubSubTrigger for Azure Functions
Redis features publish/subscribe functionality that enables messages to be sent to Redis and broadcast to subscribers.
For more information about Azure Cache for Redis triggers and bindings, Redis Extension for Azure Functions.
Scope of availability for functions triggers
Tier | Basic | Standard, Premium | Enterprise, Enterprise Flash |
---|---|---|---|
Pub/Sub Trigger | Yes | Yes | Yes |
Warning
This trigger isn't supported on a consumption plan because Redis PubSub requires clients to always be actively listening to receive all messages. For consumption plans, your function might miss certain messages published to the channel.
Important
The Node.js v4 model for Functions isn't yet supported by the Azure Cache for Redis extension. For more details about how the v4 model works, refer to the Azure Functions Node.js developer guide. To learn more about the differences between v3 and v4, refer to the migration guide.
Important
The Python v2 model for Functions isn't yet supported by the Azure Cache for Redis extension. For more details about how the v2 model works, refer to the Azure Functions Python developer guide.
Examples
Execution model | Description |
---|---|
In-process | Your function code runs in the same process as the Functions host process. Check out .NET supported versions before getting started. To learn more, see Develop C# class library functions using Azure Functions. |
Isolated process | Your function code runs in a separate .NET worker process. Check out .NET supported versions before getting started. To learn more, see Develop isolated process functions in C#. |
Important
For .NET functions, using the isolated worker model is recommended over the in-process model. For a comparison of the in-process and isolated worker models, see differences between the isolated worker model and the in-process model for .NET on Azure Functions.
This sample listens to the channel pubsubTest
.
using Microsoft.Extensions.Logging;
namespace Microsoft.Azure.Functions.Worker.Extensions.Redis.Samples.RedisPubSubTrigger
{
internal class SimplePubSubTrigger
{
private readonly ILogger<SimplePubSubTrigger> logger;
public SimplePubSubTrigger(ILogger<SimplePubSubTrigger> logger)
{
this.logger = logger;
}
[Function(nameof(SimplePubSubTrigger))]
public void Run(
[RedisPubSubTrigger(Common.connectionStringSetting, "pubsubTest")] string message)
{
logger.LogInformation(message);
}
}
}
This sample listens to any keyspace notifications for the key keyspaceTest
.
using Microsoft.Extensions.Logging;
namespace Microsoft.Azure.Functions.Worker.Extensions.Redis.Samples.RedisPubSubTrigger
{
internal class KeyspaceTrigger
{
private readonly ILogger<KeyspaceTrigger> logger;
public KeyspaceTrigger(ILogger<KeyspaceTrigger> logger)
{
this.logger = logger;
}
[Function(nameof(KeyspaceTrigger))]
public void Run(
[RedisPubSubTrigger(Common.connectionStringSetting, "__keyspace@0__:keyspaceTest")] string message)
{
logger.LogInformation(message);
}
}
}
This sample listens to any keyevent
notifications for the delete command DEL
.
using Microsoft.Extensions.Logging;
namespace Microsoft.Azure.Functions.Worker.Extensions.Redis.Samples.RedisPubSubTrigger
{
internal class KeyeventTrigger
{
private readonly ILogger<KeyeventTrigger> logger;
public KeyeventTrigger(ILogger<KeyeventTrigger> logger)
{
this.logger = logger;
}
[Function(nameof(KeyeventTrigger))]
public void Run(
[RedisPubSubTrigger(Common.connectionStringSetting, "__keyevent@0__:del")] string message)
{
logger.LogInformation($"Key '{message}' deleted.");
}
}
}
This sample listens to the channel pubsubTest
.
package com.function.RedisPubSubTrigger;
import com.microsoft.azure.functions.*;
import com.microsoft.azure.functions.annotation.*;
import com.microsoft.azure.functions.redis.annotation.*;
public class SimplePubSubTrigger {
@FunctionName("SimplePubSubTrigger")
public void run(
@RedisPubSubTrigger(
name = "req",
connection = "redisConnectionString",
channel = "pubsubTest",
pattern = false)
String message,
final ExecutionContext context) {
context.getLogger().info(message);
}
}
This sample listens to any keyspace notifications for the key myKey
.
package com.function.RedisPubSubTrigger;
import com.microsoft.azure.functions.*;
import com.microsoft.azure.functions.annotation.*;
import com.microsoft.azure.functions.redis.annotation.*;
public class KeyspaceTrigger {
@FunctionName("KeyspaceTrigger")
public void run(
@RedisPubSubTrigger(
name = "req",
connection = "redisConnectionString",
channel = "__keyspace@0__:keyspaceTest",
pattern = false)
String message,
final ExecutionContext context) {
context.getLogger().info(message);
}
}
This sample listens to any keyevent
notifications for the delete command DEL
.
package com.function.RedisPubSubTrigger;
import com.microsoft.azure.functions.*;
import com.microsoft.azure.functions.annotation.*;
import com.microsoft.azure.functions.redis.annotation.*;
public class KeyeventTrigger {
@FunctionName("KeyeventTrigger")
public void run(
@RedisPubSubTrigger(
name = "req",
connection = "redisConnectionString",
channel = "__keyevent@0__:del",
pattern = false)
String message,
final ExecutionContext context) {
context.getLogger().info(message);
}
}
This sample uses the same index.js
file, with binding data in the function.json
file determining on which channel the trigger occurs.
Here's the index.js
file:
module.exports = async function (context, message) {
context.log(message);
}
From function.json
:
Here's binding data to listen to the channel pubsubTest
.
{
"bindings": [
{
"type": "redisPubSubTrigger",
"connection": "redisConnectionString",
"channel": "pubsubTest",
"pattern": false,
"name": "message",
"direction": "in"
}
],
"scriptFile": "index.js"
}
Here's binding data to listen to keyspace notifications for the key keyspaceTest
.
{
"bindings": [
{
"type": "redisPubSubTrigger",
"connection": "redisConnectionString",
"channel": "__keyspace@0__:keyspaceTest",
"pattern": false,
"name": "message",
"direction": "in"
}
],
"scriptFile": "index.js"
}
Here's binding data to listen to keyevent
notifications for the delete command DEL
.
{
"bindings": [
{
"type": "redisPubSubTrigger",
"connection": "redisConnectionString",
"channel": "__keyevent@0__:del",
"pattern": false,
"name": "message",
"direction": "in"
}
],
"scriptFile": "index.js"
}
This sample uses the same run.ps1
file, with binding data in the function.json
file determining on which channel the trigger occurs.
Here's the run.ps1
file:
param($message, $TriggerMetadata)
Write-Host $message
From function.json
:
Here's binding data to listen to the channel pubsubTest
.
{
"bindings": [
{
"type": "redisPubSubTrigger",
"connection": "redisConnectionString",
"channel": "pubsubTest",
"pattern": false,
"name": "message",
"direction": "in"
}
],
"scriptFile": "run.ps1"
}
Here's binding data to listen to keyspace notifications for the key keyspaceTest
.
{
"bindings": [
{
"type": "redisPubSubTrigger",
"connection": "redisConnectionString",
"channel": "__keyspace@0__:keyspaceTest",
"pattern": false,
"name": "message",
"direction": "in"
}
],
"scriptFile": "run.ps1"
}
Here's binding data to listen to keyevent
notifications for the delete command DEL
.
{
"bindings": [
{
"type": "redisPubSubTrigger",
"connection": "redisConnectionString",
"channel": "__keyevent@0__:del",
"pattern": false,
"name": "message",
"direction": "in"
}
],
"scriptFile": "run.ps1"
}
The Python v1 programming model requires you to define bindings in a separate function.json file in the function folder. For more information, see the Python developer guide.
This sample uses the same __init__.py
file, with binding data in the function.json
file determining on which channel the trigger occurs.
Here's the __init__.py
file:
import logging
def main(message: str):
logging.info(message)
From function.json
:
Here's binding data to listen to the channel pubsubTest
.
{
"bindings": [
{
"type": "redisPubSubTrigger",
"connection": "redisConnectionString",
"channel": "pubsubTest",
"pattern": false,
"name": "message",
"direction": "in"
}
],
"scriptFile": "__init__.py"
}
Here's binding data to listen to keyspace notifications for the key keyspaceTest
.
{
"bindings": [
{
"type": "redisPubSubTrigger",
"connection": "redisConnectionString",
"channel": "__keyspace@0__:keyspaceTest",
"pattern": false,
"name": "message",
"direction": "in"
}
],
"scriptFile": "__init__.py"
}
Here's binding data to listen to keyevent
notifications for the delete command DEL
.
{
"bindings": [
{
"type": "redisPubSubTrigger",
"connection": "redisConnectionString",
"channel": "__keyevent@0__:del",
"pattern": false,
"name": "message",
"direction": "in"
}
],
"scriptFile": "__init__.py"
}
Attributes
Parameter | Description | Required | Default |
---|---|---|---|
Connection |
The name of the application setting that contains the cache connection string, such as: <cacheName>.redis.cache.chinacloudapi.cn:6380,password... |
Yes | |
Channel |
The pub sub channel that the trigger should listen to. Supports glob-style channel patterns. This field can be resolved using INameResolver . |
Yes |
Annotations
Parameter | Description | Required | Default |
---|---|---|---|
name |
Name of the variable holding the value returned by the function. | Yes | |
connection |
The name of the application setting that contains the cache connection string, such as: <cacheName>.redis.cache.chinacloudapi.cn:6380,password... |
Yes | |
channel |
The pub sub channel that the trigger should listen to. Supports glob-style channel patterns. | Yes |
Configuration
function.json property | Description | Required | Default |
---|---|---|---|
type |
Trigger type. For the pub sub trigger, the type is redisPubSubTrigger . |
Yes | |
connection |
The name of the application setting that contains the cache connection string, such as: <cacheName>.redis.cache.chinacloudapi.cn:6380,password... |
Yes | |
channel |
Name of the pub sub channel that is being subscribed to. | Yes | |
pattern |
A boolean to indicate the given channel uses pattern mathching. If pattern is true, then the channel is treated like a glob-style pattern instead of as a literal. |
Yes | |
name |
Name of the variable holding the value returned by the function. | Yes | |
direction |
Must be set to in . |
Yes |
Important
The connection
parameter does not hold the Redis cache connection string itself. Instead, it points to the name of the environment variable that holds the connection string. This makes the application more secure. For more information, see Redis connection string.
Usage
Redis features publish/subscribe functionality that enables messages to be sent to Redis and broadcast to subscribers. The RedisPubSubTrigger
enables Azure Functions to be triggered on pub/sub activity. The RedisPubSubTrigger
subscribes to a specific channel pattern using PSUBSCRIBE
, and surfaces messages received on those channels to the function.
Prerequisites and limitations
- The
RedisPubSubTrigger
isn't capable of listening to keyspace notifications on clustered caches. - Basic tier functions don't support triggering on
keyspace
orkeyevent
notifications through theRedisPubSubTrigger
. - The
RedisPubSubTrigger
isn't supported on a consumption plan because Redis PubSub requires clients to always be actively listening to receive all messages. For consumption plans, your function might miss certain messages published to the channel. - Functions with the
RedisPubSubTrigger
shouldn't be scaled out to multiple instances. Each instance listens and processes each pub sub message, resulting in duplicate processing.
Warning
This trigger isn't supported on a consumption plan because Redis PubSub requires clients to always be actively listening to receive all messages. For consumption plans, your function might miss certain messages published to the channel.
Triggering on keyspace notifications
Redis offers a built-in concept called keyspace notifications. When enabled, this feature publishes notifications of a wide range of cache actions to a dedicated pub/sub channel. Supported actions include actions that affect specific keys, called keyspace notifications, and specific commands, called keyevent notifications. A huge range of Redis actions are supported, such as SET
, DEL
, and EXPIRE
. The full list can be found in the keyspace notification documentation.
The keyspace
and keyevent
notifications are published with the following syntax:
PUBLISH __keyspace@0__:<affectedKey> <command>
PUBLISH __keyevent@0__:<affectedCommand> <key>
Because these events are published on pub/sub channels, the RedisPubSubTrigger
is able to pick them up. See the RedisPubSubTrigger section for more examples.
Important
In Azure Cache for Redis, keyspace
events must be enabled before notifications are published. For more information, see Advanced Settings.
Type | Description |
---|---|
string |
The channel message serialized as JSON (UTF-8 encoded for byte types) in the format that follows. |
Custom |
The trigger uses Json.NET serialization to map the message from the channel into the given custom type. |
JSON string format
{
"SubscriptionChannel":"__keyspace@0__:*",
"Channel":"__keyspace@0__:mykey",
"Message":"set"
}
Type | Description |
---|---|
string |
The channel message serialized as JSON (UTF-8 encoded for byte types) in the format that follows. |
Custom |
The trigger uses Json.NET serialization to map the message from the channel from a string into a custom type. |
{
"SubscriptionChannel":"__keyspace@0__:*",
"Channel":"__keyspace@0__:mykey",
"Message":"set"
}