/// <summary> /// Update following relationship. /// Following user : someone who i am following. /// </summary> /// <param name="storageConsistencyMode">Consistency mode</param> /// <param name="relationshipHandle">Relationship handle</param> /// <param name="userHandle">User handle</param> /// <param name="relationshipUserHandle">Relationship user handle</param> /// <param name="appHandle">App handle</param> /// <param name="userRelationshipStatus">User relationship status</param> /// <param name="lastUpdatedTime">Last updated time</param> /// <param name="readUserRelationshipLookupEntity">Read user relationship lookup entity</param> /// <returns>Update following relationship task</returns> public async Task UpdateFollowingRelationship( StorageConsistencyMode storageConsistencyMode, string relationshipHandle, string userHandle, string relationshipUserHandle, string appHandle, UserRelationshipStatus userRelationshipStatus, DateTime lastUpdatedTime, IUserRelationshipLookupEntity readUserRelationshipLookupEntity) { CTStore store = await this.tableStoreManager.GetStore(ContainerIdentifier.UserFollowing); ObjectTable lookupTable = this.tableStoreManager.GetTable(ContainerIdentifier.UserFollowing, TableIdentifier.FollowingLookup) as ObjectTable; FeedTable feedTable = this.tableStoreManager.GetTable(ContainerIdentifier.UserFollowing, TableIdentifier.FollowingFeed) as FeedTable; CountTable countTable = this.tableStoreManager.GetTable(ContainerIdentifier.UserFollowing, TableIdentifier.FollowingCount) as CountTable; await this.UpdateUserRelationship( storageConsistencyMode, relationshipHandle, userHandle, relationshipUserHandle, appHandle, userRelationshipStatus, lastUpdatedTime, readUserRelationshipLookupEntity, store, lookupTable, feedTable, countTable); }
/// <summary> /// Get target relationship status /// </summary> /// <param name="relationshipOperation">Relationship operation</param> /// <returns>Relationship status</returns> private UserRelationshipStatus GetRelationshipStatus(RelationshipOperation relationshipOperation) { UserRelationshipStatus userRelationshipStatus = UserRelationshipStatus.None; switch (relationshipOperation) { case RelationshipOperation.BlockUser: userRelationshipStatus = UserRelationshipStatus.Blocked; break; case RelationshipOperation.UnblockUser: userRelationshipStatus = UserRelationshipStatus.None; break; case RelationshipOperation.AcceptUser: userRelationshipStatus = UserRelationshipStatus.Follow; break; case RelationshipOperation.RejectUser: userRelationshipStatus = UserRelationshipStatus.None; break; case RelationshipOperation.FollowUser: userRelationshipStatus = UserRelationshipStatus.Follow; break; case RelationshipOperation.PendingUser: userRelationshipStatus = UserRelationshipStatus.Pending; break; case RelationshipOperation.UnfollowUser: userRelationshipStatus = UserRelationshipStatus.None; break; case RelationshipOperation.DeleteFollower: userRelationshipStatus = UserRelationshipStatus.None; break; } return(userRelationshipStatus); }
/// <summary> /// Get count key from app handle and relationship status /// </summary> /// <param name="appHandle">App handle</param> /// <param name="relationshipStatus">Relationship status</param> /// <returns>Count key</returns> private string GetCountKey(string appHandle, UserRelationshipStatus relationshipStatus) { return(string.Join("+", appHandle, relationshipStatus.ToString())); }
/// <summary> /// Update user relationship /// </summary> /// <param name="storageConsistencyMode">Consistency mode</param> /// <param name="relationshipHandle">Relationship handle</param> /// <param name="userHandle">User handle</param> /// <param name="relationshipUserHandle">Relationship user handle</param> /// <param name="appHandle">App handle</param> /// <param name="userRelationshipStatus">Relationship status</param> /// <param name="lastUpdatedTime">Last updated time</param> /// <param name="readUserRelationshipLookupEntity">Read user relationship lookup entity</param> /// <param name="store">store object</param> /// <param name="lookupTable">lookup table</param> /// <param name="feedTable">feed table</param> /// <param name="countTable">count table</param> /// <returns>Update follower relationship task</returns> private async Task UpdateUserRelationship( StorageConsistencyMode storageConsistencyMode, string relationshipHandle, string userHandle, string relationshipUserHandle, string appHandle, UserRelationshipStatus userRelationshipStatus, DateTime lastUpdatedTime, IUserRelationshipLookupEntity readUserRelationshipLookupEntity, CTStore store, ObjectTable lookupTable, FeedTable feedTable, CountTable countTable) { string objectKey = this.GetObjectKey(appHandle, relationshipUserHandle); string feedKey = this.GetFeedKey(appHandle, userRelationshipStatus); string countKey = this.GetCountKey(appHandle, userRelationshipStatus); Transaction transaction = new Transaction(); UserRelationshipFeedEntity relationshipFeedEntity = new UserRelationshipFeedEntity() { RelationshipHandle = relationshipHandle, UserHandle = relationshipUserHandle }; if (readUserRelationshipLookupEntity == null) { UserRelationshipLookupEntity newRelationshipLookupEntity = new UserRelationshipLookupEntity() { RelationshipHandle = relationshipHandle, LastUpdatedTime = lastUpdatedTime, UserRelationshipStatus = userRelationshipStatus, }; transaction.Add(Operation.Insert(lookupTable, userHandle, objectKey, newRelationshipLookupEntity)); if (userRelationshipStatus != UserRelationshipStatus.None) { transaction.Add(Operation.Insert(feedTable, userHandle, feedKey, relationshipHandle, relationshipFeedEntity)); transaction.Add(Operation.InsertOrIncrement(countTable, userHandle, countKey)); } } else { UserRelationshipStatus oldUserRelationshipStatus = readUserRelationshipLookupEntity.UserRelationshipStatus; string oldRelationshipHandle = readUserRelationshipLookupEntity.RelationshipHandle; readUserRelationshipLookupEntity.RelationshipHandle = relationshipHandle; readUserRelationshipLookupEntity.UserRelationshipStatus = userRelationshipStatus; readUserRelationshipLookupEntity.LastUpdatedTime = lastUpdatedTime; string oldFeedKey = this.GetFeedKey(appHandle, oldUserRelationshipStatus); string oldCountKey = this.GetCountKey(appHandle, oldUserRelationshipStatus); transaction.Add(Operation.Replace(lookupTable, userHandle, objectKey, readUserRelationshipLookupEntity as UserRelationshipLookupEntity)); if (userRelationshipStatus == oldUserRelationshipStatus) { if (userRelationshipStatus != UserRelationshipStatus.None && relationshipHandle != oldRelationshipHandle) { transaction.Add(Operation.Delete(feedTable, userHandle, oldFeedKey, oldRelationshipHandle)); transaction.Add(Operation.Insert(feedTable, userHandle, feedKey, relationshipHandle, relationshipFeedEntity)); } } else { if (userRelationshipStatus != UserRelationshipStatus.None) { transaction.Add(Operation.Insert(feedTable, userHandle, feedKey, relationshipHandle, relationshipFeedEntity)); transaction.Add(Operation.InsertOrIncrement(countTable, userHandle, countKey)); } if (oldUserRelationshipStatus != UserRelationshipStatus.None) { transaction.Add(Operation.Delete(feedTable, userHandle, oldFeedKey, oldRelationshipHandle)); transaction.Add(Operation.Increment(countTable, userHandle, oldCountKey, -1.0)); } } } await store.ExecuteTransactionAsync(transaction, storageConsistencyMode.ToConsistencyMode()); }
/// <summary> /// Update a relationship between two users /// </summary> /// <param name="processType">Process type</param> /// <param name="relationshipOperation">User relationship operation</param> /// <param name="relationshipHandle">Relationship handle</param> /// <param name="followerKeyUserHandle">Follower key user handle</param> /// <param name="followingKeyUserHandle">Following key user handle</param> /// <param name="appHandle">App handle</param> /// <param name="lastUpdatedTime">Last updated time</param> /// <param name="followerRelationshipLookupEntity">Follower relationship lookup entity</param> /// <param name="followingRelationshipLookupEntity">Following relationship lookup entity</param> /// <returns>Update relationship task</returns> public async Task UpdateRelationshipToUser( ProcessType processType, RelationshipOperation relationshipOperation, string relationshipHandle, string followerKeyUserHandle, string followingKeyUserHandle, string appHandle, DateTime lastUpdatedTime, IUserRelationshipLookupEntity followerRelationshipLookupEntity, IUserRelationshipLookupEntity followingRelationshipLookupEntity) { UserRelationshipStatus userRelationshipStatus = this.GetRelationshipStatus(relationshipOperation); if (processType == ProcessType.Frontend) { await this.userRelationshipsStore.UpdateFollowerRelationship( StorageConsistencyMode.Strong, relationshipHandle, followerKeyUserHandle, followingKeyUserHandle, appHandle, userRelationshipStatus, lastUpdatedTime, followerRelationshipLookupEntity); await this.userRelationshipsStore.UpdateFollowingRelationship( StorageConsistencyMode.Strong, relationshipHandle, followingKeyUserHandle, followerKeyUserHandle, appHandle, userRelationshipStatus, lastUpdatedTime, followingRelationshipLookupEntity); await this.relationshipsQueue.SendRelationshipMessage( relationshipOperation, relationshipHandle, followerKeyUserHandle, followingKeyUserHandle, appHandle, lastUpdatedTime); } else if (processType == ProcessType.Backend || processType == ProcessType.BackendRetry) { if (relationshipOperation == RelationshipOperation.FollowUser) { await this.notificationsManager.CreateNotification( processType, followerKeyUserHandle, appHandle, relationshipHandle, ActivityType.Following, followingKeyUserHandle, followerKeyUserHandle, ContentType.Unknown, null, lastUpdatedTime); await this.fanoutActivitiesQueue.SendFanoutActivityMessage( followingKeyUserHandle, appHandle, relationshipHandle, ActivityType.Following, followingKeyUserHandle, followerKeyUserHandle, ContentType.Unknown, null, lastUpdatedTime); await this.followingImportsQueue.SendFollowingImportMessage( followingKeyUserHandle, appHandle, followerKeyUserHandle); } else if (relationshipOperation == RelationshipOperation.PendingUser) { await this.notificationsManager.CreateNotification( processType, followerKeyUserHandle, appHandle, relationshipHandle, ActivityType.FollowRequest, followingKeyUserHandle, followerKeyUserHandle, ContentType.Unknown, null, lastUpdatedTime); } else if (relationshipOperation == RelationshipOperation.AcceptUser) { await this.notificationsManager.CreateNotification( processType, followingKeyUserHandle, appHandle, relationshipHandle, ActivityType.FollowAccept, followerKeyUserHandle, followingKeyUserHandle, ContentType.Unknown, null, lastUpdatedTime); await this.followingImportsQueue.SendFollowingImportMessage( followingKeyUserHandle, appHandle, followerKeyUserHandle); } // Update popular user feed when follower count changes if (relationshipOperation == RelationshipOperation.FollowUser || relationshipOperation == RelationshipOperation.UnfollowUser || relationshipOperation == RelationshipOperation.DeleteFollower || relationshipOperation == RelationshipOperation.BlockUser || relationshipOperation == RelationshipOperation.AcceptUser) { long?followersCount = await this.userRelationshipsStore.QueryFollowersCount(followerKeyUserHandle, appHandle); long followersCountValue = followersCount.HasValue ? followersCount.Value : 0; if (followersCountValue % PopularUsersUpdateFollowersCount == 0) { await this.popularUsersManager.UpdatePopularUser(processType, followerKeyUserHandle, appHandle, followersCountValue); } } } }