mirror of
https://github.com/rojo-rbx/rojo.git
synced 2026-04-20 20:55:50 +00:00
Fix disconnected session activity (#675)
When a session is disconnected, the apiContext long-polling for messages continues until resolved/rejected. This means that even after a session is disconnected, a message can be received and handled. This leads to bad behavior, as the session was already cleaned up and the message cannot be handled correctly. The instance map was cleaned up upon disconnect, so it will warn about unapplied changes to unknown instances. (Like #512) It's very easy to repro: Connect a session, disconnect it, then save a change. https://github.com/rojo-rbx/rojo/assets/40185666/846a7269-7043-4727-9f9c-b3ac55a18a3a ----------- This PR fixes that neatly by tracking all active requests in a map, and cancelling their promises when we disconnect.
This commit is contained in:
@@ -93,6 +93,7 @@ function ApiContext.new(baseUrl)
|
||||
__sessionId = nil,
|
||||
__messageCursor = -1,
|
||||
__connected = true,
|
||||
__activeRequests = {},
|
||||
}
|
||||
|
||||
return setmetatable(self, ApiContext)
|
||||
@@ -113,6 +114,11 @@ end
|
||||
|
||||
function ApiContext:disconnect()
|
||||
self.__connected = false
|
||||
for request in self.__activeRequests do
|
||||
Log.trace("Cancelling request {}", request)
|
||||
request:cancel()
|
||||
end
|
||||
self.__activeRequests = {}
|
||||
end
|
||||
|
||||
function ApiContext:setMessageCursor(index)
|
||||
@@ -204,7 +210,7 @@ function ApiContext:retrieveMessages()
|
||||
local url = ("%s/api/subscribe/%s"):format(self.__baseUrl, self.__messageCursor)
|
||||
|
||||
local function sendRequest()
|
||||
return Http.get(url)
|
||||
local request = Http.get(url)
|
||||
:catch(function(err)
|
||||
if err.type == Http.Error.Kind.Timeout then
|
||||
if self.__connected then
|
||||
@@ -216,6 +222,15 @@ function ApiContext:retrieveMessages()
|
||||
|
||||
return Promise.reject(err)
|
||||
end)
|
||||
|
||||
Log.trace("Tracking request {}", request)
|
||||
self.__activeRequests[request] = true
|
||||
|
||||
return request:finally(function(...)
|
||||
Log.trace("Cleaning up request {}", request)
|
||||
self.__activeRequests[request] = nil
|
||||
return ...
|
||||
end)
|
||||
end
|
||||
|
||||
return sendRequest()
|
||||
|
||||
@@ -285,6 +285,8 @@ end
|
||||
function ServeSession:__mainSyncLoop()
|
||||
return self.__apiContext:retrieveMessages()
|
||||
:andThen(function(messages)
|
||||
Log.trace("Serve session {} retrieved {} messages", tostring(self), #messages)
|
||||
|
||||
for _, message in ipairs(messages) do
|
||||
local unappliedPatch = self.__reconciler:applyPatch(message)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user