private void RefreshPresenceAsync(CancellationToken cancellationToken) { if (cancellationToken.IsCancellationRequested) { return; } this.refreshLock.EnterWriteLock(); try { this.socialGraphState = SocialGraphState.Refresh; // TODO: Fire a presence refresh for these users. List <ulong> userIds = this.userBuffer.Inactive.SocialUserGraph.Keys.ToList(); } finally { this.socialGraphState = SocialGraphState.Normal; this.refreshLock.ExitWriteLock(); // Setup another refresh for the future. // TODO: Make this delay the correct value. Should be something based on RTA. Task.Delay(RefreshDuration).ContinueWith( delayTask => this.RefreshPresenceAsync(cancellationToken), cancellationToken); } }
/// <summary> /// Process the next event that's available and return true if there are more events to process. /// </summary> /// <returns>True if there are more events to process.</returns> private bool ProcessNextEvent() { bool hasRemainingEvent = false; bool hasCachedEvents = false; this.refreshLock.EnterWriteLock(); try { this.socialGraphState = SocialGraphState.EventProcessing; hasCachedEvents = this.IsInitialized && !userBuffer.Inactive.EventQueue.IsEmpty; if (hasCachedEvents) { ProcessCachedEvents(); hasRemainingEvent = true; } else if (this.IsInitialized) { this.socialGraphState = SocialGraphState.Normal; hasRemainingEvent = ProcessEvents(); } else { this.socialGraphState = SocialGraphState.Normal; } } finally { this.refreshLock.ExitWriteLock(); } return(hasRemainingEvent); }
private void ProcessCachedEvents() { InternalSocialEvent internalEvent; if (this.userBuffer.Inactive.EventQueue.TryDequeue(out internalEvent)) { this.ApplyEvent(internalEvent, false); } this.socialGraphState = SocialGraphState.Normal; }
/// <summary> /// Background task to refresh the graph. This would be great to do in a loop but there's not /// an easy way to do so without await, so we'll go ahead with the current pattern. /// </summary> /// <param name="cancellationToken"></param> /// <returns></returns> private void RefreshGraphAsync(CancellationToken cancellationToken) { if (cancellationToken.IsCancellationRequested) { return; } this.peopleHubService.GetSocialGraph(this.localUser, this.detailLevel) .ContinueWith(t => { try { if (!t.IsFaulted) { this.refreshLock.EnterWriteLock(); this.socialGraphState = SocialGraphState.Refresh; List <XboxSocialUser> userRefreshList = new List <XboxSocialUser>(); foreach (XboxSocialUser graphUser in this.userBuffer.Inactive.SocialUserGraph.Values) { if (!graphUser.IsFollowedByCaller) { userRefreshList.Add(graphUser); } } // TODO: We have some RTA triggers to called based on the userRefreshList. // Regardless, we can perform the diff which will give us any change events. this.PerformDiff(t.Result); } } finally { this.socialGraphState = SocialGraphState.Normal; this.refreshLock.ExitWriteLock(); // Setup another refresh for the future. Task nextRefresh = Task.Delay(RefreshDuration).ContinueWith( delayTask => this.RefreshGraphAsync(cancellationToken), cancellationToken); } }); }
private void PerformDiff(List <XboxSocialUser> xboxSocialUsers) { try { this.socialGraphState = SocialGraphState.Diff; List <XboxSocialUser> usersAddedList = new List <XboxSocialUser>(); List <ulong> usersRemovedList = new List <ulong>(); List <XboxSocialUser> presenceChangeList = new List <XboxSocialUser>(); List <XboxSocialUser> socialRelationshipChangeList = new List <XboxSocialUser>(); List <XboxSocialUser> profileChangeList = new List <XboxSocialUser>(); foreach (XboxSocialUser currentUser in xboxSocialUsers) { XboxSocialUser existingUser; if (!this.userBuffer.Inactive.SocialUserGraph.TryGetValue(currentUser.XboxUserId, out existingUser)) { usersAddedList.Add(currentUser); continue; } var changes = existingUser.GetChanges(currentUser); if (changes.HasFlag(ChangeListType.ProfileChange)) { presenceChangeList.Add(currentUser); } if (changes.HasFlag(ChangeListType.SocialRelationshipChange)) { socialRelationshipChangeList.Add(currentUser); } if (changes.HasFlag(ChangeListType.PresenceChange)) { profileChangeList.Add(currentUser); } } foreach (XboxSocialUser socialUser in this.userBuffer.Inactive.SocialUserGraph.Values) { if (socialUser.XboxUserId.ToString() == this.localUser.XboxUserId) { continue; } if (!xboxSocialUsers.Contains(socialUser, XboxSocialUserIdEqualityComparer.Instance)) { usersRemovedList.Add(socialUser.XboxUserId); } } if (usersAddedList.Count > 0) { this.internalEventQueue.Enqueue(InternalSocialEventType.UsersChanged, usersAddedList); } if (usersRemovedList.Count > 0) { this.internalEventQueue.Enqueue(InternalSocialEventType.UsersRemoved, usersRemovedList); } if (presenceChangeList.Count > 0) { this.internalEventQueue.Enqueue(InternalSocialEventType.PresenceChanged, presenceChangeList); } if (profileChangeList.Count > 0) { this.internalEventQueue.Enqueue(InternalSocialEventType.ProfilesChanged, profileChangeList); } if (socialRelationshipChangeList.Count > 0) { this.internalEventQueue.Enqueue(InternalSocialEventType.SocialRelationshipsChanged, socialRelationshipChangeList); } } finally { this.socialGraphState = SocialGraphState.Normal; } }