Skip to content

Commit 372dfd4

Browse files
authored
Merge pull request #3528 from koskila/antti/add-retry-to-submitpnpsearchquery2
Add retry logic to Submit-PnPSearchQuery
2 parents 5e7cf7c + 7fe2acd commit 372dfd4

File tree

3 files changed

+93
-36
lines changed

3 files changed

+93
-36
lines changed

CHANGELOG.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/).
3939
- Added GCC support for `Get-PnPAzureADUser` , `Add-PnPFlowOwner` , `Remove-PnPFlowOwner`, `Sync-PnPSharePointUserProfilesFromAzureActiveDirectory`, `New-PnPAzureADUserTemporaryAccessPass` and `Get-PnPAvailableSensitivityLabel` cmdlets. [#3484](https://github.com/pnp/powershell/pull/3484)
4040
- Added a devcontainer for easily building a minimal environment necessary to contribute to the project. [#3497](https://github.com/pnp/powershell/pull/3497)
4141
- Added `-RelativeUrl` parameter to `Connect-PnPOnline` cmdlet to allow specifying custom URLs for usage with `-WebLogin` method. [#3530](https://github.com/pnp/powershell/pull/3530)
42+
- Added `-RetryCount` to `Submit-PnPSearchQuery` which allows for specifying the number of retries to perform when an exception occurs [#3528](https://github.com/pnp/powershell/pull/3528)
4243
- Added `-MailNickname` parameter to `Set-PnPMicrosoft365Group` cmdlet to allow changing of this property on a Microsoft 365 Group [#3529](https://github.com/pnp/powershell/pull/3529)
4344

4445
### Fixed
@@ -85,6 +86,7 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/).
8586

8687
### Contributors
8788

89+
- Antti K. Koskela [koskila]
8890
- Christian Veenhuis [ChVeen]
8991
- Kunj Balkrishna Sangani [kunj-sangani]
9092
- Antti K. Koskela [koskila]

documentation/Submit-PnPSearchQuery.md

Lines changed: 29 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ Submit-PnPSearchQuery [-Query] <String> [-StartRow <Int32>] [-MaxResults <Int32>
2222
[-RankingModelId <String>] [-ClientType <String>] [-CollapseSpecification <String>]
2323
[-HiddenConstraints <String>] [-TimeZoneId <Int32>] [-EnablePhonetic <Boolean>] [-EnableStemming <Boolean>]
2424
[-EnableQueryRules <Boolean>] [-SourceId <Guid>] [-ProcessBestBets <Boolean>]
25-
[-ProcessPersonalFavorites <Boolean>] [-RelevantResults] [-Connection <PnPConnection>]
25+
[-ProcessPersonalFavorites <Boolean>] [-RelevantResults] [-Connection <PnPConnection>] [-RetryCount <Int32>] [-Verbose]
2626
2727
```
2828

@@ -34,7 +34,7 @@ Submit-PnPSearchQuery [-Query] <String> [-All] [-TrimDuplicates <Boolean>] [-Pro
3434
[-CollapseSpecification <String>] [-HiddenConstraints <String>] [-TimeZoneId <Int32>]
3535
[-EnablePhonetic <Boolean>] [-EnableStemming <Boolean>] [-EnableQueryRules <Boolean>] [-SourceId <Guid>]
3636
[-ProcessBestBets <Boolean>] [-ProcessPersonalFavorites <Boolean>] [-RelevantResults]
37-
[-Connection <PnPConnection>]
37+
[-Connection <PnPConnection>] [-RetryCount <Int32>] [-Verbose]
3838
```
3939

4040
## DESCRIPTION
@@ -353,6 +353,20 @@ Accept pipeline input: False
353353
Accept wildcard characters: False
354354
```
355355
356+
### -RetryCount
357+
How many times to retry for a failed query. Default is 0 (no retries). Will wait 5 seconds between each retry.
358+
359+
```yaml
360+
Type: Int32
361+
Parameter Sets: (All)
362+
363+
Required: False
364+
Position: Named
365+
Default value: 0
366+
Accept pipeline input: False
367+
Accept wildcard characters: False
368+
```
369+
356370
### -SelectProperties
357371
The list of properties to return in the search results, separated by a comma. I.e. ComplianceTag,InformationProtectionLabelId.
358372
@@ -437,9 +451,20 @@ Accept pipeline input: False
437451
Accept wildcard characters: False
438452
```
439453
454+
### -Verbose
455+
When provided, additional debug statements will be shown while executing the cmdlet.
440456
457+
```yaml
458+
Type: SwitchParameter
459+
Parameter Sets: (All)
441460

442-
## RELATED LINKS
461+
Required: False
462+
Position: Named
463+
Default value: None
464+
Accept pipeline input: False
465+
Accept wildcard characters: False
466+
```
443467
444-
[Microsoft 365 Patterns and Practices](https://aka.ms/m365pnp)
468+
## RELATED LINKS
445469
470+
[Microsoft 365 Patterns and Practices](https://aka.ms/m365pnp)

src/Commands/Search/SubmitSearchQuery.cs

Lines changed: 62 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
using Microsoft.SharePoint.Client.Search.Query;
66
using System.Collections.Generic;
77
using System.Linq;
8+
using System.Threading;
89

910
namespace PnP.PowerShell.Commands.Search
1011
{
@@ -85,6 +86,9 @@ public class SubmitSearchQuery : PnPWebCmdlet
8586
[Parameter(Mandatory = false, ParameterSetName = ParameterAttribute.AllParameterSets)]
8687
public SwitchParameter RelevantResults;
8788

89+
[Parameter(Mandatory = false, ParameterSetName = ParameterAttribute.AllParameterSets)]
90+
public int RetryCount = 0;
91+
8892
internal IEnumerable<object> Run()
8993
{
9094
int startRow = StartRow;
@@ -121,53 +125,79 @@ internal IEnumerable<object> Run()
121125
keywordQuery.QueryText += " IndexDocId>" + lastDocId;
122126
}
123127

124-
var searchExec = new SearchExecutor(ClientContext);
125-
var results = searchExec.ExecuteQuery(keywordQuery);
126-
ClientContext.ExecuteQueryRetry();
127-
128-
if (results.Value != null)
128+
// We'll always try at least once, even if RetryCount is 0 (default)
129+
for (var iterator = 0; iterator <= RetryCount; iterator++)
129130
{
130-
if (finalResults == null)
131+
try
131132
{
132-
finalResults = (PnPResultTableCollection)results.Value;
133-
foreach (ResultTable resultTable in results.Value)
133+
var searchExec = new SearchExecutor(ClientContext);
134+
var results = searchExec.ExecuteQuery(keywordQuery);
135+
ClientContext.ExecuteQueryRetry();
136+
137+
if (results.Value != null)
134138
{
135-
if (resultTable.TableType == "RelevantResults")
139+
if (finalResults == null)
136140
{
137-
currentCount = resultTable.RowCount;
138-
if (currentCount > 0)
141+
finalResults = (PnPResultTableCollection)results.Value;
142+
foreach (ResultTable resultTable in results.Value)
139143
{
140-
lastDocId = resultTable.ResultRows.Last()["DocId"].ToString();
144+
if (resultTable.TableType == "RelevantResults")
145+
{
146+
currentCount = resultTable.RowCount;
147+
if (currentCount > 0)
148+
{
149+
lastDocId = resultTable.ResultRows.Last()["DocId"].ToString();
150+
}
151+
}
141152
}
142153
}
143-
}
144-
}
145-
else
146-
{
147-
// we're in paging mode
148-
foreach (ResultTable resultTable in results.Value)
149-
{
150-
PnPResultTable pnpResultTable = (PnPResultTable)resultTable;
151-
var existingTable = finalResults.SingleOrDefault(t => t.TableType == resultTable.TableType);
152-
if (existingTable != null)
153-
{
154-
existingTable.ResultRows.AddRange(pnpResultTable.ResultRows);
155-
}
156154
else
157155
{
158-
finalResults.Add(pnpResultTable);
159-
}
160-
if (pnpResultTable.TableType == "RelevantResults")
161-
{
162-
currentCount = resultTable.RowCount;
163-
if (currentCount > 0)
156+
// we're in paging mode
157+
foreach (ResultTable resultTable in results.Value)
164158
{
165-
lastDocId = resultTable.ResultRows.Last()["DocId"].ToString();
159+
PnPResultTable pnpResultTable = (PnPResultTable)resultTable;
160+
var existingTable = finalResults.SingleOrDefault(t => t.TableType == resultTable.TableType);
161+
if (existingTable != null)
162+
{
163+
existingTable.ResultRows.AddRange(pnpResultTable.ResultRows);
164+
}
165+
else
166+
{
167+
finalResults.Add(pnpResultTable);
168+
}
169+
if (pnpResultTable.TableType == "RelevantResults")
170+
{
171+
currentCount = resultTable.RowCount;
172+
if (currentCount > 0)
173+
{
174+
lastDocId = resultTable.ResultRows.Last()["DocId"].ToString();
175+
}
176+
}
166177
}
167178
}
168179
}
180+
181+
// If we were successful (and didn't end in the catch block), we don't want to retry -> break out of retry loop
182+
break;
169183
}
184+
// If we're not retrying, or if we're on the last retry, don't catch the exception
185+
catch (Exception ex)
186+
{
187+
if (RetryCount > 0 && iterator < RetryCount)
188+
{
189+
var waitTime = 5 * (iterator + 1);
170190

191+
WriteVerbose($"Search operation failed with exception {ex.Message}. Attempt {iterator + 1} out of {RetryCount}. Retrying in {waitTime} seconds.");
192+
193+
Thread.Sleep(TimeSpan.FromSeconds(waitTime));
194+
continue;
195+
}
196+
else
197+
{
198+
throw;
199+
}
200+
}
171201
}
172202
startRow += rowLimit;
173203
} while (currentCount == rowLimit && All.IsPresent);

0 commit comments

Comments
 (0)