Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/nextcloud/text.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMax <max@nextcloud.com>2022-10-17 14:08:40 +0300
committerMax <max@nextcloud.com>2022-10-17 16:12:03 +0300
commit0b8e2600c57ce4be8e020c5ff25a0bea254cefcc (patch)
treeb18aa89a47e9ebaad8d10f5b8d1b0e2640e2379d
parent70e5a9586933bce6df8fe185e32b4611977afa2e (diff)
enh: reply to yjs sync step 1 as the serverexperiment/minimal-yjs
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>
-rw-r--r--lib/Service/ApiService.php4
-rw-r--r--lib/Service/DocumentService.php34
2 files changed, 34 insertions, 4 deletions
diff --git a/lib/Service/ApiService.php b/lib/Service/ApiService.php
index bf3177dd7..7fc94a025 100644
--- a/lib/Service/ApiService.php
+++ b/lib/Service/ApiService.php
@@ -177,11 +177,11 @@ class ApiService {
$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);
}
diff --git a/lib/Service/DocumentService.php b/lib/Service/DocumentService.php
index fc6d3ff09..d1816e28e 100644
--- a/lib/Service/DocumentService.php
+++ b/lib/Service/DocumentService.php
@@ -183,9 +183,39 @@ class DocumentService {
* @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);
@@ -202,7 +232,7 @@ class DocumentService {
$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) {