@Brian_Davis that method actually had some issues with regard to how efficiently it parallelized the operations in 2.x, and is not part of the 3.x design. Part of the problem is that the most efficient way to parallelize is going to vary widely by use case. Things like expected document size, number of data nodes, network latency, and configured connection pool size can all affect how many operations can be efficiently run in parallel.
My recommendation is to parallelize the operations yourself. For a small set of documents (say, a couple dozen), you don’t need to worry about anything fancy.
var keys = new[] {"document_1", "document_2", "document_3"};
var tasks = keys.Select(p => bucket.GetAsync(p)).ToList();
await Task.WhenAll(tasks); // Note: This line will throw an exception if ANY of the gets fail
var results = tasks.Select(p => p.Result).ToList();
If you’re trying to get a large number of documents, you may want to implement a limiter to keep the number of in-flight operations under control. For very large numbers of documents, I recommend grouping the requests into parallel batches for the best efficiency.
If you have more specifics about your use case, I’m happy to provide more details.
The issue is that the internal concrete implementation of GetResult has the Id property, but the IGetResult interface exposed to you does not. I see three possibilities.
The SDK could be changed to expose Id on IResult or IGetResult in a future release
You could use reflection to get to the Id property (theoretically unsafe, as the Id property, being internal, is subject to change in future SDK releases)
Alter the logic a bit to keep the Id pair with the task in something like a ValueTuple
var keys = new[] {"document_1", "document_2", "document_3"};
List<(string Id, Task<IGetResult> Task)> tasks = keys.Select(p => (p, bucket.GetAsync(p))).ToList();
await Task.WhenAll(tasks.Select(p => p.Task)); // Note: This line will throw an exception if ANY of the gets fail
List<(string Id, IGetResult Result)> results = tasks.Select(p => (p, p.Result)).ToList();
As this was something discussed when the RFC was written and it is by design, it might make sense to make an extensions library for handling use-cases like this that are outside of the RFC.
Had to put a check for strings and use custom transcoder for that was done with the “Get” Method was working on before.
using (var scope = Datadog.Trace.Tracer.Instance.StartActive(method, null, EnvName))
{
List<(string Id, Task<IGetResult> Task)> tasks;
var typeCode = Type.GetTypeCode(typeof(T));
// Work around for now for "strings" it is a bug in SDK 3.x which is going to be fixed in next release.
if (typeCode == TypeCode.Char || typeCode == TypeCode.String)
{
var options = new GetOptions();
options.Transcoder(_LegacyTranscoder);
// SDK 3.X Wrapper
tasks = keys.Select(p => (p, Get(p,options))).ToList();
}
else
{
// SDK 3.X Wrapper
tasks = keys.Select(p => (p, Get(p))).ToList();
}
await System.Threading.Tasks.Task.WhenAll(tasks.Select(p => p.Item2)); // Note: This line will throw an exception if ANY of the gets fail
List<(string Id, IGetResult result)> results = tasks.Select(p => (p.Id, p.Item2.Result)).ToList();
return results;
}