From b0dcf515f0d435b7976745d2cf5607490806848d Mon Sep 17 00:00:00 2001 From: Lucien Greathouse Date: Mon, 14 Oct 2019 14:05:25 -0700 Subject: [PATCH] Refactor plugins, port message dropping bugfix from 0.5.1 --- plugin/src/ApiContext.lua | 8 ++-- plugin/src/ServeSession.lua | 89 +++++++++++++++++++------------------ 2 files changed, 51 insertions(+), 46 deletions(-) diff --git a/plugin/src/ApiContext.lua b/plugin/src/ApiContext.lua index 44259c1c..49757dac 100644 --- a/plugin/src/ApiContext.lua +++ b/plugin/src/ApiContext.lua @@ -92,6 +92,10 @@ function ApiContext:disconnect() self.__connected = false end +function ApiContext:setMessageCursor(index) + self.__messageCursor = index +end + function ApiContext:connect() local url = ("%s/api/rojo"):format(self.__baseUrl) @@ -125,8 +129,6 @@ function ApiContext:read(ids) assert(validateApiRead(body)) - self.__messageCursor = body.messageCursor - return body end) end @@ -155,7 +157,7 @@ function ApiContext:retrieveMessages() assert(validateApiSubscribe(body)) - self.__messageCursor = body.messageCursor + self:setMessageCursor(body.messageCursor) return body.messages end) diff --git a/plugin/src/ServeSession.lua b/plugin/src/ServeSession.lua index 6033dde4..1e1d95b3 100644 --- a/plugin/src/ServeSession.lua +++ b/plugin/src/ServeSession.lua @@ -12,7 +12,6 @@ local Status = strict("Session.Status", { local function DEBUG_printPatch(patch) local HttpService = game:GetService("HttpService") - for removed in ipairs(patch.removed) do print("Remove:", removed) end @@ -64,48 +63,9 @@ function ServeSession:start() local rootInstanceId = serverInfo.rootInstanceId - return self.__apiContext:read({ rootInstanceId }) - :andThen(function(readResponseBody) - local hydratePatch = self.__reconciler:hydrate( - readResponseBody.instances, - rootInstanceId, - game - ) - - -- TODO: Prompt user to notify them of this patch, since - -- it's effectively a conflict between the Rojo server and - -- the client. - - self.__reconciler:applyPatch(hydratePatch) - - -- TODO: Applying a patch may eventually only apply part of - -- the patch and start a content negotiation process with - -- the Rojo server. We should handle that! - - local function mainLoop() - return self.__apiContext:retrieveMessages() - :andThen(function(messages) - for _, message in ipairs(messages) do - -- TODO: Update server to return patches in - -- correct format so that we don't have to - -- transform them for the reconciler. - - local asPatch = { - removed = message.removedInstances, - updated = message.updatedInstances, - added = message.addedInstances, - } - - self.__reconciler:applyPatch(asPatch) - end - - if self.__status ~= Status.Disconnected then - return mainLoop() - end - end) - end - - return mainLoop() + return self:__initialSync(rootInstanceId) + :andThen(function() + return self:__mainSyncLoop() end) end) :catch(function(err) @@ -117,6 +77,49 @@ function ServeSession:stop() self:__stopInternal() end +function ServeSession:__initialSync(rootInstanceId) + return self.__apiContext:read({ rootInstanceId }) + :andThen(function(readResponseBody) + -- Tell the API Context that we're up-to-date with the version of + -- the tree defined in this response. + self.__apiContext:setMessageCursor(readResponseBody.messageCursor) + + -- Calculate the initial patch to apply to the DataModel to catch us + -- up to what Rojo thinks the place should look like. + local hydratePatch = self.__reconciler:hydrate( + readResponseBody.instances, + rootInstanceId, + game + ) + + -- TODO: Prompt user to notify them of this patch, since it's + -- effectively a conflict between the Rojo server and the client. + + self.__reconciler:applyPatch(hydratePatch) + end) +end + +function ServeSession:__mainSyncLoop() + return self.__apiContext:retrieveMessages() + :andThen(function(messages) + for _, message in ipairs(messages) do + -- TODO: Update server to return patches in correct format so + -- that we don't have to transform them for the reconciler. + local asPatch = { + removed = message.removedInstances, + updated = message.updatedInstances, + added = message.addedInstances, + } + + self.__reconciler:applyPatch(asPatch) + end + + if self.__status ~= Status.Disconnected then + return self:__mainSyncLoop() + end + end) +end + function ServeSession:__stopInternal(err) self:__setStatus(Status.Disconnected, err) self.__apiContext:disconnect()