Two way sync V0 (#282)

* Unfinished two-way sync API

* In-memory two-way sync complete

* Move PatchSet application into ChangeProcessor thread, where it can be synchronous

* Stop InstanceMap's signals when a ServeSession terminates

* Apply patch in ChangeProcessor

* Feature flag

* Fix error in ChangeProcessor due to wrong drop order
This commit is contained in:
Lucien Greathouse
2019-12-20 14:24:28 -08:00
committed by GitHub
parent 26e2e81188
commit a398338c02
9 changed files with 156 additions and 20 deletions

View File

@@ -156,11 +156,22 @@ function ApiContext:read(ids)
end
function ApiContext:write(patch)
local url = ("%s/write"):format(self.__baseUrl)
local body = Http.jsonEncode({
local url = ("%s/api/write"):format(self.__baseUrl)
local body = {
sessionId = self.__sessionId,
patch = patch,
})
removed = patch.removed,
updated = patch.updated,
}
-- Only add the 'added' field if the table is non-empty, or else Roblox's
-- JSON implementation will turn the table into an array instead of an
-- object, causing API validation to fail.
if next(patch.added) ~= nil then
body.added = patch.added
end
body = Http.jsonEncode(body)
return Http.post(url, body)
:andThen(rejectFailedRequests)

View File

@@ -25,7 +25,7 @@ local VALUES = {
[Environment.Test] = true,
},
},
ExperimentalTwoWaySync = {
UnstableTwoWaySync = {
type = "BoolValue",
values = {
[Environment.User] = false,
@@ -141,7 +141,7 @@ function DevSettings:shouldTypecheck()
end
function DevSettings:twoWaySyncEnabled()
return getValue("ExperimentalTwoWaySync")
return getValue("UnstableTwoWaySync")
end
function _G.ROJO_DEV_CREATE()

View File

@@ -20,6 +20,16 @@ function InstanceMap.new(onInstanceChanged)
return setmetatable(self, InstanceMap)
end
--[[
Disconnect all connections and release all instance references.
]]
function InstanceMap:stop()
-- I think this is safe.
for instance in pairs(self.fromInstances) do
self:removeInstance(instance)
end
end
function InstanceMap:__fmtDebug(output)
output:writeLine("InstanceMap {{")
output:indent()
@@ -145,7 +155,9 @@ function InstanceMap:__disconnectSignals(instance)
local signals = self.instancesToSignal[instance]
if signals ~= nil then
-- In the general case, we avoid
-- In most cases, we only have a single signal, so we avoid keeping
-- around the extra table. ValueBase objects force us to use multiple
-- signals to emulate the Instance.Changed event, however.
if typeof(signals) == "table" then
for _, signal in ipairs(signals) do
signal:Disconnect()

View File

@@ -189,6 +189,7 @@ end
function ServeSession:__stopInternal(err)
self:__setStatus(Status.Disconnected, err)
self.__apiContext:disconnect()
self.__instanceMap:stop()
end
function ServeSession:__setStatus(status, detail)