FuturistiCoder / LiteDB.Realtime

A LiteDB with realtime notifications
MIT License
42 stars 10 forks source link

Frequency of updates cannot be throttled #6

Closed pomeara closed 4 years ago

pomeara commented 4 years ago

Hello, I am using this LiteDB.Realtime and love it's functionality, I am also updating the collections quite quickly and am looking to find a throttle mechanism so that I can 'batch changes' or 'throttle changes' to only happen say each second vs multiple milliseconds apart when I update individual items in the collection

Can you advise if this is capable, if not I think this would be a great update/feature to add to this library

Thanks in advance

FuturistiCoder commented 4 years ago

Hello @pomeara , Thanks for your advice. I'm working on it.

FuturistiCoder commented 4 years ago

@pomeara , I just released a new version 1.1.0 and updated Readme. You can try it.

// you can throttle the notifications by 1 second for example.
db.Realtime
    .Collection<Item>("items")
    .Raw
    .Throttle(TimeSpan.FromSecond(1)) // System.Reactive
    .Subscribe(col =>
    {
        var list = col.Query().OrderBy(i => i.Id).Limit(10).ToList();
        Update(list);
    });
pomeara commented 4 years ago

@FuturistiCoder great stuff I'll give it a try and let you know how it goes. Can I check the syntax for subscribing to a single docmuemnt within a collection please is it something like

`

db.Realtime .Collection("items") .Id(xxx) .Subscribe(col => { Update(singleDocument); });`

FuturistiCoder commented 4 years ago

@pomeara

db.Realtime
    .Collection<Item>("items")
    .Id(itemId)
    .Subscribe(item => Update(item));
FuturistiCoder commented 4 years ago

@pomeara There are some examples in Readme.md

pomeara commented 4 years ago

Hi @FuturistiCoder I have been looking at the notifications for a new document being added and can only see that the entire collection is always passed rather than a single document.

I looked at the examples and these provide a single insert into an empty database so this only provides a single document, if however I have multiple threads inserting documents at different times I am curious if the capability to only receive the inserted documents exists

I can get the collection and sort it and just take the last document based on a new timestamp I have added however if there are 1000+ documents in a collection these are all loaded into memory just to filter out to get the last one inserted

Many thanks

FuturistiCoder commented 4 years ago

@pomeara , From what I know, you want to be notified with a ChangeSet which contains Updates, Inserts, Deletes etc. But I didn't implemented it yet. I need time to figure out if it's possible without modifying LiteDB.

Still, there are some solutions for now.

db.Realtime
    .Collection<Item>("items")
    .Raw
    .Throttle(TimeSpan.FromSecond(1))
    .Subscribe(col =>
    {
        var list = col.Find(item => item.DateTime > _lastDateTime).ToList();
        UpdateLastDateTime();
        Update(list);
    });           
db.Realtime
    .Collection<Item>("items")
    .Raw
    .Throttle(TimeSpan.FromSecond(1))
    .Subscribe(col =>
    {
        var list = col.Query().ToList();
        // DynamicData lib here, you can change the comparer
         _yourSourceCache.EditDiff(list, (item1, item2) => item1.Equals(item2));
    });

Your SourceCache is now synchronized with LiteDB. Then subscribe to your SourceCahce to get IChangeSet notifications.

_yourSourceCache.Connect()
                .Sort(SortExpressionComparer<Item>.Descending(item => item.DateTime))
                .ObserveOn(RxApp.MainThreadScheduler)
                .Bind(out _items)
                .Subscribe();
pomeara commented 4 years ago

@FuturistiCoder thanks for the information, I will look into this to see how I can incorporate it into my solution.

Thanks for a great repo, it has a lot of potential looking forward to future updates

FuturistiCoder commented 4 years ago

throttle can be done from v1.1.0