[WIP] Shared state publisher prototype#3291
Conversation
| @@ -0,0 +1,17 @@ | |||
| | |||
| namespace Orleans | |||
There was a problem hiding this comment.
classes in ../Utils/SharedState/.. are shared state infrastructure. Common to all uses of the shared state.
| @@ -0,0 +1,40 @@ | |||
| | |||
| namespace Orleans.Runtime | |||
| { | |||
There was a problem hiding this comment.
SiloStatusChange and SiloStatusSharedState expose silo status as shared state.
| @@ -87,6 +85,8 @@ public override Task Initialize(string strProviderName, | |||
| } | |||
| this.allQueues = new ReadOnlyCollection<QueueId>(queueMapper.GetAllQueues().ToList()); | |||
| this.siloMaturityPeriod = siloMaturityPeriod; | |||
There was a problem hiding this comment.
Queue balancer uses the shared state, rather than being a listener itself, limiting it to only accessing the silo status changes from it's own thread. In this case, the queue manager system target's thread.
| { | ||
| this.siloStatusSharedState = await this.siloStatusSharedState.NextAsync; | ||
| HandleSiloStatusChange(this.siloStatusSharedState.State); | ||
| } |
There was a problem hiding this comment.
As long as the silo is not terminating, the thread will wait for silo status changes, process them, then wait for the next change. It can only access the change in the it's own thread.
|
|
||
| public void SiloStatusChangeNotification(SiloAddress updatedSilo, SiloStatus status) | ||
| { | ||
| this.Publish(new SiloStatusChange(updatedSilo, status)); |
There was a problem hiding this comment.
When we get a SiloStatusChangeNotification (on the silo status oracle's thread) all we do is publish the change. Other threads that want to handle the change must access it via the ISharedState from their own thread.
| try | ||
| { | ||
| this.siloStatusSharedState = await this.siloStatusSharedState.NextAsync; | ||
| HandleSiloStatusChange(this.siloStatusSharedState.State); |
There was a problem hiding this comment.
I think ideal behavior is only process new state when there's a change. But this code seems to process state regardless whether it is new or not. Since NextAsync=> this.NextCompletion.Task; while NextCompletion.Result only get updated when there's new state. So most of the time the code keep processing the old NextCompletion.Result. Am I right? Or did I miss anything?
There was a problem hiding this comment.
And also keep a while loop here seems to bring more performance penalty, since there's always a thread occupied, keep running this while loop until Terminating. Am I right?
So if this is the expected usage pattern for this feature, then we can have extra performance penalty if we use this feature?
There was a problem hiding this comment.
Think ideal behavior is only process new state when there's a change
A new state is only available for processing when the task on NextAsync returns the next shared state. The task in the next shared state is not resolved until a new state is published, so upon the task of NextAsync being resolved, we have a new state to process, and a new task to await for the next state change.
There was a problem hiding this comment.
Regarding the performance, we'll always have a pending task on the state listener's thread (in this case, the queue manager's thread), but that does not take up cpu.
Prototype for discussion purposes.
NOT FOR CHECKIN
This PR explores using a shared state publisher pattern to notify other threads of immutable state in a thread safe manner.
In this prototype, the silo status change notifications are exposed as shared state to the queue balancer, so that no queue balancing logic is run on the silo status oracle's thread.