-
-
Notifications
You must be signed in to change notification settings - Fork 147
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Regarding AttachDocument()
's performance with Housekeeping and Garbage Collection
#444
Comments
Great analysis. Based on the analysis, I have a few ideas for improvement:
|
Thank you for sharing your ideas! Solution 1: Setting Solution 2 and 3 will definitely clear out the root cause of this problem as current react-tldraw example's workloads are almost coming from shape movement(coordinate change). About solution 4... I have little knowledge about RHTPQMap and RHT... so I have to study about this. I will keep updating this issue if I have some progress on these solutions. |
I have implemented some come for Solution 1: Setting I have tested it, and it seems to work fine. |
Close issue as PR: Add ClientDeactivateThreshold in Project merged. |
After introducing In |
Description:
There is a
AttachDocument()
API performance issue on current react-tldraw example.Attaching document is taking almost 14 seconds to complete, and this is severally harming Yorkie's user experience.
I have investigated this issue and I think I have found the root cause of this problem.
I will explain why this is happening, and then mention some suggestions to solve this issue.
Why:
There were two main causes of this problem:
housekeeping-deactivate-threshold
detachDocument()
ordeactivateClient()
for several reasonsI will explain those two causes with react-tldraw example mentioned above.
It's a long story, so you can scroll down and just see final timeline for this incident.
in my react-tldraw example, I called two functions
client.detach()
andclient.deactivate()
inhandleDisconnect()
on window close to successfully close Yorkie connections.However
handleDisconnect()
function was not invoked on window close. SodetachDocument()
ordeactivateClient()
were failed. I will call this failed client, adead
client.But still this incident was in control because Yorkie server's Housekeeping service will deactivate clients that have not been used for a long time.
But, current Yorkie server's default configuration value of deactivate threshold
DefaultHousekeepingDeactivateThreshold
was7 * 24 * time.Hour
=7 days
(I assume that current Yorkie server on Yorkie SaaS is running on this value).Therefore, housekeeping(deactivation) of client on react-tldraw did not happen. This made Yorkie server to keep storing
dead
client'ssyncedseqs
becauseupdateSyncedSeq()
was not performed.After that, in every
PushPull()
,minSyncedTicket
inUpdateAndFindMinSyncedTicket()
was not updated because of thisdead
client'ssyncedseqs
, which will always be the smallest value. To keep in mind,syncedseqs
is used to perform Garbage Collection on document. For more information, check https://yorkie.dev/docs/internals#garbage-collection.Therefore, GC was not performed even several
changes
were made in the document becauseminSyncedTicket
was always the same.This made
document
/snapshot
get bigger and bigger as more changes are made in the document.So, response snapshot of
AttachDocument()
got huge (in react-tldraw exmaple's case,10.9MB
), and this delayed network transfer but also slowed down browser's resource loading (in react-tldraw exmaple's case,2.05 s
network transfer +7.12 s
resource loading). This situation is especially common in whiteboard because tons of changes(shape change, coordinate move, etc) are made in collaborative whiteboard.To conclude:
detachDocument()
anddeactivateDocument()
were not performed on tldraw close.DefaultHousekeepingDeactivateThreshold
was 7 days, so housekeeping(deactivation) on dead client was not performed.syncedseqs
of dead client was preserved becauseupdateSyncedSeq()
was not performed.minSyncedTicket
inUpdateAndFindMinSyncedTicket()
were not changed.AttachDocument()
got huge.Suggestions:
Deactivating(Housekeeping) dead client is very crucial because just one dead client will block
minSyncedTicket
's update, and the whole document will grow due to GC failure. And this will effect other peer's attach performance.I think there are several ways to solve this problem.
navigator.sendBaecon(deactivate)
in web browser.But eventually, server is responsible for this, because client can be unexpectedly terminated due to several reasons (web browser force close, or device crash/blue screen).
I noticed that server can detect
WatchDocuments()
stream close on client's dead state. Maybe we can perform some actions whenWatchDocuments()
stream is closed. I will keep looking for the solution to solve this problem.P.S:
attachDocument()
performance issue onyorkie-js-sdk
: Performance issue when attaching doc yorkie-js-sdk#395, so after we fix this issue, I should look for this issue too.The text was updated successfully, but these errors were encountered: