Skip to content

Commit

Permalink
892057: Updated helper class property names
Browse files Browse the repository at this point in the history
  • Loading branch information
mugunthan-anbalagan committed Jul 31, 2024
1 parent b505379 commit 3d56484
Show file tree
Hide file tree
Showing 4 changed files with 43 additions and 41 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ public class CollaborativeEditingController : ControllerBase
private static IConnectionMultiplexer _redisConnection;
private readonly IWebHostEnvironment _hostingEnvironment;
private readonly IHubContext<DocumentEditorHub> _hubContext;

// Constructor for the CollaborativeEditingController
public CollaborativeEditingController(IWebHostEnvironment hostingEnvironment,
IHubContext<DocumentEditorHub> hubContext,
Expand All @@ -45,7 +45,7 @@ public async Task<string> ImportFile([FromBody] WebApplication1.Model.FileInfo p
// Create a new instance of DocumentContent to hold the document data
DocumentContent content = new DocumentContent();
// Retrieve the source document to be edited
// In this case, document is retrieved from the Getting Started.docx file in the wwwroot folder
// In this case, 'Giant Panda.docx' file from the wwwroot folder is opened.
// We can modify the code to retrieve the document from a different location or source.
Syncfusion.EJ2.DocumentEditor.WordDocument document = GetSourceDocument();
// Get the list of pending operations for the document
Expand Down Expand Up @@ -75,7 +75,7 @@ public async Task<string> ImportFile([FromBody] WebApplication1.Model.FileInfo p
[EnableCors("AllowAllOrigins")]
public async Task<ActionInfo> UpdateAction(ActionInfo param)
{
ActionInfo modifiedAction = await AddOperationsToTable(param);
ActionInfo modifiedAction = await AddOperationsToCache(param);
await _hubContext.Clients.Group(param.RoomName).SendAsync("dataReceived", "action", modifiedAction);
return modifiedAction;
}
Expand All @@ -89,16 +89,16 @@ public async Task<string> GetActionsFromServer(ActionInfo param)
try
{
// Initialize necessary variables from the parameters and helper class
int saveThreshold = CollaborativeEditingHelper.SaveThreshold;
string tableName = param.RoomName;
int saveThreshold = CollaborativeEditingHelper.MaxOperationQueueLimit;
string roomName = param.RoomName;
int lastSyncedVersion = param.Version;
int clientVersion = param.Version;

// Retrieve the database connection
IDatabase database = _redisConnection.GetDatabase();

// Fetch actions that are effective and pending based on the last synced version
List<ActionInfo> actions = await GetEffectivePendingVersion(tableName, lastSyncedVersion, database);
List<ActionInfo> actions = await GetEffectivePendingVersion(roomName, lastSyncedVersion, database);

// Increment the version for each action sequentially
actions.ForEach(action => action.Version = ++clientVersion);
Expand All @@ -120,16 +120,16 @@ public async Task<string> GetActionsFromServer(ActionInfo param)
}
}

private async Task<ActionInfo> AddOperationsToTable(ActionInfo action)
private async Task<ActionInfo> AddOperationsToCache(ActionInfo action)
{
int clientVersion = action.Version;

// Initialize the database connection
IDatabase database = _redisConnection.GetDatabase();
// Define the keys for Redis operations based on the action's room name
RedisKey[] keys = new RedisKey[] { action.RoomName + CollaborativeEditingHelper.VersionSuffix, action.RoomName, action.RoomName + CollaborativeEditingHelper.RevisionSuffix, action.RoomName + CollaborativeEditingHelper.ElementsToBeRemoved };
RedisKey[] keys = new RedisKey[] { action.RoomName + CollaborativeEditingHelper.VersionInfoSuffix, action.RoomName, action.RoomName + CollaborativeEditingHelper.RevisionInfoSuffix, action.RoomName + CollaborativeEditingHelper.ActionsToRemoveSuffix };
// Serialize the action and prepare values for the Redis script
RedisValue[] values = new RedisValue[] { JsonConvert.SerializeObject(action), clientVersion.ToString(), CollaborativeEditingHelper.SaveThreshold.ToString() };
RedisValue[] values = new RedisValue[] { JsonConvert.SerializeObject(action), clientVersion.ToString(), CollaborativeEditingHelper.MaxOperationQueueLimit.ToString() };
// Execute the Lua script in Redis and store the results
RedisResult[] results = (RedisResult[])await database.ScriptEvaluateAsync(CollaborativeEditingHelper.InsertScript, keys, values);

Expand Down Expand Up @@ -185,15 +185,15 @@ private async void UpdateRecordToCache(int version, ActionInfo action, IDatabase
RedisKey[] keys = new RedisKey[]
{
action.RoomName, // Key for the room's main data
action.RoomName + CollaborativeEditingHelper.RevisionSuffix // Key for the room's revision data
action.RoomName + CollaborativeEditingHelper.RevisionInfoSuffix // Key for the room's revision data
};

// Prepare Redis values for the script execution
RedisValue[] values = new RedisValue[]
{
JsonConvert.SerializeObject(action), // Serialize the action to store/update it in Redis
(version - 1).ToString(), // Decrement the version to get the previous version for comparison or update
CollaborativeEditingHelper.SaveThreshold.ToString() // Convert the save threshold to string for Redis
CollaborativeEditingHelper.MaxOperationQueueLimit.ToString() // Convert the save threshold to string for Redis
};

// Execute the Lua script with the prepared keys and values
Expand All @@ -211,14 +211,14 @@ private async Task<List<ActionInfo>> GetEffectivePendingVersion(string roomName,
RedisKey[] keys = new RedisKey[]
{
roomName, // Key for the room's actions
roomName + CollaborativeEditingHelper.RevisionSuffix // Key for the room's revision data
roomName + CollaborativeEditingHelper.RevisionInfoSuffix // Key for the room's revision data
};

// Prepare Redis values for the script: start index and save threshold
RedisValue[] values = new RedisValue[]
{
startIndex.ToString(), // Convert start index to string for Redis command
CollaborativeEditingHelper.SaveThreshold.ToString() // Convert save threshold to string for Redis command
CollaborativeEditingHelper.MaxOperationQueueLimit.ToString() // Convert save threshold to string for Redis command
};

// Execute the Lua script on Redis to fetch upcoming actions based on the provided keys and values
Expand All @@ -233,7 +233,7 @@ public async Task<List<ActionInfo>> GetPendingOperations(string listKey, long st
{
// Get the database connection from the Redis connection multiplexer
var db = _redisConnection.GetDatabase();
var result = (RedisResult[])await db.ScriptEvaluateAsync(CollaborativeEditingHelper.PendingOperations, new RedisKey[] { listKey, listKey + CollaborativeEditingHelper.ElementsToBeRemoved }, new RedisValue[] { startIndex, endIndex });
var result = (RedisResult[])await db.ScriptEvaluateAsync(CollaborativeEditingHelper.PendingOperations, new RedisKey[] { listKey, listKey + CollaborativeEditingHelper.ActionsToRemoveSuffix }, new RedisValue[] { startIndex, endIndex });
var processingValues = (RedisResult[])result[0];
var listValues = (RedisResult[])result[1];

Expand All @@ -251,7 +251,7 @@ public async Task<List<ActionInfo>> GetPendingOperations(string listKey, long st

internal static Syncfusion.EJ2.DocumentEditor.WordDocument GetSourceDocument()
{
string path = fileLocation + "\\Getting Started.docx";
string path = fileLocation + "\\Giant Panda.docx";
int index = path.LastIndexOf('.');
string type = index > -1 && index < path.Length - 1 ?
path.Substring(index) : ".docx";
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -47,15 +47,15 @@ public async Task JoinGroup(ActionInfo info)
await _db.HashSetAsync(info.RoomName + CollaborativeEditingHelper.UserInfoSuffix, Context.ConnectionId, JsonConvert.SerializeObject(info));

// Store the room name with the connection ID
await _db.HashSetAsync(CollaborativeEditingHelper.ConnectionIdToRoomMapping, Context.ConnectionId, info.RoomName);
await _db.HashSetAsync(CollaborativeEditingHelper.ConnectionIdRoomMappingKey, Context.ConnectionId, info.RoomName);

// Notify all the exsisiting users in the group about the new user
await Clients.GroupExcept(info.RoomName, Context.ConnectionId).SendAsync("dataReceived", "addUser", info);
}
public override async Task OnDisconnectedAsync(Exception? e)
{
//Get the room name associated with the connection ID
string roomName = await _db.HashGetAsync(CollaborativeEditingHelper.ConnectionIdToRoomMapping, Context.ConnectionId);
string roomName = await _db.HashGetAsync(CollaborativeEditingHelper.ConnectionIdRoomMappingKey, Context.ConnectionId);
// Remove user from Redis
await _db.HashDeleteAsync(roomName + CollaborativeEditingHelper.UserInfoSuffix, Context.ConnectionId);

Expand All @@ -65,27 +65,30 @@ public override async Task OnDisconnectedAsync(Exception? e)
var userList = allUsers.Select(u => JsonConvert.DeserializeObject<ActionInfo>(u.Value)).ToList();

// Remove connection to room name mapping
await _db.HashDeleteAsync(CollaborativeEditingHelper.ConnectionIdToRoomMapping, Context.ConnectionId);
await _db.HashDeleteAsync(CollaborativeEditingHelper.ConnectionIdRoomMappingKey, Context.ConnectionId);


if (userList.Count == 0)
{
// Auto save the document
// Auto save the pending operations to source document
RedisValue[] pendingOps = await _db.ListRangeAsync(roomName, 0, -1);
List<ActionInfo> actions = new List<ActionInfo>();
// Prepare the message fir adding it in background service queue.
foreach (var element in pendingOps)
if (pendingOps.Length > 0)
{
actions.Add(JsonConvert.DeserializeObject<ActionInfo>(element.ToString()));
List<ActionInfo> actions = new List<ActionInfo>();
// Prepare the message fir adding it in background service queue.
foreach (var element in pendingOps)
{
actions.Add(JsonConvert.DeserializeObject<ActionInfo>(element.ToString()));
}
var message = new SaveInfo
{
Action = actions,
PartialSave = false,
RoomName = roomName,
};
// Queue the message for background processing and save the operations to source document in background task
_ = saveTaskQueue.QueueBackgroundWorkItemAsync(message);
}
var message = new SaveInfo
{
Action = actions,
PartialSave = false,
RoomName = roomName,
};
// Queue the message for background processing and save the operations to source document in background task
_ = saveTaskQueue.QueueBackgroundWorkItemAsync(message);
}
else
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,22 +6,22 @@ public class CollaborativeEditingHelper
{
// Maximum number of operation we can queue in redis cache.
// If we reach this limit, we will save the operations to source document.
internal static int SaveThreshold = 100;
internal static int MaxOperationQueueLimit = 100;

// Suffix key to store revision information in redis cache.
internal static string RevisionSuffix = "_revision_info";
internal static string RevisionInfoSuffix = "_revision_info";

// Suffix key to store version information in redis cache.
internal static string VersionSuffix = "_version_info";
internal static string VersionInfoSuffix = "_version_info";

// Suffix key to store user information in redis cache.
internal static string UserInfoSuffix = "_user_info";

// Key to store room information with conncetion Id in redis cache.
internal static string ConnectionIdToRoomMapping = "ConnectionIdToRoomMapping";
internal static string ConnectionIdRoomMappingKey = "ej_de_connection_id_room_mapping";

// Suffix key to store removed actions information in redis cache.
internal static string ElementsToBeRemoved = "_elements_to_be_removed";
internal static string ActionsToRemoveSuffix = "_actions_to_remove";

internal static string InsertScript = @"
-- Define keys for version, list, and revision
Expand Down Expand Up @@ -104,8 +104,7 @@ public class CollaborativeEditingHelper
-- This effectively 'inserts' the item into the list at the position reflecting the client's view of the list
redis.call('LSET', listKey, clientVersion, item)";


internal static string EffectivePendingOperations = @"
internal static string EffectivePendingOperations = @"
-- Define the keys for accessing the list and revision in Redis
local listKey = KEYS[1]
local revisionKey = KEYS[2]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -47,11 +47,11 @@ private async void ClearRecordsFromRedisCache(SaveInfo workItem)
if (!workItem.PartialSave)
{
await database.KeyDeleteAsync(workItem.RoomName);
await database.KeyDeleteAsync(workItem.RoomName + CollaborativeEditingHelper.RevisionSuffix);
await database.KeyDeleteAsync(workItem.RoomName + CollaborativeEditingHelper.VersionSuffix);
await database.KeyDeleteAsync(workItem.RoomName + CollaborativeEditingHelper.RevisionInfoSuffix);
await database.KeyDeleteAsync(workItem.RoomName + CollaborativeEditingHelper.VersionInfoSuffix);
}
//Clear operations from redis cache.
await database.KeyDeleteAsync(workItem.RoomName + CollaborativeEditingHelper.ElementsToBeRemoved);
await database.KeyDeleteAsync(workItem.RoomName + CollaborativeEditingHelper.ActionsToRemoveSuffix);
}

public void ApplyOperationsToSourceDocument(List<ActionInfo> actions)
Expand Down

0 comments on commit 3d56484

Please # to comment.