Skip to content

Commit 3341789

Browse files
authored
Added a duration cap (15s) to getParentInstanceId() methods (#267)
1 parent 55fcd52 commit 3341789

File tree

4 files changed

+35
-7
lines changed

4 files changed

+35
-7
lines changed

durablefunctionsmonitor.dotnetbackend/Common/DetailedOrchestrationStatus.cs

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
using System.Text.RegularExpressions;
1515
using Microsoft.Extensions.Logging;
1616
using Microsoft.WindowsAzure.Storage.Table;
17+
using System.Threading;
1718

1819
namespace DurableFunctionsMonitor.DotNetBackend
1920
{
@@ -81,6 +82,8 @@ internal static async Task<DetailedOrchestrationStatus> CreateFrom(DurableOrches
8182
return result;
8283
}
8384

85+
private static int GetParentInstanceIdTimeoutInSeconds = 15;
86+
8487
internal static async Task<string> GetParentInstanceIdDirectlyFromTable(IDurableClient durableClient, string connEnvVariableName, string hubName, string instanceId)
8588
{
8689
var tableClient = await TableClient.GetTableClient(connEnvVariableName);
@@ -131,7 +134,9 @@ internal static async Task<string> GetParentInstanceIdDirectlyFromTable(IDurable
131134
)
132135
);
133136

134-
tableResult = await tableClient.GetAllAsync($"{durableClient.TaskHubName}History", executionIdQuery);
137+
// This scan can still take long time, so we'll have to hard-limit it to a few seconds. TaskCancelledException will be handled by upper code.
138+
var cts = new CancellationTokenSource(TimeSpan.FromSeconds(GetParentInstanceIdTimeoutInSeconds));
139+
tableResult = await tableClient.GetAllAsync($"{durableClient.TaskHubName}History", executionIdQuery, cts.Token);
135140
}
136141

137142
return tableResult.FirstOrDefault()?.PartitionKey;

durablefunctionsmonitor.dotnetbackend/Common/TableClient.cs

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
using Microsoft.WindowsAzure.Storage.Table;
99
using Microsoft.WindowsAzure.Storage;
1010
using Microsoft.WindowsAzure.Storage.Auth;
11+
using System.Threading;
1112

1213
namespace DurableFunctionsMonitor.DotNetBackend
1314
{
@@ -22,7 +23,10 @@ public interface ITableClient
2223

2324
// Asynchronously retrieves all results from Azure Table
2425
Task<IEnumerable<TEntity>> GetAllAsync<TEntity>(string tableName, TableQuery<TEntity> query) where TEntity : TableEntity, new();
25-
26+
27+
// Asynchronously retrieves all results from Azure Table
28+
Task<IEnumerable<TEntity>> GetAllAsync<TEntity>(string tableName, TableQuery<TEntity> query, CancellationToken ct) where TEntity : TableEntity, new();
29+
2630
// Executes a TableOperation
2731
Task<TableResult> ExecuteAsync(string tableName, TableOperation operation);
2832
}
@@ -119,7 +123,11 @@ public IEnumerable<TEntity> GetAll<TEntity>(string tableName, TableQuery<TEntity
119123
}
120124

121125
/// <inheritdoc/>
122-
public async Task<IEnumerable<TEntity>> GetAllAsync<TEntity>(string tableName, TableQuery<TEntity> query)
126+
public Task<IEnumerable<TEntity>> GetAllAsync<TEntity>(string tableName, TableQuery<TEntity> query)
127+
where TEntity : TableEntity, new() => this.GetAllAsync(tableName, query, CancellationToken.None);
128+
129+
/// <inheritdoc/>
130+
public async Task<IEnumerable<TEntity>> GetAllAsync<TEntity>(string tableName, TableQuery<TEntity> query, CancellationToken ct)
123131
where TEntity : TableEntity, new()
124132
{
125133
var table = this._client.GetTableReference(tableName);
@@ -134,7 +142,9 @@ public async Task<IEnumerable<TEntity>> GetAllAsync<TEntity>(string tableName, T
134142
TableContinuationToken token = null;
135143
do
136144
{
137-
var nextBatch = await table.ExecuteQuerySegmentedAsync(query, token, null, operationContext);
145+
ct.ThrowIfCancellationRequested();
146+
147+
var nextBatch = await table.ExecuteQuerySegmentedAsync(query, token, null, operationContext, ct);
138148

139149
result.AddRange(nextBatch.Results);
140150
token = nextBatch.ContinuationToken;

durablefunctionsmonitor.dotnetisolated.core/Common/DetailedOrchestrationStatus.cs

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,8 @@ internal static async Task<DetailedOrchestrationStatus> CreateFrom(
8181
return result;
8282
}
8383

84+
private static int GetParentInstanceIdTimeoutInSeconds = 15;
85+
8486
internal static async Task<string> GetParentInstanceIdDirectlyFromTable(DurableTaskClient durableClient, string connEnvVariableName, string hubName, string instanceId)
8587
{
8688
var tableClient = await TableClient.GetTableClient(connEnvVariableName);
@@ -131,7 +133,9 @@ internal static async Task<string> GetParentInstanceIdDirectlyFromTable(DurableT
131133
)
132134
);
133135

134-
tableResult = await tableClient.GetAllAsync($"{durableClient.Name}History", executionIdQuery);
136+
// This scan can still take long time, so we'll have to hard-limit it to a few seconds. TaskCancelledException will be handled by upper code.
137+
var cts = new CancellationTokenSource(TimeSpan.FromSeconds(GetParentInstanceIdTimeoutInSeconds));
138+
tableResult = await tableClient.GetAllAsync($"{durableClient.Name}History", executionIdQuery, cts.Token);
135139
}
136140

137141
return tableResult.FirstOrDefault()?.PartitionKey;

durablefunctionsmonitor.dotnetisolated.core/Common/TableClient.cs

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,9 @@ public interface ITableClient
1919
// Asynchronously retrieves all results from Azure Table
2020
Task<IEnumerable<TEntity>> GetAllAsync<TEntity>(string tableName, TableQuery<TEntity> query) where TEntity : TableEntity, new();
2121

22+
// Asynchronously retrieves all results from Azure Table
23+
Task<IEnumerable<TEntity>> GetAllAsync<TEntity>(string tableName, TableQuery<TEntity> query, CancellationToken ct) where TEntity : TableEntity, new();
24+
2225
// Executes a TableOperation
2326
Task<TableResult> ExecuteAsync(string tableName, TableOperation operation);
2427
}
@@ -122,7 +125,11 @@ public IEnumerable<TEntity> GetAll<TEntity>(string tableName, TableQuery<TEntity
122125
}
123126

124127
/// <inheritdoc/>
125-
public async Task<IEnumerable<TEntity>> GetAllAsync<TEntity>(string tableName, TableQuery<TEntity> query)
128+
public Task<IEnumerable<TEntity>> GetAllAsync<TEntity>(string tableName, TableQuery<TEntity> query)
129+
where TEntity : TableEntity, new() => this.GetAllAsync(tableName, query, CancellationToken.None);
130+
131+
/// <inheritdoc/>
132+
public async Task<IEnumerable<TEntity>> GetAllAsync<TEntity>(string tableName, TableQuery<TEntity> query, CancellationToken ct)
126133
where TEntity : TableEntity, new()
127134
{
128135
var table = this._client.GetTableReference(tableName);
@@ -137,7 +144,9 @@ public async Task<IEnumerable<TEntity>> GetAllAsync<TEntity>(string tableName, T
137144
TableContinuationToken token = null;
138145
do
139146
{
140-
var nextBatch = await table.ExecuteQuerySegmentedAsync(query, token, null, operationContext);
147+
ct.ThrowIfCancellationRequested();
148+
149+
var nextBatch = await table.ExecuteQuerySegmentedAsync(query, token, null, operationContext, ct);
141150

142151
result.AddRange(nextBatch.Results);
143152
token = nextBatch.ContinuationToken;

0 commit comments

Comments
 (0)