Implement sync source-only mode in ServeSession and ChangeBatcher

- Added support for a new sync mode in ServeSession that filters property changes to only include the Source property when the server indicates it is in source-only mode.
- Updated ChangeBatcher to handle the new syncSourceOnly parameter, ensuring that only relevant property changes are processed based on the server's capabilities.
- Enhanced API response to include sync_source_only flag, indicating the server's sync capabilities.
- Adjusted related functions to accommodate the new sync logic, improving data synchronization efficiency.
This commit is contained in:
Joe 2026-01-24 05:24:08 -06:00
parent 8650cdbd82
commit b30aa8280d
6 changed files with 52 additions and 8 deletions

View file

@ -106,13 +106,17 @@ function App:init()
-- Our notif is now out of date- redoing will not restore the patch
-- since we've undone even further. Dismiss the notif.
cleanup()
dismissNotif()
if dismissNotif then
dismissNotif()
end
end)
redoConnection = ChangeHistoryService.OnRedo:Once(function(redoneAction: string)
if redoneAction == action then
-- The user has restored the patch, so we can dismiss the notif
cleanup()
dismissNotif()
if dismissNotif then
dismissNotif()
end
end
end)
end)

View file

@ -12,7 +12,7 @@ local PatchSet = require(script.Parent.Parent.PatchSet)
local encodePatchUpdate = require(script.Parent.encodePatchUpdate)
return function(instanceMap, propertyChanges)
return function(instanceMap, propertyChanges, syncSourceOnly)
local patch = PatchSet.newEmpty()
for instance, properties in propertyChanges do
@ -30,8 +30,20 @@ return function(instanceMap, propertyChanges)
Log.warn("Cannot sync non-nil Parent property changes yet")
end
else
local update = encodePatchUpdate(instance, instanceId, properties)
table.insert(patch.updated, update)
if syncSourceOnly then
-- Filter to only Source property when server is in source-only mode
if properties.Source then
local update = encodePatchUpdate(instance, instanceId, { Source = true })
if update then
table.insert(patch.updated, update)
end
end
else
local update = encodePatchUpdate(instance, instanceId, properties)
if update then
table.insert(patch.updated, update)
end
end
end
propertyChanges[instance] = nil

View file

@ -27,11 +27,16 @@ function ChangeBatcher.new(instanceMap, onChangesFlushed)
__instanceMap = instanceMap,
__onChangesFlushed = onChangesFlushed,
__pendingPropertyChanges = {},
__syncSourceOnly = false,
}, ChangeBatcher)
return self
end
function ChangeBatcher:setSyncSourceOnly(enabled)
self.__syncSourceOnly = enabled
end
function ChangeBatcher:stop()
self.__renderSteppedConnection:Disconnect()
self.__pendingPropertyChanges = {}
@ -69,7 +74,7 @@ function ChangeBatcher:__flush()
return nil
end
local patch = createPatchSet(self.__instanceMap, self.__pendingPropertyChanges)
local patch = createPatchSet(self.__instanceMap, self.__pendingPropertyChanges, self.__syncSourceOnly)
if PatchSet.isEmpty(patch) then
return nil

View file

@ -100,6 +100,7 @@ function ServeSession.new(options)
__status = Status.NotStarted,
__apiContext = options.apiContext,
__twoWaySync = options.twoWaySync,
__syncSourceOnly = false,
__reconciler = reconciler,
__instanceMap = instanceMap,
__changeBatcher = changeBatcher,
@ -196,6 +197,11 @@ function ServeSession:start()
:connect()
:andThen(function(serverInfo)
self:setLoadingText("Loading initial data from server...")
-- Configure sync mode based on server capabilities
self.__syncSourceOnly = serverInfo.syncSourceOnly or false
self.__changeBatcher:setSyncSourceOnly(self.__syncSourceOnly)
return self:__initialSync(serverInfo):andThen(function()
self:setLoadingText("Starting sync loop...")
self:__setStatus(Status.Connected, serverInfo.projectName)
@ -526,8 +532,20 @@ function ServeSession:__initialSync(serverInfo)
continue
end
local update = encodePatchUpdate(instance, change.id, change.changedProperties)
table.insert(inversePatch.updated, update)
local propertiesToSync = change.changedProperties
if self.__syncSourceOnly then
-- Filter to only Source property when server is in source-only mode
if propertiesToSync.Source then
propertiesToSync = { Source = propertiesToSync.Source }
else
continue
end
end
local update = encodePatchUpdate(instance, change.id, propertiesToSync)
if update then
table.insert(inversePatch.updated, update)
end
end
-- Add the removed instances back to Rojo
-- selene:allow(empty_if, unused_variable, empty_loop)

View file

@ -95,6 +95,7 @@ impl ApiService {
place_id: self.serve_session.place_id(),
game_id: self.serve_session.game_id(),
root_instance_id,
sync_source_only: true,
})
}

View file

@ -165,6 +165,10 @@ pub struct ServerInfoResponse {
pub game_id: Option<u64>,
pub place_id: Option<u64>,
pub root_instance_id: Ref,
/// When true, the server only supports syncing script Source property changes.
/// Other property changes will be ignored.
#[serde(default)]
pub sync_source_only: bool,
}
/// Response body from /api/read/{id}