Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What is the most optimal method of querying a reliable dictionary collection

I would like to use service fabric reliable dictionaries to store data that we intend to query via a rest interface. I was wondering what was the most optimal approach to querying data held in those collections.

The documentation doesn't seem to provide any methods to support querying a IReliableDictionary interface apart from simply enumerating over the collection.

Is the only option to fetch every object out of the reliable dictionary and pop into a List<> collection for querying?

Thanks

like image 290
Richard Baldwin Avatar asked Mar 15 '23 11:03

Richard Baldwin


2 Answers

As Vaclav mentions in his answer, you can always enumerate the entire dictionary and filter as you wish. Additionally, take a look at the docs for IReliableDictionary, specifically CreateEnumerableAsync(ITransaction, Func<TKey, Boolean>, EnumerationMode). This allows you to filter the keys you wish to include in the enumeration up-front, which may improve perf (e.g. by avoiding paging unnecessary values back in from disk).

Simple Example (exception handling/retry/etc. omitted for brevity):

var myDictionary = await this.StateManager.GetOrAddAsync<IReliableDictionary<int, string>>(new Uri("fabric:/myDictionary"));

using (var tx = this.StateManager.CreateTransaction())
{
    // Fetch all key-value pairs where the key an integer less than 10
    var enumerable = await myDictionary.CreateEnumerableAsync(tx, key => key < 10, EnumerationMode.Ordered); 
    var asyncEnumerator = enumerable.GetAsyncEnumerator();

    while (await asyncEnumerator.MoveNextAsync(cancellationToken))
    {
        // Process asyncEnumerator.Current.Key and asyncEnumerator.Current.Value as you wish
    }
}

You could create canned or dynamic key filters corresponding to your REST queries which search based on key - for value-based queries you will need to fall back to full enumeration (e.g. by using the same pattern as above, but omitting the key filter) or use notifications in order to build your own secondary index.

like image 116
tyadam Avatar answered Mar 16 '23 23:03

tyadam


IReliableDictionary implements IEnumerable, which means you can query it with LINQ expressions, same way you would with an IDictionary.

Note that an enumeration over IReliableDictionary uses snapshot isolation, so it is lock free. Basically this means when you start the enumeration you are enumerating over the dictionary as it is at the time you started. If items are added or removed while you're enumerating, those changes won't appear in that enumeration. More info about this and Reliable Collections in general here: https://azure.microsoft.com/en-us/documentation/articles/service-fabric-reliable-services-reliable-collections/

like image 45
Vaclav Turecek Avatar answered Mar 17 '23 00:03

Vaclav Turecek