Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ObserverManager Notify should fan out #8284

Open
bjorkstromm opened this issue Jan 26, 2023 · 2 comments
Open

ObserverManager Notify should fan out #8284

bjorkstromm opened this issue Jan 26, 2023 · 2 comments

Comments

@bjorkstromm
Copy link
Contributor

Peeked at the code for ObserverManager Notify, and I think we should fan out notifications. Notifying all observers in serial is not necessary in my opinion.

try
{
await notification(observer.Value.Observer);
}
catch (Exception)
{
// Failing observers are considered defunct and will be removed..
defunct ??= new List<TIdentity>();
defunct.Add(observer.Key);
}

@ghost ghost added the Needs: triage 🔍 label Jan 26, 2023
@ReubenBond
Copy link
Member

Good idea

@willg1983
Copy link
Contributor

If the notifiation delegate had closure over grain state would that introduce either conurrency or re-entrant behaviour by stealth?

Separately, but related to that are a few other problems/limitations I've seen with the current implementation, which could be addressed at the same time:

Calling Notify from a re-entrant grain can result in an InvalidOperationException - Collection was modified; enumeration operation may not execute. I assume because whilst the ObserverManager is using foreach loop to notify each observer (and awaiting completion) a re-entrant grain is free to process subscribe/unsubscribe commands from other observers which modify the underlying Dictionary in the ObserverManager, leading to the exception when the loop resumes.

It would be useful (at least I would find it useful) to be able to set a timeout for the observer notification, so that a slow observer does not hang the grain and is treated as defunct and removed. Not sure if there's already a good mechanism for doing this? or whether something like #7837 would address this? I currently use WaitAsync peppered around my observer notifications but it feels like boilerplate code that could be moved to the ObserverManager.

Should we look at supporting serialization of the ObserverManager so that a grain activation with observers that fails, can be re-activated on another silo and continue sending to the set of observers already subscribed to it, without waiting for them to re-subsubscribe when they hit their expiry time.

It might also be useful to change the method name of Notify to NotifyAsync as per naming conventions and possibly add cancellation token support - although that has marginal benefit.

All this may suggest revisiting the implementation of ObserverManager to fix the re-entrant bug and make the state serializable, and maybe add an new method to support fan-out distribution explicitly (which can follow the async naming convention and take a cancellation token for example).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants