You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
* Make App Lock timeout configurable (#982)
Add configurable AppLockTimeoutMs setting for the SQL trigger binding's
application lock timeout. Previously hardcoded to 30 seconds, the timeout
can now be configured via:
- Sql_Trigger_AppLockTimeoutMs app setting
- AppLockTimeoutMs property in host.json SqlOptions
The default remains 30000ms (30 seconds) with a minimum of 1000ms (1 second).
Changes:
- Convert static AppLockStatements field to GetAppLockStatements(int) method
- Add AppLockTimeoutMs property to SqlOptions with validation
- Read config from app settings with SqlOptions fallback in SqlTableChangeMonitor,
SqlTriggerListener, and SqlScalerProvider
- Pass appLockTimeoutMs through ScaleMonitor/TargetScaler/MetricsProvider chain
- Add telemetry for HasConfiguredAppLockTimeout and AppLockTimeoutMs
- Add unit tests for new config and GetAppLockStatements method
- Update documentation in BindingsOverview.md and TriggerBinding.md
Closes#982
* Address review feedback: rename MinimumAppLockTimeoutMs and add validation
- Rename DefaultMinimumAppLockTimeoutMs to MinimumAppLockTimeoutMs (public const)
to clarify it represents the minimum accepted value, not a default
- Add min-value validation in SqlScalerProvider for app-settings value
- Tighten validation in SqlTableChangeMonitor and SqlTriggerListener to
check against MinimumAppLockTimeoutMs instead of just > 0
Co-authored-by: Copilot <[email protected]>
* Address PR #1213 review comments
- SqlScalerProvider: Use nullable int for AppLockTimeoutMs config to
distinguish 'not configured' from 'explicitly set to 0'
- SqlTriggerListener: Add HasConfiguredAppLockTimeout property and
AppLockTimeoutMs measure to StartListener telemetry event
- SqlTriggerConstants: Merge duplicate XML summary doc comments on
GetAppLockStatements method
- SqlOptionsTests: Add test for negative AppLockTimeoutMs values
Co-authored-by: Copilot <[email protected]>
---------
Co-authored-by: george.crocker <[email protected]>
Co-authored-by: Copilot <[email protected]>
Co-authored-by: Charles Gagnon <[email protected]>
-[Scaling for Trigger Bindings](#scaling-for-trigger-bindings)
25
26
-[Retry support for Trigger Bindings](#retry-support-for-trigger-bindings)
@@ -153,6 +154,10 @@ The delay in milliseconds between processing each batch of changes.
153
154
154
155
The upperlimiton the number of pending changes in the user table that are allowed per application-worker. If the count of changes exceeds this limit, it may result in a scale out. The setting only applies for Azure Function Apps with runtime driven scaling enabled. See the [Scaling](#scaling-for-trigger-bindings) section for more information.
155
156
157
+
#### Sql_Trigger_AppLockTimeoutMs
158
+
159
+
The timeout in milliseconds for acquiring the application lock used to prevent deadlocks when processing changes. The default value is 30000 (30 seconds). The minimum allowed value is 1000 (1 second).
160
+
156
161
#### WEBSITE_SITE_NAME
157
162
158
163
If this setting exists, it will be used to generate a unique identifier for the function that is used for tracking function state. If not specified, this unique identifier will be generated from the [IHostIdProvider.GetHostIdAsync](https://github.com/Azure/azure-webjobs-sdk/blob/dev/src/Microsoft.Azure.WebJobs.Host/Executors/IHostIdProvider.cs#L14).
Copy file name to clipboardExpand all lines: docs/TriggerBinding.md
+1-1Lines changed: 1 addition & 1 deletion
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -119,6 +119,6 @@ The SQL Trigger uses transactions to guarantee that changes are rolled back in t
119
119
120
120
Because of this, and the number of internal state tables that the trigger interacts with, there is a high chance of deadlocks occurring if two functions are attempting to make changes to the tables at the same time.
121
121
122
-
To avoid this from happening the trigger utilizes the [sp_getapplock](https://learn.microsoft.com/sql/relational-databases/system-stored-procedures/sp-getapplock-transact-sql) statement to ensure that each transaction is processed serially. Before each statement in a transaction, sp_getapplock gets an Exclusive lock on the `_az_func_Trigger` resource - this ensures that for the duration of the transaction it is the only Azure Function that will be accessing any of the tables used.
122
+
To avoid this from happening the trigger utilizes the [sp_getapplock](https://learn.microsoft.com/sql/relational-databases/system-stored-procedures/sp-getapplock-transact-sql) statement to ensure that each transaction is processed serially. Before each statement in a transaction, sp_getapplock gets an Exclusive lock on the `_az_func_Trigger` resource - this ensures that for the duration of the transaction it is the only Azure Function that will be accessing any of the tables used. The timeout for acquiring this lock defaults to 30 seconds and can be configured using the `Sql_Trigger_AppLockTimeoutMs`[application setting](./BindingsOverview.md#sql_trigger_applocktimeoutms) or the `AppLockTimeoutMs` host.json option.
123
123
124
124
While this helps ensure concurrency safety for Azure Functions, other queries on the system can still cause a deadlock to occur. [This guide](https://learn.microsoft.com/sql/relational-databases/sql-server-deadlocks-guide) can help troubleshoot any issues that occur and provides some suggestions for fixing these issues. You may also utilize the sp_getapplock statement yourself with the `_az_func_Trigger` resource to synchronize requests, although doing so may have a negative impact on the performance of your Functions.
thrownewInvalidOperationException($"Invalid value for configuration setting '{SqlTriggerConstants.ConfigKey_SqlTrigger_AppLockTimeoutMs}'. Value must not be less than {SqlOptions.MinimumAppLockTimeoutMs}ms.");
@@ -144,15 +145,24 @@ public SqlTableChangeMonitor(
144
145
{
145
146
thrownewInvalidOperationException($"Invalid value for configuration setting '{ConfigKey_SqlTrigger_PollingInterval}'. Ensure that the value is a positive integer.");
thrownewInvalidOperationException($"Invalid value for configuration setting '{ConfigKey_SqlTrigger_AppLockTimeoutMs}'. Value must not be less than {SqlOptions.MinimumAppLockTimeoutMs}ms.");
0 commit comments