ReubenBond on master
Remove SimpleAzureQueueAdapter … (compare)
Without persistent state you can't guarantee that there are single instances for something which is purely in-memory.
@ReubenBond can you expand on above statement from :point_up: January 20, 2020 9:06 AM
By Persistent state did you meant grain which are having state using [PersistentState] or similar attribute. I wanted to make sure I am reading it wrong :) Not related to original question but wanted to understand more if there are some nuances which I should be aware of.
The in-built grain directory implementation in Orleans is eventually-consistent, @sammym1982. That can become an issue when the cluster isn't in a steady state and calls for the same grain come in quick success - if nothing is done to mitigate it. The mitigation is persistent state. Any time a grain activation tries to write state, a concurrency check is performed to make sure the grain activation has the latest state (i.e, it has seen all previous writes). If that is not true then an exception is thrown and the grain is deactivating, making the convergence quicker.
Without that mitigation (or something to a similar effect), it's possible for multiple activations of the grain to exist simultaneously for a short period of time. Those duplicates are proactively killed as the directory converges.
ISiloBuilder
& IHostBuilder
from TestClusters ☺ The implementation is very simple in the end.
@Zeroshi @COCPORN
why couldnt you add an if statement to determine if it should run? @sergeybykov any idea?
Early on, we were concerned about deactivating grains under perceived memory pressure, primarily because it wasn't clear how to measure what amount of memory is actually being used by the app logic as opposed to the amount of Gen2 memory garbage accumulated since the last Gen2 pass of the memory manager. I suspect it should be more clear these days.
It's a bit more than adding an if statement because grains activations are tracked in buckets, from most recently used ones to LRU. Other than that, at least conceptually, it could be a matter of checking for memory pressure (if configured) upon every activation collection cycle and adding an oldest bucket or two for collection.
@Zeroshi
hi @sergeybykov , I was checking in to see if you had a chance to read that essay.
Sorry, I dropped the ball when we suddenly got some snow. I read it now. I think it'd be better for us to chat thematically over Teams/Skype than for me to try to type the same thoughts, and then for us to go back and forth. A voice dialog is an efficient means of arriving to something. 🙂
Silo A hosts Grain A1
Silo B hosts Grain B1 which has method DoSomething(Customer customer)
I call grain B1 from clusterclient, the invocation goes to A1 which deserializes the message (and crashes because it does not know about Customer) and does not resend the message to B1
Hi,
i have a question regarding async running methods.
This is a examplecode of a GrainMethod:
public Task GrainMethod()
{
_anotherGrain = GrainFactory.GetGrain<IBasicMeasurementDevice>(guid);
_anotherGrain.AnotherGrainMethod().ContinueWith(task =>
{
//modify private members in Grain;
}, TaskContinuationOptions.OnlyOnFaulted);
}
I want to run the "AnotherGrain" Method without awaiting for it. But if there occurs a exception, I want to modifie the state of the caller grain.
Could this solution lead to race conditions?
@COCPORN
@sergeybykov Yes, it was hyperbole from me. About the buckets, perhaps I've misunderstood how they work. It looks to just be sorted on expiry time, and then I suppose any grain that has activity moves itself to another bucket based on the time to live configuration. I could take a stab at implementing my suggestion, as I think the amount of work needed to have something that is useful (or can at least be evaluated for usefulness) isn't that big.
Yes, when a grain is invoked, it gets moved to the most recent bucket, unless it's already there. If you are willing to take a stab at it, we'll be happy to help.