When and where is the best to initialize reliable collection? - azure-service-fabric

Scenario: statefull SF service will store its state in several reliable collections. Statefull SF is available via remoting.
Do I need to "initialize" the collections before the first use (by calling StateManager.GetOrAddAsync)? Will it help lower the first access to reliable collection or it is not necessary to do this step?
If it is advised to do this init, when is right time and place to do it?
The most reasonable place is right before endless loop in RunAsync but what if method called via remoting will be called before the collections are initialized? Is there going to be any deterioration in performance in that first remoting call (when the collection is going to be initialized)?
Last thing -> when working with reliable collections it is OK to hold reference to collection in class (e.g. during some instance initiation I will get the reference by using StateManager.GetOrAddAsync) and working just with this reference or is better to call StateManager.GetOrAddAsync before every call to collection?
Thanks for answers!

Do I need to "initialize" the collections before the first use (by calling StateManager.GetOrAddAsync)?
Yes, but you don't have to do that to “warm up” collection. Call that method if you really need retrieve some data or want to store something.
what if method called via remoting will be called before the collections are initialized?
That's why you need to do StateManager.GetOrAddAsync on every call to the service.
Is there going to be any deterioration in performance in that first remoting call
Yes. But it will be unnoticeable.
when working with reliable collections it is OK to hold reference to collection in class
You can hold a reference to the collection in a variable within a method call. Here is an example:
public async Task AddPost(Guid userId, PostId postId)
{
try
{
var state = await StateManager.GetOrAddAsync<IReliableDictionary<Guid, List<PostId>>>(StateName);
using (var tx = StateManager.CreateTransaction())
{
await state.AddOrUpdateAsync(
tx,
userId,
addValue: new List<PostId> {postId},
updateValueFactory: (usrId, oldPostsList) =>
{
oldPostsList.Insert(0, postId);
return oldPostsList;
}
);
await tx.CommitAsync();
}
}
catch (TimeoutException)
{
PostsLogger.Singleton.LogWarning("Add post timeout");
throw;
}
catch (Exception ex)
{
PostsLogger.Singleton.LogException(sb.ToString(), ex);
throw;
}
}

Related

Flutter iterate through Stream<List<DocumentSnapshot<Object?>>>

