octokit.graphql.net
octokit.graphql.net copied to clipboard
🚀🚀🚀 TransferAllIssues -> parallel foreach async -> MAGIC :) 🚀🚀🚀
Hi! Maybe someone will need this too - or can implement in octokit.graphql.net.
Adding some parallel foreach async MAGIC :)
public async Task<bool> TransferAllIssues(string fromRepositoryName, string toRepositoryId, string pemKey)
{
var issueIDs = await GetAllIssuesFromRepository(fromRepositoryName, pemKey);
// Async Parallel Foreach in C# -> check extension
issueIDs.AsyncParallelForEach(async issueId =>
{
await TransferIssue(issueId, toRepositoryId, pemKey);
}, 100, TaskScheduler.FromCurrentSynchronizationContext());
return true;
}
public async Task<string> TransferIssue(string issueId, string toRepositoryId, string pemKey)
{
_pemKey = pemKey;
var connection = await GetGraphQlConnection();
var mutation = new Mutation()
.TransferIssue(new TransferIssueInput()
{
IssueId = new ID(issueId),
RepositoryId = new ID(toRepositoryId)
}
)
.Select(payload => new {payload.Issue.Id})
.Compile();
if (connection != null)
{
var result = await connection.Run(mutation);
return result.Id.Value;
}
else
{
// TODO
return "ERROR!!!!!!!!!!!!!!!!!";
}
}
public async Task<IEnumerable<string>> GetAllIssuesFromRepository(string repositoryName, string pemKey)
{
_pemKey = pemKey;
var connection = await GetGraphQlConnection();
var query = new Query()
.RepositoryOwner(StaticData.Organization)
.Repository(repositoryName)
.Issues() // OR with paging: Issues = r.Issues(100, null, null, null, null, null, null, null) + .Nodes -> without AllPages()
.AllPages() // Auto-pages Issues
.Select(issue => new
{
issue.Id
}).Compile();
if (connection != null)
{
var result = await connection.Run(query);
IEnumerable<string> issueIDs = result.Select(i => i.Id.Value);
return issueIDs;
}
else
{
// TODO
return null;
}
}
//
// Parallel Foreach async in C#
// Optimizing Parallel async Foreach with C# 8.0 async streams
// https://scatteredcode.net/parallel-foreach-async-in-c/
//
//
// | Method | Mean | Error | StdDev | Ratio | RatioSD |
// |------------------------------- |---------:|--------:|--------:|------:|--------:|
// | Linear | 244.07 s | 5.703 s | 8.879 s | 1.00 | 0.00 |
// | ForEachAsync | 30.84 s | 1.899 s | 5.324 s | 0.11 | 0.01 |
// | AsyncForEach | 272.10 s | 5.435 s | 8.620 s | 1.12 | 0.05 |
// | ParallelForEachAsync | 26.53 s | 0.339 s | 0.317 s | 0.11 | 0.00 |
// we are using this --> :) --> | AsyncParallelForEach | 25.79 s | 0.490 s | 0.564 s | 0.10 | 0.00 |
// | AsyncEnumerableParallelForEach | 24.67 s | 0.436 s | 0.408 s | 0.10 | 0.00 |
//
public static Task AsyncParallelForEach<T>(this IEnumerable<T> source, Func<T, Task> body, int maxDegreeOfParallelism = DataflowBlockOptions.Unbounded, TaskScheduler scheduler = null)
{
var options = new ExecutionDataflowBlockOptions
{
MaxDegreeOfParallelism = maxDegreeOfParallelism
};
if (scheduler != null)
options.TaskScheduler = scheduler;
var block = new ActionBlock<T>(body, options);
foreach (var item in source)
block.Post(item);
block.Complete();
return block.Completion;
}