Skip to content

Commit d5c66df

Browse files
authored
Rename worker table to leases table (Azure#319)
1 parent 5d3931b commit d5c66df

File tree

7 files changed

+72
-72
lines changed

7 files changed

+72
-72
lines changed

README.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -605,9 +605,9 @@ The trigger binding utilizes SQL [change tracking](https://docs.microsoft.com/sq
605605
ENABLE CHANGE_TRACKING;
606606
```
607607
608-
For more information, please refer to the documentation [here](https://docs.microsoft.com/sql/relational-databases/track-changes/enable-and-disable-change-tracking-sql-server#enable-change-tracking-for-a-table). The trigger needs to have read access on the table being monitored for changes as well as to the change tracking system tables. It also needs write access to an `az_func` schema within the database, where it will create additional worker tables to store the trigger states and leases. Each function trigger will thus have an associated change tracking table and worker table.
608+
For more information, please refer to the documentation [here](https://docs.microsoft.com/sql/relational-databases/track-changes/enable-and-disable-change-tracking-sql-server#enable-change-tracking-for-a-table). The trigger needs to have read access on the table being monitored for changes as well as to the change tracking system tables. It also needs write access to an `az_func` schema within the database, where it will create additional leases tables to store the trigger states and leases. Each function trigger will thus have an associated change tracking table and leases table.
609609
610-
> **NOTE:** The worker table contains all columns corresponding to the primary key from the user table and three additional columns named `_az_func_ChangeVersion`, `_az_func_AttemptCount` and `_az_func_LeastExpirationTime`. If any of the primary key columns happen to have the same name, that will result in an error message listing any conflicts. In this case, the listed primary key columns must be renamed for the trigger to work.
610+
> **NOTE:** The leases table contains all columns corresponding to the primary key from the user table and three additional columns named `_az_func_ChangeVersion`, `_az_func_AttemptCount` and `_az_func_LeastExpirationTime`. If any of the primary key columns happen to have the same name, that will result in an error message listing any conflicts. In this case, the listed primary key columns must be renamed for the trigger to work.
611611
612612
#### Trigger Samples
613613
The trigger binding takes two [arguments](https://github.com/Azure/azure-functions-sql-extension/blob/main/src/TriggerBinding/SqlTriggerAttribute.cs)

src/Telemetry/Telemetry.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -359,11 +359,11 @@ public enum TelemetryPropertyName
359359
ErrorName,
360360
ExceptionType,
361361
HasIdentityColumn,
362+
LeasesTableName,
362363
QueryType,
363364
ServerVersion,
364365
Type,
365366
UserFunctionId,
366-
WorkerTableName,
367367
}
368368

369369
/// <summary>
@@ -376,7 +376,7 @@ public enum TelemetryMeasureName
376376
CommandDurationMs,
377377
CreatedSchemaDurationMs,
378378
CreateGlobalStateTableDurationMs,
379-
CreateWorkerTableDurationMs,
379+
CreateLeasesTableDurationMs,
380380
DurationMs,
381381
GetCaseSensitivityDurationMs,
382382
GetChangesDurationMs,

src/TriggerBinding/SqlTableChangeMonitor.cs

Lines changed: 39 additions & 39 deletions
Large diffs are not rendered by default.

src/TriggerBinding/SqlTriggerConstants.cs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -9,10 +9,10 @@ internal static class SqlTriggerConstants
99

1010
public const string GlobalStateTableName = "[" + SchemaName + "].[GlobalState]";
1111

12-
public const string WorkerTableNameFormat = "[" + SchemaName + "].[Worker_{0}]";
12+
public const string LeasesTableNameFormat = "[" + SchemaName + "].[Leases_{0}]";
1313

14-
public const string WorkerTableChangeVersionColumnName = "_az_func_ChangeVersion";
15-
public const string WorkerTableAttemptCountColumnName = "_az_func_AttemptCount";
16-
public const string WorkerTableLeaseExpirationTimeColumnName = "_az_func_LeaseExpirationTime";
14+
public const string LeasesTableChangeVersionColumnName = "_az_func_ChangeVersion";
15+
public const string LeasesTableAttemptCountColumnName = "_az_func_AttemptCount";
16+
public const string LeasesTableLeaseExpirationTimeColumnName = "_az_func_LeaseExpirationTime";
1717
}
1818
}

src/TriggerBinding/SqlTriggerListener.cs

Lines changed: 23 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -103,19 +103,19 @@ public async Task StartAsync(CancellationToken cancellationToken)
103103
IReadOnlyList<(string name, string type)> primaryKeyColumns = await this.GetPrimaryKeyColumnsAsync(connection, userTableId, cancellationToken);
104104
IReadOnlyList<string> userTableColumns = await this.GetUserTableColumnsAsync(connection, userTableId, cancellationToken);
105105

106-
string workerTableName = string.Format(CultureInfo.InvariantCulture, SqlTriggerConstants.WorkerTableNameFormat, $"{this._userFunctionId}_{userTableId}");
107-
this._logger.LogDebug($"Worker table name: '{workerTableName}'.");
108-
this._telemetryProps[TelemetryPropertyName.WorkerTableName] = workerTableName;
106+
string leasesTableName = string.Format(CultureInfo.InvariantCulture, SqlTriggerConstants.LeasesTableNameFormat, $"{this._userFunctionId}_{userTableId}");
107+
this._logger.LogDebug($"leases table name: '{leasesTableName}'.");
108+
this._telemetryProps[TelemetryPropertyName.LeasesTableName] = leasesTableName;
109109

110110
var transactionSw = Stopwatch.StartNew();
111-
long createdSchemaDurationMs = 0L, createGlobalStateTableDurationMs = 0L, insertGlobalStateTableRowDurationMs = 0L, createWorkerTableDurationMs = 0L;
111+
long createdSchemaDurationMs = 0L, createGlobalStateTableDurationMs = 0L, insertGlobalStateTableRowDurationMs = 0L, createLeasesTableDurationMs = 0L;
112112

113113
using (SqlTransaction transaction = connection.BeginTransaction(System.Data.IsolationLevel.RepeatableRead))
114114
{
115115
createdSchemaDurationMs = await CreateSchemaAsync(connection, transaction, cancellationToken);
116116
createGlobalStateTableDurationMs = await CreateGlobalStateTableAsync(connection, transaction, cancellationToken);
117117
insertGlobalStateTableRowDurationMs = await this.InsertGlobalStateTableRowAsync(connection, transaction, userTableId, cancellationToken);
118-
createWorkerTableDurationMs = await CreateWorkerTableAsync(connection, transaction, workerTableName, primaryKeyColumns, cancellationToken);
118+
createLeasesTableDurationMs = await CreateLeasesTableAsync(connection, transaction, leasesTableName, primaryKeyColumns, cancellationToken);
119119
transaction.Commit();
120120
}
121121

@@ -127,7 +127,7 @@ public async Task StartAsync(CancellationToken cancellationToken)
127127
userTableId,
128128
this._userTable,
129129
this._userFunctionId,
130-
workerTableName,
130+
leasesTableName,
131131
userTableColumns,
132132
primaryKeyColumns.Select(col => col.name).ToList(),
133133
this._executor,
@@ -142,7 +142,7 @@ public async Task StartAsync(CancellationToken cancellationToken)
142142
[TelemetryMeasureName.CreatedSchemaDurationMs] = createdSchemaDurationMs,
143143
[TelemetryMeasureName.CreateGlobalStateTableDurationMs] = createGlobalStateTableDurationMs,
144144
[TelemetryMeasureName.InsertGlobalStateTableRowDurationMs] = insertGlobalStateTableRowDurationMs,
145-
[TelemetryMeasureName.CreateWorkerTableDurationMs] = createWorkerTableDurationMs,
145+
[TelemetryMeasureName.CreateLeasesTableDurationMs] = createLeasesTableDurationMs,
146146
[TelemetryMeasureName.TransactionDurationMs] = transactionSw.ElapsedMilliseconds,
147147
};
148148

@@ -213,7 +213,7 @@ private async Task<int> GetUserTableIdAsync(SqlConnection connection, Cancellati
213213
/// Gets the names and types of primary key columns of the user table.
214214
/// </summary>
215215
/// <exception cref="InvalidOperationException">
216-
/// Thrown if there are no primary key columns present in the user table or if their names conflict with columns in worker table.
216+
/// Thrown if there are no primary key columns present in the user table or if their names conflict with columns in leases table.
217217
/// </exception>
218218
private async Task<IReadOnlyList<(string name, string type)>> GetPrimaryKeyColumnsAsync(SqlConnection connection, int userTableId, CancellationToken cancellationToken)
219219
{
@@ -263,9 +263,9 @@ FROM sys.indexes AS i
263263

264264
string[] reservedColumnNames = new[]
265265
{
266-
SqlTriggerConstants.WorkerTableChangeVersionColumnName,
267-
SqlTriggerConstants.WorkerTableAttemptCountColumnName,
268-
SqlTriggerConstants.WorkerTableLeaseExpirationTimeColumnName
266+
SqlTriggerConstants.LeasesTableChangeVersionColumnName,
267+
SqlTriggerConstants.LeasesTableAttemptCountColumnName,
268+
SqlTriggerConstants.LeasesTableLeaseExpirationTimeColumnName
269269
};
270270

271271
var conflictingColumnNames = primaryKeyColumns.Select(col => col.name).Intersect(reservedColumnNames).ToList();
@@ -326,7 +326,7 @@ FROM sys.columns AS c
326326
}
327327

328328
/// <summary>
329-
/// Creates the schema for global state table and worker tables, if it does not already exist.
329+
/// Creates the schema for global state table and leases tables, if it does not already exist.
330330
/// </summary>
331331
private static async Task<long> CreateSchemaAsync(SqlConnection connection, SqlTransaction transaction, CancellationToken cancellationToken)
332332
{
@@ -409,33 +409,33 @@ INSERT INTO {SqlTriggerConstants.GlobalStateTableName}
409409
}
410410

411411
/// <summary>
412-
/// Creates the worker table for the 'user function and table', if one does not already exist.
412+
/// Creates the leases table for the 'user function and table', if one does not already exist.
413413
/// </summary>
414-
private static async Task<long> CreateWorkerTableAsync(
414+
private static async Task<long> CreateLeasesTableAsync(
415415
SqlConnection connection,
416416
SqlTransaction transaction,
417-
string workerTableName,
417+
string leasesTableName,
418418
IReadOnlyList<(string name, string type)> primaryKeyColumns,
419419
CancellationToken cancellationToken)
420420
{
421421
string primaryKeysWithTypes = string.Join(", ", primaryKeyColumns.Select(col => $"{col.name.AsBracketQuotedString()} {col.type}"));
422422
string primaryKeys = string.Join(", ", primaryKeyColumns.Select(col => col.name.AsBracketQuotedString()));
423423

424-
string createWorkerTableQuery = $@"
425-
IF OBJECT_ID(N'{workerTableName}', 'U') IS NULL
426-
CREATE TABLE {workerTableName} (
424+
string createLeasesTableQuery = $@"
425+
IF OBJECT_ID(N'{leasesTableName}', 'U') IS NULL
426+
CREATE TABLE {leasesTableName} (
427427
{primaryKeysWithTypes},
428-
{SqlTriggerConstants.WorkerTableChangeVersionColumnName} bigint NOT NULL,
429-
{SqlTriggerConstants.WorkerTableAttemptCountColumnName} int NOT NULL,
430-
{SqlTriggerConstants.WorkerTableLeaseExpirationTimeColumnName} datetime2,
428+
{SqlTriggerConstants.LeasesTableChangeVersionColumnName} bigint NOT NULL,
429+
{SqlTriggerConstants.LeasesTableAttemptCountColumnName} int NOT NULL,
430+
{SqlTriggerConstants.LeasesTableLeaseExpirationTimeColumnName} datetime2,
431431
PRIMARY KEY ({primaryKeys})
432432
);
433433
";
434434

435-
using (var createWorkerTableCommand = new SqlCommand(createWorkerTableQuery, connection, transaction))
435+
using (var createLeasesTableCommand = new SqlCommand(createLeasesTableQuery, connection, transaction))
436436
{
437437
var stopwatch = Stopwatch.StartNew();
438-
await createWorkerTableCommand.ExecuteNonQueryAsync(cancellationToken);
438+
await createLeasesTableCommand.ExecuteNonQueryAsync(cancellationToken);
439439
return stopwatch.ElapsedMilliseconds;
440440
}
441441
}

test/Integration/SqlTriggerBindingIntegrationTests.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -123,7 +123,7 @@ public void PrimaryKeyNotCreatedTriggerTest()
123123

124124
/// <summary>
125125
/// Tests the error message when the user table contains one or more primary keys with names conflicting with
126-
/// column names in the worker table.
126+
/// column names in the leases table.
127127
/// </summary>
128128
[Fact]
129129
public void ReservedPrimaryKeyColumnNamesTriggerTest()

test/Integration/test-csharp/ReservedPrimaryKeyColumnNamesTrigger.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ public static class ReservedPrimaryKeyColumnNamesTrigger
1111
{
1212
/// <summary>
1313
/// Used in verification of the error message when the user table contains one or more primary keys with names
14-
/// conflicting with column names in the worker table.
14+
/// conflicting with column names in the leases table.
1515
/// </summary>
1616
[FunctionName(nameof(ReservedPrimaryKeyColumnNamesTrigger))]
1717
public static void Run(

0 commit comments

Comments
 (0)