I have an object of type
Stream<List<DocumentSnapshot<Object?>>>
That is returned from my database. I'm using it in a method that sends data and such so I don't believe I can use a stream builder with it to iterate over it.
I want to be able to loop through each one and use an if statement so I can check data on each document snapshot in the list
I worked it out I sumply just had to do
users.listen((List<DocumentSnapshot> documentList) {
// doSomething()
documentList.forEach((DocumentSnapshot document) {
//do code in here
}
}

Bound variable in ViewModel is not updating the displayed value

I was trying to create an countdown timer in ViewModel but i didnt found any method to do that so i ve tried to do this with task delay and while loop but it ends after first task delay. Do u know any other way how to do that or how to repair that one.
public PageViewModel()
{
MethodName();
}
public async void MethodName()
{
CountSeconds = 10;
while (CountSeconds > 0)
{
await Task.Delay(1000);
CountSeconds--;
}
}
The reason why you can`t see others is related to context. You trying to run async code in non-async context.
To solve this problem you can do several ways, which way to choose is your choice and depends on your needs:
await MethodName();
async Task MethodName()
{
CountSeconds = 10;
while (CountSeconds > 0)
{
await Task.Delay(1000);
CountSeconds--;
}
}
Another way is to create various of tasks and execute them, here you can see methods, which can help you.
And as Rand Random metioned it's not about MAUI, it`s about understanding of async programming itself, so for you will be usefull read more about it.
You can use Dispatacher.StartTimer() (available in the DispatcherExtensions class) to create a function that will execute every x seconds/minutes/hours (depending of what you're setting) using the device's clock.
To access the Application's Dispatcher from any class, use the following line:
var dispatcher = Application.Current.Dispatcher;
Since there is no documentation available yet for MAUI, you can read the Device.StartTimer() documentation from Xamarin, which acts exactly the same.

Make iterations of a loop sequentially in Mutiny

I am new in the reactive programming world. I am currently working in a Java reactive application using the Mutiny library.
I need to develop a loop that waits for the previous iteration to finish in order to start the next one. For instance:
List<Uni<T>> uniList = new ArrayList<>();
for (T item : items) { //items is an already fulfilled collection
uniList.add(this.doSomethingAndReturnInUni(item));
}
return Uni.combine().all().unis(uniList).combinedWith(unisToCombine -> {
List<T> list = new ArrayList<>();
unisToCombine.forEach(x ->list.add(x));
return list;
});
The for loop in the example, generates a thread per iteration. I am wondering how to order the i-th call to the method doSomethingAndReturnInUni() waits for the (i-1) call to trigger the event, that is, make the for loop sequentially. It is possible to suscribe those events in such a way?
Could you try something like this?
Builder<Item> items = Uni.join().builder();
for (Item item : items) {
builder.add(this.doSomethingAndReturnInUni(item));
}
return builder.joinAll().andCollectFailures()
.flatMap(itemList -> do whatever you need ...) //itemList type is List<Item>
I don't know why you are using uni, as this should just handle one operation, for loops you should use multi, where you can handle the back pressure, and only get the next event, when one event is finished. Multi can be run sequentially and in parallel.
see https://quarkus.io/blog/mutiny-back-pressure/
I’ve done the same, using Multi’s see the ‘generateData()’ method here:
https://github.com/Serkan80/quarkus-quickstarts/blob/development/redis-streams-quickstart/weather-producer/src/main/java/org/acme/redis/streams/producer/ValuesGenerator.java

.NET Rx - ReplaySubject buffer size not working

I've been using .NET Reactive Extensions to observe log events as they come in. I'm currently using a class that derives from IObservable and uses a ReplaySubject to store the logs, that way I can filter and replay the logs (for example: Show me all the Error logs, or show me all the Verbose logs) without losing the logs I've buffered.
The problem is, even though I've set a buffer size on the subject:
this.subject = new ReplaySubject<LogEvent>(10);
The memory usage of my program goes through the roof when I use OnNext to add to the observable collection on an infinite loop:
internal void WatchForNewEvents()
{
Task.Factory.StartNew(() =>
{
while (true)
{
dynamic parameters = new ExpandoObject();
// TODO: Add parameters for getting specific log events
if (this.logEventRepository.GetManyHasNewResults(parameters))
{
foreach (var recentEvent in this.logEventRepository.GetMany(parameters))
{
this.subject.OnNext(recentEvent);
}
}
// Commented this out for now to really see the memory go up
// Thread.Sleep(1000);
}
});
}
Does the buffer size on ReplaySubject not work? It doesn't seem to be clearing the buffer when the buffer size is reached. Any help much appreciated!
UPDATE:
I add subscribers like this (Is this wrong?):
public IDisposable Subscribe(IObserver<LogEvent> observer)
{
return this.subject.Subscribe(observer);
}
...which is called like:
// Inserts into UI ListView
this.logEventObservable.Subscribe(evt => this.InsertNewLogEvent(evt));
I'm not sure if this is the definitive answer, but I suspect that you're hitting an issue because of concurrency around the scheduler you're using. The constructor you're calling on ReplaySubject looks like this:
public ReplaySubject(int bufferSize)
: this(bufferSize, TimeSpan.MaxValue, Scheduler.CurrentThread)
{ }
The Scheduler.CurrentThread worries me. Try changing it to Scheduler.ThreadPool and see if that helps.
Also, as a side note, you seem to be mixing Rx with TPL and old fashioned thread sleeping. It's usually best to avoid doing that. You could change your WatchForNewEvents code to look like this:
dynamic parameters = new ExpandoObject();
var newEvents =
from n in Observable.Interval(TimeSpan.FromSeconds(1.0))
where this.logEventRepository.GetManyHasNewResults(parameters)
from recentEvent in
this.logEventRepository.GetMany(parameters).ToObservable()
select recentEvent;
newEvents.Subscribe(this.subject);
That's a nice compact Rx-y way of doing things.

return statement from within using

using (IDbCommand command = new SqlCommand())
{
IDbDataAdapter adapter = new SqlDataAdapter();
DataSet ds = new DataSet();
adapter.SelectCommand = command;
command.Connection = _dataAccess.Connection;
command.CommandType = CommandType.StoredProcedure;
command.CommandText = "GetProcData";
command.Parameters.Add(new SqlParameter("#ProcID ", procId));
adapter.Fill(ds);
return ds.Tables[0].AsEnumerable();
}
This returns an IEnumerable DataRow The question is that since the return is within the using statement, will it property dispose of the IDBCommand? I know I can easily refactor this so I change the scope of the DataSet outside of the using, but it is more of a wonder than anything else.
Yes, this will work as expected with IDbCommand being properly disposed. The compiler will transform the using block to a try-catch-finally, where Dispose is invoked in the finally block.
Yes, the DB Command will be disposed, so far so good.
You can get troubles with IEnumerables. Because the items could potentially be produced when getting them from the IEnumerable, not when creating the IEnumerable, that is the nature of it. So it depends on how ds.Tables[0].AsEnumerable() is implemented. It could wait with executing the command until you get the first item. This is in the calling code, outside of the using block. You'll get an error, because the command had been disposed.
This is probably not an issue here, but should always be considered when returning IEnumerables (or lambda expressions) from a using block:
using (A a = new A())
{
return someItems.Select(x => a.Get(x));
}
When accessing the first item, a is already disposed and you get an error.
The IDbCommand is disposed correctly. As a rule of thumb when returning from within a using statement you are fine to do so so long as:
The thing you are returning isn't in the clause of the using
statement
The thing being returned isn't a reference created within the block of the using statement.
In the first case the using statement will dispose of the thing you are trying to return and in the second case the variable will go out of scope.
e.g.
//this is fine as result is createsd outside the scope of the block.
bool result = false;
using (SmtpClient mailClient = new SmtpClient())
{
try
{
mailClient.Send(...);
result = true;
}
catch(SmtpException)
{
result = false;
}
finally
{
return result;
}
}
Here, the using(){ ... } statement is our friend. When we exit the block our SmtpClient is disposed, and the result condition will still exist for you to use.
However, say we are writing a WinForm app or WPF app and we wrap a using block around our data context then we create a problem as the context disappears before the control can consume it.
// this will fail when you bind the customers to a form control!
using (DbContext context = new DBContext())
{
context.Customers.Where(c => c.Name.Contains("Bob")).Load();
return context.Customers.Local;
}
Here, the using(){ ... } statement hurts us. As when we come to dataBind our customer to a GridView (or other such databound control) the fact that we have disposed of the DbContext will mean our form has nothing to bind to so it will throw an exception!
HTH
The scope of your IDbCommand object is very clear: between the brackets { and }. As soon as your program flow exits from there, the object is disposed.