Skip to content
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

GC and versionVector handling in documents created after v0.5.6 #1081

Open
hackerwins opened this issue Nov 26, 2024 · 1 comment
Open

GC and versionVector handling in documents created after v0.5.6 #1081

hackerwins opened this issue Nov 26, 2024 · 1 comment
Assignees
Labels
bug 🐞 Something isn't working

Comments

@hackerwins
Copy link
Member

hackerwins commented Nov 26, 2024

What happened:

Starting from v0.5.6, there was a change where the browser is now able to deactivate the client during the beforeunload in CodePair, leading to GC being processed.

However, when testing documents created after v0.5.6, the following issues were observed:

  • Executing doc.getGarbageLen() on documents created after v0.5.6 appears to correctly remove garbage under normal conditions.
  • However, there are discrepancies in the sizes of doc.changeID.versionVector and doc.presences. Occasionally, versionVector does not decrease, while presences appear to be cleaned up correctly.

image

What you expected to happen:

The expectation is that GC should function correctly for both documents created after v0.5.6, ensuring that both doc.presences and versionVector maintain corresponding sizes.

How to reproduce it (as minimally and precisely as possible):

https://codepair.yorkie.dev/hackerwins/674522059b55661e04668721/share?token=c5uq0y

Anything else we need to know?:

Related to #723

Environment:

  • Operating system: All
  • Browser and version: All
  • Yorkie version (use yorkie version): v0.5.6
  • Yorkie JS SDK version: v0.5.6
@hackerwins hackerwins added the bug 🐞 Something isn't working label Nov 26, 2024
@hackerwins hackerwins moved this from Backlog to In progress in Yorkie Project Dec 2, 2024
hackerwins added a commit that referenced this issue Feb 11, 2025
This commit extends RWMutex interface for locker package.

The original plan was to implement RWMutex for maintaining consistency
in updateVersionVector during PushPull operations(#1081). However, this
change is currently on hold due to the following reasons:

1. A bug was discovered in Lamport removal logic: #1089
2. The removal logic has been deprecated since v0.5.7

This commit includes only the interface extension while the actual 
implementation will be addressed in a future update.

---------

Co-authored-by: Youngteac Hong <[email protected]>
@raararaara
Copy link
Contributor

This issue can also be reproduced in the CodeMirror example of yorkie-js-sdk.

Follow these steps to reproduce the issue:

  1. Run the Yorkie server with version v0.5.6:

    $ git checkout v0.5.6 && make build && ./bin/yorkie server
  2. Run the JS SDK CodeMirror example with version v0.5.6:

    $ git checkout v056-vv-presence-diff
    $ pnpm sdk dev
  3. Automate the reproduction using puppeteer-cluster:
    To reproduce the issue, you will need three clients: one to execute Detach, another to perform Write, and one more for observation.
    The issue occurs when the client performing Write triggers a change and the client executing Detach reads it while simultaneously executing the Detach action.

You can run the following test code to reproduce the issue (node test.mjs command):

import { Cluster } from "puppeteer-cluster";  

const DOCUMENT_URL = `http://localhost:4173`;  

(async () => {  
  const maxConcurrency = 2;  

  const cluster = await Cluster.launch({  
    concurrency: Cluster.CONCURRENCY_CONTEXT,  
    maxConcurrency,  
    puppeteerOptions: {  
      headless: true, // Set to true to hide the browser window  
      args: [`--window-size=${1680},${970}`],  
    },  
    timeout: 999999999,  
  });  

  let count = 0;  
  let readyCount = 0;  

  const waitForReadyCount = async (target) => {  
    while (readyCount < target) {  
      console.log(readyCount);  
      await new Promise((resolve) => setTimeout(resolve, 100));
    }  
  };  

  // Write  
  await cluster.task(async ({ page, data: url }) => {  
    try {  
      await page.goto(url);  

      const selector = ".CodeMirror-scroll";  

      await page.waitForSelector(selector);  
      readyCount++;  

      await waitForReadyCount(2);  
      console.log("readyCount", readyCount);  

      await new Promise((resolve) => setTimeout(resolve, 50));  

      count++;  
      if (count % 2 === 1) {  
        console.log("writer");  

        await page.click(selector);  
        await page.keyboard.press("Enter");  

        console.log("writer finish");  
      } else {  
        console.log("deactivator");  

        await page.addScriptTag({  
          content: `client.deactivate({keepalive:true});`,  
        });  

        console.log("deactivate finish");  
      }  

      await new Promise((resolve) => setTimeout(resolve, 50));  
    } catch (error) {  
      console.error(error);  
    }  
  });  

  const iter = 100;
  for (let i = 0; i < iter; i++) {  
    console.log("********* step: ", i);  
    for (let j = 0; j < maxConcurrency; j++) {  
      await cluster.queue(DOCUMENT_URL);  
    }  
    console.log("queued");  

    await cluster.idle();  
    readyCount = 0;  
    console.log("idle finish");  
  }  

  await cluster.close();  
  console.log("closed");  
})();
  1. Observing the Results
    In the debug console of the observation client, if the issue occurs, you can see the following log:
Image

The two lists in the output represent:

  1. The actor IDs of clients that exist in doc.presences but are not present in doc.changeID.versionVector.
  2. The actor IDs of clients that exist in doc.changeID.versionVector but are not present in doc.presences.

This may occur due to a temporary discrepancy. To determine whether it is persistent, observe if the target actor IDs continue to appear in subsequent logs.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug 🐞 Something isn't working
Projects
Status: In progress
Development

No branches or pull requests

2 participants