Skip to content

Commit

Permalink
Implements Pagination to a hardcoded limit in excess of the server ha…
Browse files Browse the repository at this point in the history
…rd limit
  • Loading branch information
jsdbroughton committed Apr 22, 2023
1 parent 29950d8 commit 06e61e2
Show file tree
Hide file tree
Showing 2 changed files with 91 additions and 2 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,71 @@ public async Task<List<Branch>> StreamGetBranches(
var res = await ExecuteGraphQLRequest<StreamData>(request, cancellationToken).ConfigureAwait(false);
return res.stream.branches.items;
}
/// <summary>
/// Get branches from a given stream
/// </summary>
/// <param name="streamId">Id of the stream to get the branches from</param>
/// <param name="branchesLimit">Max number of branches to retrieve</param>
/// <param name="commitsLimit">Max number of commits to retrieve</param>
/// <returns></returns>
public Task<Branches> PagedStreamGetBranches(string streamId, int branchesLimit = 10, int commitsLimit = 10, string? nextCursor = null)
{
return PagedStreamGetBranches(CancellationToken.None, streamId, branchesLimit, commitsLimit);
}

/// <summary>
/// Get paginated branches from a given stream
/// </summary>
/// <param name="cancellationToken"></param>
/// <param name="streamId">Id of the stream to get the branches from</param>
/// <param name="branchesLimit">Max number of branches to retrieve</param>
/// <param name="commitsLimit">Max number of commits to retrieve</param>
/// <param name="nextCursor">Cursor to get the next page of results</param>
/// <returns></returns>
/// <exception cref="Exception"></exception>
public async Task<Branches> PagedStreamGetBranches(
CancellationToken cancellationToken,
string streamId,
int branchesLimit = 10,
int commitsLimit = 10,
string? nextCursor = null
)
{
var request = new GraphQLRequest
{
Query =
$@"query Stream ($streamId: String!) {{
stream(id: $streamId) {{
branches(limit: {branchesLimit}, cursor: ""{nextCursor}"") {{
cursor
items {{
id
name
description
commits (limit: {commitsLimit}) {{
totalCount
cursor
items {{
id
referencedObject
sourceApplication
message
authorName
authorId
branchName
parents
createdAt
}}
}}
}}
}}
}}
}}",
Variables = new { streamId, nextCursor }
};
var res = await ExecuteGraphQLRequest<StreamData>(request, cancellationToken).ConfigureAwait(false);
return res.stream.branches;
}

/// <summary>
/// Creates a branch on a stream.
Expand Down
28 changes: 26 additions & 2 deletions DesktopUI2/DesktopUI2/ViewModels/StreamViewModel.cs
Original file line number Diff line number Diff line change
Expand Up @@ -220,6 +220,9 @@ public async Task GetStream()
}
}

/// The limit of branches to be displayed in the stream, Given a limit to prevent runaway Branch DOS attacks
private const int BranchLimit = 500;

internal async void GetBranchesAndRestoreState()
{
try
Expand All @@ -246,7 +249,17 @@ internal async void GetBranchesAndRestoreState()
AvailableFilters = new List<FilterViewModel>(Bindings.GetSelectionFilters().Select(x => new FilterViewModel(x)));
SelectedFilter = AvailableFilters[0];

Branches = await Client.StreamGetBranches(Stream.id, 100, 0).ConfigureAwait(true);
// Get all branches created in the stream, not limited to the server limits
string nextCursor = null;
var branchCount = 0;

do
{
var branchResponse = await Client.PagedStreamGetBranches(Stream.id, 100, 0, nextCursor).ConfigureAwait(false);
Branches.AddRange(branchResponse.items);
nextCursor = branchResponse.cursor;
branchCount += branchResponse.items.Count;
} while (!string.IsNullOrEmpty(nextCursor) && branchCount <= BranchLimit);

var index = Branches.FindIndex(x => x.name == StreamState.BranchName);
if (index != -1)
Expand Down Expand Up @@ -408,7 +421,18 @@ private void UpdateStreamState()
private async Task GetBranches()
{
var prevBranchName = SelectedBranch != null ? SelectedBranch.Branch.name : StreamState.BranchName;
Branches = await Client.StreamGetBranches(Stream.id, 100, 0).ConfigureAwait(true);

// Get all branches created in the stream, not limited to the server limits
string nextCursor = null;
var branchCount = 0;

do
{
var branchResponse = await Client.PagedStreamGetBranches(Stream.id, 100, 0, nextCursor).ConfigureAwait(false);
Branches.AddRange(branchResponse.items);
nextCursor = branchResponse.cursor;
branchCount += branchResponse.items.Count;
} while (!string.IsNullOrEmpty(nextCursor) && branchCount <= BranchLimit);

var index = Branches.FindIndex(x => x.name == prevBranchName);
if (index != -1)
Expand Down

0 comments on commit 06e61e2

Please sign in to comment.