Skip to content

Commit

Permalink
enh: reply to yjs sync step 1 as the server
Browse files Browse the repository at this point in the history
The yjs sync protocol has three types of messages:
* Sync step 1 (Question)
* Sync step 2 (Answer)
* Update

The different parties will exchange questions and answers to sync.
Once all parties are synced they exchange updates containing the latest changes.

We used to relay all questions to all parties
which resulted in a lot of unneccessary traffic and db entries.

Instead only store the answers and updates on the server.
Whenever any question comes in reply with the log of all the other messages.
This way questions are only answered once (by the server)
and we can still stick to a "stupid" server
that does not need to understand state vectors and so on.

Signed-off-by: Max <max@nextcloud.com>
  • Loading branch information
max-nextcloud committed Dec 7, 2022
1 parent 1026c37 commit 5f30093
Show file tree
Hide file tree
Showing 2 changed files with 34 additions and 4 deletions.
4 changes: 2 additions & 2 deletions lib/Service/ApiService.php
Original file line number Diff line number Diff line change
Expand Up @@ -177,11 +177,11 @@ public function push($documentId, $sessionId, $sessionToken, $version, $steps, $
$file = $this->documentService->getFileForSession($session, $token);
if (!$this->documentService->isReadOnly($file, $token)) {
try {
$steps = $this->documentService->addStep($documentId, $sessionId, $steps, $version);
$result = $this->documentService->addStep($documentId, $sessionId, $steps, $version);
} catch (InvalidArgumentException $e) {
return new DataResponse($e->getMessage(), 422);
}
return new DataResponse($steps);
return new DataResponse($result);
}
return new DataResponse([], 403);
}
Expand Down
34 changes: 32 additions & 2 deletions lib/Service/DocumentService.php
Original file line number Diff line number Diff line change
Expand Up @@ -183,9 +183,39 @@ public function get($documentId) {
* @throws InvalidArgumentException
*/
public function addStep($documentId, $sessionId, $steps, $version): array {
$stepsToInsert = [];
$querySteps = [];
$getStepsSinceVersion = null;
$newVersion = $version;
foreach ($steps as $step) {
if ($step > "AAE") {
array_push($stepsToInsert, $step);
} else {
array_push($querySteps, $step);
}
}
if (sizeof($stepsToInsert) > 0) {
$newVersion = $this->insertSteps($documentId, $sessionId, $stepsToInsert, $version);
}
$getStepsSinceVersion = sizeof($querySteps) > 0 ? 0 : $version;
return [
'steps' => $this->getSteps($documentId, $getStepsSinceVersion),
'version' => $newVersion
];
}

/**
* @param $documentId
* @param $sessionId
* @param $steps
* @param $version
* @return string
* @throws DoesNotExistException
* @throws InvalidArgumentException
*/
private function insertSteps($documentId, $sessionId, $steps, $version): string {
$document = null;
$stepsVersion = null;

try {
$document = $this->documentMapper->find($documentId);
$stepsJson = json_encode($steps);
Expand All @@ -202,7 +232,7 @@ public function addStep($documentId, $sessionId, $steps, $version): array {
$step->setVersion($newVersion);
$this->stepMapper->insert($step);
// TODO write steps to cache for quicker reading
return $steps;
return $newVersion;
} catch (DoesNotExistException $e) {
throw $e;
} catch (\Throwable $e) {
Expand Down

0 comments on commit 5f30093

Please sign in to comment.