Compare commits

..

1 Commits

Author SHA1 Message Date
dependabot[bot] 5c100e7bca chore(deps): bump docker/build-push-action from 4 to 5
Bumps [docker/build-push-action](https://github.com/docker/build-push-action) from 4 to 5.
- [Release notes](https://github.com/docker/build-push-action/releases)
- [Commits](https://github.com/docker/build-push-action/compare/v4...v5)

---
updated-dependencies:
- dependency-name: docker/build-push-action
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-09-18 12:19:19 +00:00
45 changed files with 159 additions and 410 deletions
-1
View File
@@ -16,7 +16,6 @@ jobs:
uses: standardnotes/server/.github/workflows/common-server-application.yml@main
with:
service_name: analytics
workspace_name: "@standardnotes/analytics"
deploy_web: false
package_path: packages/analytics
secrets: inherit
-1
View File
@@ -16,7 +16,6 @@ jobs:
uses: standardnotes/server/.github/workflows/common-server-application.yml@main
with:
service_name: api-gateway
workspace_name: "@standardnotes/api-gateway"
deploy_worker: false
package_path: packages/api-gateway
secrets: inherit
-1
View File
@@ -16,7 +16,6 @@ jobs:
uses: standardnotes/server/.github/workflows/common-server-application.yml@main
with:
service_name: auth
workspace_name: "@standardnotes/auth-server"
package_path: packages/auth
secrets: inherit
+1 -16
View File
@@ -9,9 +9,6 @@ on:
package_path:
required: true
type: string
workspace_name:
required: true
type: string
secrets:
DOCKER_USERNAME:
required: true
@@ -33,14 +30,6 @@ jobs:
with:
python-version: '3.11'
- name: Cache build
id: cache-build
uses: actions/cache@v3
with:
path: |
packages/**/dist
key: ${{ runner.os }}-${{ inputs.service_name }}-build-${{ github.sha }}
- name: Set up Node
uses: actions/setup-node@v3
with:
@@ -50,10 +39,6 @@ jobs:
- name: Install dependencies
run: yarn install --immutable
- name: Build
if: steps.cache-build.outputs.cache-hit != 'true'
run: yarn build
- name: Login to Docker Hub
uses: docker/login-action@v2
with:
@@ -81,7 +66,7 @@ jobs:
uses: docker/setup-buildx-action@master
- name: Publish Docker image
uses: docker/build-push-action@v4
uses: docker/build-push-action@v5
with:
builder: ${{ steps.buildx.outputs.name }}
context: .
+1 -1
View File
@@ -35,7 +35,7 @@ jobs:
uses: docker/setup-buildx-action@master
- name: Publish Docker image
uses: docker/build-push-action@v4
uses: docker/build-push-action@v5
with:
builder: ${{ steps.buildx.outputs.name }}
context: .
@@ -6,9 +6,6 @@ on:
service_name:
required: true
type: string
workspace_name:
required: true
type: string
deploy_web:
required: false
default: true
@@ -39,7 +36,6 @@ jobs:
with:
service_name: ${{ inputs.service_name }}
package_path: ${{ inputs.package_path }}
workspace_name: ${{ inputs.workspace_name }}
secrets: inherit
deploy-web:
-1
View File
@@ -16,7 +16,6 @@ jobs:
uses: standardnotes/server/.github/workflows/common-server-application.yml@main
with:
service_name: files
workspace_name: "@standardnotes/files-server"
package_path: packages/files
secrets: inherit
-1
View File
@@ -16,7 +16,6 @@ jobs:
uses: standardnotes/server/.github/workflows/common-server-application.yml@main
with:
service_name: revisions
workspace_name: "@standardnotes/revisions-server"
package_path: packages/revisions
secrets: inherit
-1
View File
@@ -16,7 +16,6 @@ jobs:
uses: standardnotes/server/.github/workflows/common-server-application.yml@main
with:
service_name: scheduler
workspace_name: "@standardnotes/scheduler-server"
deploy_web: false
package_path: packages/scheduler
secrets: inherit
-1
View File
@@ -16,7 +16,6 @@ jobs:
uses: standardnotes/server/.github/workflows/common-server-application.yml@main
with:
service_name: syncing-server-js
workspace_name: "@standardnotes/syncing-server"
package_path: packages/syncing-server
secrets: inherit
-1
View File
@@ -16,7 +16,6 @@ jobs:
uses: standardnotes/server/.github/workflows/common-server-application.yml@main
with:
service_name: websockets
workspace_name: "@standardnotes/websockets-server"
package_path: packages/websockets
secrets: inherit
-4
View File
@@ -3,10 +3,6 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
## [2.26.17](https://github.com/standardnotes/server/compare/@standardnotes/analytics@2.26.16...@standardnotes/analytics@2.26.17) (2023-09-19)
**Note:** Version bump only for package @standardnotes/analytics
## [2.26.16](https://github.com/standardnotes/server/compare/@standardnotes/analytics@2.26.15...@standardnotes/analytics@2.26.16) (2023-09-18)
**Note:** Version bump only for package @standardnotes/analytics
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "@standardnotes/analytics",
"version": "2.26.17",
"version": "2.26.16",
"engines": {
"node": ">=18.0.0 <21.0.0"
},
-4
View File
@@ -3,10 +3,6 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
## [1.74.15](https://github.com/standardnotes/api-gateway/compare/@standardnotes/api-gateway@1.74.14...@standardnotes/api-gateway@1.74.15) (2023-09-19)
**Note:** Version bump only for package @standardnotes/api-gateway
## [1.74.14](https://github.com/standardnotes/api-gateway/compare/@standardnotes/api-gateway@1.74.13...@standardnotes/api-gateway@1.74.14) (2023-09-18)
**Note:** Version bump only for package @standardnotes/api-gateway
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "@standardnotes/api-gateway",
"version": "1.74.15",
"version": "1.74.14",
"engines": {
"node": ">=18.0.0 <21.0.0"
},
-16
View File
@@ -3,22 +3,6 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
## [1.143.7](https://github.com/standardnotes/server/compare/@standardnotes/auth-server@1.143.6...@standardnotes/auth-server@1.143.7) (2023-09-19)
**Note:** Version bump only for package @standardnotes/auth-server
## [1.143.6](https://github.com/standardnotes/server/compare/@standardnotes/auth-server@1.143.4...@standardnotes/auth-server@1.143.6) (2023-09-19)
### Bug Fixes
* **auth:** bump version ([b91cd7e](https://github.com/standardnotes/server/commit/b91cd7e2329d68026665f61d9bd17ba918c57563))
## [1.143.4](https://github.com/standardnotes/server/compare/@standardnotes/auth-server@1.143.3...@standardnotes/auth-server@1.143.4) (2023-09-19)
### Bug Fixes
* **auth:** add debug logs to transition ([bf855bb](https://github.com/standardnotes/server/commit/bf855bb26e8a3618113bd2f5801c260782566815))
## [1.143.3](https://github.com/standardnotes/server/compare/@standardnotes/auth-server@1.143.2...@standardnotes/auth-server@1.143.3) (2023-09-18)
**Note:** Version bump only for package @standardnotes/auth-server
-10
View File
@@ -53,10 +53,7 @@ const requestTransition = async (
continue
}
let wasTransitionRequested = false
if (itemsTransitionStatus?.value !== TransitionStatus.STATUSES.Verified) {
wasTransitionRequested = true
await transitionStatusRepository.remove(user.uuid, 'items')
await domainEventPublisher.publish(
@@ -69,7 +66,6 @@ const requestTransition = async (
}
if (revisionsTransitionStatus?.value !== TransitionStatus.STATUSES.Verified) {
wasTransitionRequested = true
await transitionStatusRepository.remove(user.uuid, 'revisions')
await domainEventPublisher.publish(
@@ -82,12 +78,6 @@ const requestTransition = async (
}
usersTriggered += 1
if (wasTransitionRequested) {
logger.info(
`[TRANSITION ${timestamp}] Transition requested for user ${user.uuid} - items status: ${itemsTransitionStatus?.value}, revisions status: ${revisionsTransitionStatus?.value}, has transition role: ${userHasTransitionRole}`,
)
}
}
logger.info(
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "@standardnotes/auth-server",
"version": "1.143.7",
"version": "1.143.3",
"engines": {
"node": ">=18.0.0 <21.0.0"
},
-6
View File
@@ -3,12 +3,6 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
## [1.30.1](https://github.com/standardnotes/server/compare/@standardnotes/domain-core@1.30.0...@standardnotes/domain-core@1.30.1) (2023-09-19)
### Bug Fixes
* **domain-core:** allow any version and variant of the UUID format ([de081fe](https://github.com/standardnotes/server/commit/de081fe78658bdd36c8c5d86b70a16a2880aa3d1))
# [1.30.0](https://github.com/standardnotes/server/compare/@standardnotes/domain-core@1.29.0...@standardnotes/domain-core@1.30.0) (2023-09-18)
### Features
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "@standardnotes/domain-core",
"version": "1.30.1",
"version": "1.30.0",
"engines": {
"node": ">=18.0.0 <21.0.0"
},
@@ -5,7 +5,6 @@ describe('Validator', () => {
'2221101c-1da9-4d2b-9b32-b8be2a8d1c82',
'c08f2f29-a74b-42b4-aefd-98af9832391c',
'b453fa64-1493-443b-b5bb-bca7b9c696c7',
'fa7350b3-77cf-8c0c-40b2-6046b13254fe',
]
const invalidUuids = [
@@ -1,13 +1,12 @@
import { Result } from './Result'
export class Validator {
private static readonly UUID_ANY_VERSION_AND_VARIANT_REGEX =
/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i
private static readonly UUID_REGEX = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-5][0-9a-f]{3}-[089ab][0-9a-f]{3}-[0-9a-f]{12}$/i
private static readonly EMAIL_REGEX =
/^(([^<>()[\]\\.,;:\s@"]+(\.[^<>()[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/
static isValidUuid(value: string): Result<string> {
const matchesUuidRegex = String(value).toLowerCase().match(Validator.UUID_ANY_VERSION_AND_VARIANT_REGEX) !== null
const matchesUuidRegex = String(value).toLowerCase().match(Validator.UUID_REGEX) !== null
if (matchesUuidRegex) {
return Result.ok()
}
-4
View File
@@ -3,10 +3,6 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
## [1.11.45](https://github.com/standardnotes/server/compare/@standardnotes/event-store@1.11.44...@standardnotes/event-store@1.11.45) (2023-09-19)
**Note:** Version bump only for package @standardnotes/event-store
## [1.11.44](https://github.com/standardnotes/server/compare/@standardnotes/event-store@1.11.43...@standardnotes/event-store@1.11.44) (2023-09-18)
**Note:** Version bump only for package @standardnotes/event-store
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "@standardnotes/event-store",
"version": "1.11.45",
"version": "1.11.44",
"description": "Event Store Service",
"private": true,
"main": "dist/src/index.js",
-4
View File
@@ -3,10 +3,6 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
## [1.22.24](https://github.com/standardnotes/files/compare/@standardnotes/files-server@1.22.23...@standardnotes/files-server@1.22.24) (2023-09-19)
**Note:** Version bump only for package @standardnotes/files-server
## [1.22.23](https://github.com/standardnotes/files/compare/@standardnotes/files-server@1.22.22...@standardnotes/files-server@1.22.23) (2023-09-18)
**Note:** Version bump only for package @standardnotes/files-server
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "@standardnotes/files-server",
"version": "1.22.24",
"version": "1.22.23",
"engines": {
"node": ">=18.0.0 <21.0.0"
},
-28
View File
@@ -3,34 +3,6 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
## [1.15.68](https://github.com/standardnotes/server/compare/@standardnotes/home-server@1.15.67...@standardnotes/home-server@1.15.68) (2023-09-19)
**Note:** Version bump only for package @standardnotes/home-server
## [1.15.67](https://github.com/standardnotes/server/compare/@standardnotes/home-server@1.15.66...@standardnotes/home-server@1.15.67) (2023-09-19)
**Note:** Version bump only for package @standardnotes/home-server
## [1.15.66](https://github.com/standardnotes/server/compare/@standardnotes/home-server@1.15.65...@standardnotes/home-server@1.15.66) (2023-09-19)
**Note:** Version bump only for package @standardnotes/home-server
## [1.15.65](https://github.com/standardnotes/server/compare/@standardnotes/home-server@1.15.64...@standardnotes/home-server@1.15.65) (2023-09-19)
**Note:** Version bump only for package @standardnotes/home-server
## [1.15.64](https://github.com/standardnotes/server/compare/@standardnotes/home-server@1.15.63...@standardnotes/home-server@1.15.64) (2023-09-19)
**Note:** Version bump only for package @standardnotes/home-server
## [1.15.63](https://github.com/standardnotes/server/compare/@standardnotes/home-server@1.15.62...@standardnotes/home-server@1.15.63) (2023-09-19)
**Note:** Version bump only for package @standardnotes/home-server
## [1.15.62](https://github.com/standardnotes/server/compare/@standardnotes/home-server@1.15.61...@standardnotes/home-server@1.15.62) (2023-09-19)
**Note:** Version bump only for package @standardnotes/home-server
## [1.15.61](https://github.com/standardnotes/server/compare/@standardnotes/home-server@1.15.60...@standardnotes/home-server@1.15.61) (2023-09-18)
**Note:** Version bump only for package @standardnotes/home-server
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "@standardnotes/home-server",
"version": "1.15.68",
"version": "1.15.61",
"engines": {
"node": ">=18.0.0 <21.0.0"
},
-32
View File
@@ -3,38 +3,6 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
## [1.35.7](https://github.com/standardnotes/server/compare/@standardnotes/revisions-server@1.35.6...@standardnotes/revisions-server@1.35.7) (2023-09-19)
### Bug Fixes
* skip removing already existing content in secondary to pick up where the transition left of ([857c6af](https://github.com/standardnotes/server/commit/857c6af9468ec829ff4dce9a96ba7bf9c14d55a5))
## [1.35.6](https://github.com/standardnotes/server/compare/@standardnotes/revisions-server@1.35.5...@standardnotes/revisions-server@1.35.6) (2023-09-19)
### Bug Fixes
* increase timeout for secondary database to catch up for indexes to be rebuilt ([b265a39](https://github.com/standardnotes/server/commit/b265a39b635373c36ee8c3d8e09f0631159b3574))
* logs verbosity during transitions ([e589029](https://github.com/standardnotes/server/commit/e589029722ab9f4debc8aa6cc78913f877eda2e3))
## [1.35.5](https://github.com/standardnotes/server/compare/@standardnotes/revisions-server@1.35.4...@standardnotes/revisions-server@1.35.5) (2023-09-19)
### Bug Fixes
* add checking for secondary items logs ([a1a3e9f](https://github.com/standardnotes/server/commit/a1a3e9f586358b943b1b490a1382e42f081f7d06))
* logs for removing already existing content and paging through diff of the content ([a40b17b](https://github.com/standardnotes/server/commit/a40b17b141f1d5954e1a45b969d5a941386c68d0))
## [1.35.4](https://github.com/standardnotes/server/compare/@standardnotes/revisions-server@1.35.3...@standardnotes/revisions-server@1.35.4) (2023-09-19)
### Bug Fixes
* logs formatting during transition for better readability ([0ae028d](https://github.com/standardnotes/server/commit/0ae028db739decec8c50321b18b0af515e00bd23))
## [1.35.3](https://github.com/standardnotes/server/compare/@standardnotes/revisions-server@1.35.2...@standardnotes/revisions-server@1.35.3) (2023-09-19)
### Bug Fixes
* **syncing-server:** paging through already existing items ([e4fcd73](https://github.com/standardnotes/server/commit/e4fcd738c35a4dc96e57db6ca08383a5647d61ad))
## [1.35.2](https://github.com/standardnotes/server/compare/@standardnotes/revisions-server@1.35.1...@standardnotes/revisions-server@1.35.2) (2023-09-18)
**Note:** Version bump only for package @standardnotes/revisions-server
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "@standardnotes/revisions-server",
"version": "1.35.7",
"version": "1.35.2",
"engines": {
"node": ">=18.0.0 <21.0.0"
},
@@ -29,7 +29,7 @@ export class TransitionRequestedEventHandler implements DomainEventHandlerInterf
}
if (await this.isAlreadyMigrated(userUuid)) {
this.logger.info(`[${event.payload.userUuid}] User already migrated.`)
this.logger.info(`User ${event.payload.userUuid} already migrated.`)
await this.domainEventPublisher.publish(
this.domainEventFactory.createTransitionStatusUpdatedEvent({
@@ -43,7 +43,7 @@ export class TransitionRequestedEventHandler implements DomainEventHandlerInterf
return
}
this.logger.info(`[${event.payload.userUuid}] Handling transition requested event`)
this.logger.info(`Handling transition requested event for user ${event.payload.userUuid}`)
await this.domainEventPublisher.publish(
this.domainEventFactory.createTransitionStatusUpdatedEvent({
@@ -59,7 +59,7 @@ export class TransitionRequestedEventHandler implements DomainEventHandlerInterf
})
if (result.isFailed()) {
this.logger.error(`[${event.payload.userUuid}] Failed to transition: ${result.getError()}`)
this.logger.error(`Failed to transition for user ${event.payload.userUuid}`)
await this.domainEventPublisher.publish(
this.domainEventFactory.createTransitionStatusUpdatedEvent({
@@ -88,7 +88,7 @@ export class TransitionRequestedEventHandler implements DomainEventHandlerInterf
if (totalRevisionsCountForUserInPrimary > 0) {
this.logger.info(
`[${userUuid.value}] User has ${totalRevisionsCountForUserInPrimary} revisions in primary database.`,
`User ${userUuid.value} has ${totalRevisionsCountForUserInPrimary} revisions in primary database.`,
)
}
@@ -98,7 +98,9 @@ export class TransitionRequestedEventHandler implements DomainEventHandlerInterf
private async getUserUuidFromEvent(event: TransitionRequestedEvent): Promise<Uuid | null> {
const userUuidOrError = Uuid.create(event.payload.userUuid)
if (userUuidOrError.isFailed()) {
this.logger.error(`[${event.payload.userUuid}] Failed to transition revisions: ${userUuidOrError.getError()}`)
this.logger.error(
`Failed to transition revisions for user ${event.payload.userUuid}: ${userUuidOrError.getError()}`,
)
await this.domainEventPublisher.publish(
this.domainEventFactory.createTransitionStatusUpdatedEvent({
userUuid: event.payload.userUuid,
@@ -17,7 +17,7 @@ export class TransitionRevisionsFromPrimaryToSecondaryDatabaseForUser implements
) {}
async execute(dto: TransitionRevisionsFromPrimaryToSecondaryDatabaseForUserDTO): Promise<Result<void>> {
this.logger.info(`[${dto.userUuid}] Transitioning revisions for user`)
this.logger.info(`Transitioning revisions for user ${dto.userUuid}`)
if (this.secondRevisionsRepository === null) {
return Result.fail('Secondary revision repository is not set')
@@ -30,28 +30,31 @@ export class TransitionRevisionsFromPrimaryToSecondaryDatabaseForUser implements
const userUuid = userUuidOrError.getValue()
let newRevisionsInSecondaryCount = 0
let updatedRevisionsInSecondary: string[] = []
let alreadyIdenticalInSecondaryAndPrimary: string[] = []
let updatedRevisionsInSecondary: Revision[] = []
if (await this.hasAlreadyDataInSecondaryDatabase(userUuid)) {
const { alreadyExistingInSecondaryAndPrimary, newRevisionsInSecondary, updatedInSecondary } =
const { alreadyExistingInPrimary, newRevisionsInSecondary, updatedInSecondary } =
await this.getNewRevisionsCreatedInSecondaryDatabase(userUuid)
this.logger.info(
`[${dto.userUuid}] ${alreadyExistingInSecondaryAndPrimary.length} already existing identical revisions in primary and secondary.`,
)
alreadyIdenticalInSecondaryAndPrimary = alreadyExistingInSecondaryAndPrimary
for (const existingRevision of alreadyExistingInPrimary) {
this.logger.info(`Removing revision ${existingRevision.id.toString()} from secondary database`)
await (this.secondRevisionsRepository as RevisionRepositoryInterface).removeOneByUuid(
Uuid.create(existingRevision.id.toString()).getValue(),
userUuid,
)
}
if (newRevisionsInSecondary.length > 0) {
this.logger.info(
`[${dto.userUuid}] Found ${newRevisionsInSecondary.length} new revisions in secondary database`,
`Found ${newRevisionsInSecondary.length} new revisions in secondary database for user ${userUuid.value}`,
)
}
newRevisionsInSecondaryCount = newRevisionsInSecondary.length
if (updatedInSecondary.length > 0) {
this.logger.info(`[${dto.userUuid}] Found ${updatedInSecondary.length} updated revisions in secondary database`)
this.logger.info(
`Found ${updatedInSecondary.length} updated revisions in secondary database for user ${userUuid.value}`,
)
}
updatedRevisionsInSecondary = updatedInSecondary
@@ -63,19 +66,15 @@ export class TransitionRevisionsFromPrimaryToSecondaryDatabaseForUser implements
const migrationTimeStart = this.timer.getTimestampInMicroseconds()
this.logger.info(`[${dto.userUuid}] Migrating revisions`)
this.logger.debug(`Transitioning revisions for user ${userUuid.value}`)
const migrationResult = await this.migrateRevisionsForUser(
userUuid,
updatedRevisionsInSecondary,
alreadyIdenticalInSecondaryAndPrimary,
)
const migrationResult = await this.migrateRevisionsForUser(userUuid, updatedRevisionsInSecondary)
if (migrationResult.isFailed()) {
if (newRevisionsInSecondaryCount === 0 && updatedRevisionsInSecondaryCount === 0) {
const cleanupResult = await this.deleteRevisionsForUser(userUuid, this.secondRevisionsRepository)
if (cleanupResult.isFailed()) {
this.logger.error(
`[${dto.userUuid}] Failed to clean up secondary database revisions: ${cleanupResult.getError()}`,
`Failed to clean up secondary database revisions for user ${userUuid.value}: ${cleanupResult.getError()}`,
)
}
}
@@ -89,14 +88,13 @@ export class TransitionRevisionsFromPrimaryToSecondaryDatabaseForUser implements
userUuid,
newRevisionsInSecondaryCount,
updatedRevisionsInSecondary,
alreadyIdenticalInSecondaryAndPrimary,
)
if (integrityCheckResult.isFailed()) {
if (newRevisionsInSecondaryCount === 0 && updatedRevisionsInSecondaryCount === 0) {
const cleanupResult = await this.deleteRevisionsForUser(userUuid, this.secondRevisionsRepository)
if (cleanupResult.isFailed()) {
this.logger.error(
`[${dto.userUuid}] Failed to clean up secondary database revisions: ${cleanupResult.getError()}`,
`Failed to clean up secondary database revisions for user ${userUuid.value}: ${cleanupResult.getError()}`,
)
}
}
@@ -106,7 +104,9 @@ export class TransitionRevisionsFromPrimaryToSecondaryDatabaseForUser implements
const cleanupResult = await this.deleteRevisionsForUser(userUuid, this.primaryRevisionsRepository)
if (cleanupResult.isFailed()) {
this.logger.error(`[${dto.userUuid}] Failed to clean up primary database revisions: ${cleanupResult.getError()}`)
this.logger.error(
`Failed to clean up primary database revisions for user ${userUuid.value}: ${cleanupResult.getError()}`,
)
}
const migrationTimeEnd = this.timer.getTimestampInMicroseconds()
@@ -115,7 +115,7 @@ export class TransitionRevisionsFromPrimaryToSecondaryDatabaseForUser implements
const migrationDurationTimeStructure = this.timer.convertMicrosecondsToTimeStructure(migrationDuration)
this.logger.info(
`[${dto.userUuid}] Transitioned revisions in ${migrationDurationTimeStructure.hours}h ${migrationDurationTimeStructure.minutes}m ${migrationDurationTimeStructure.seconds}s ${migrationDurationTimeStructure.milliseconds}ms`,
`Transitioned revisions for user ${userUuid.value} in ${migrationDurationTimeStructure.hours}h ${migrationDurationTimeStructure.minutes}m ${migrationDurationTimeStructure.seconds}s ${migrationDurationTimeStructure.milliseconds}ms`,
)
return Result.ok()
@@ -123,11 +123,11 @@ export class TransitionRevisionsFromPrimaryToSecondaryDatabaseForUser implements
private async migrateRevisionsForUser(
userUuid: Uuid,
updatedRevisionsInSecondary: string[],
alreadyExistingInSecondaryAndPrimary: string[],
updatedRevisionsInSecondary: Revision[],
): Promise<Result<void>> {
try {
const totalRevisionsCountForUser = await this.primaryRevisionsRepository.countByUserUuid(userUuid)
let totalRevisionsCountTransitionedToSecondary = 0
const totalPages = Math.ceil(totalRevisionsCountForUser / this.pageSize)
for (let currentPage = 1; currentPage <= totalPages; currentPage++) {
const query = {
@@ -141,29 +141,28 @@ export class TransitionRevisionsFromPrimaryToSecondaryDatabaseForUser implements
for (const revision of revisions) {
try {
if (
updatedRevisionsInSecondary.find((updatedRevisionUuid) => updatedRevisionUuid === revision.id.toString())
updatedRevisionsInSecondary.find(
(updatedRevision) => updatedRevision.id.toString() === revision.id.toString(),
)
) {
this.logger.info(
`[${
userUuid.value
}] Skipping saving revision ${revision.id.toString()} as it was updated in secondary database`,
`Skipping saving revision ${revision.id.toString()} as it was updated in secondary database`,
)
continue
}
if (
alreadyExistingInSecondaryAndPrimary.find(
(alreadyExistingRevisionUuid) => alreadyExistingRevisionUuid === revision.id.toString(),
)
) {
continue
}
this.logger.debug(
`Transitioning revision #${
totalRevisionsCountTransitionedToSecondary + 1
}: ${revision.id.toString()} to secondary database`,
)
const didSave = await (this.secondRevisionsRepository as RevisionRepositoryInterface).insert(revision)
if (!didSave) {
return Result.fail(`Failed to save revision ${revision.id.toString()} to secondary database`)
}
totalRevisionsCountTransitionedToSecondary++
} catch (error) {
return Result.fail(
`Errored when saving revision ${revision.id.toString()} to secondary database: ${
@@ -174,6 +173,8 @@ export class TransitionRevisionsFromPrimaryToSecondaryDatabaseForUser implements
}
}
this.logger.debug(`Transitioned ${totalRevisionsCountTransitionedToSecondary} revisions to secondary database`)
return Result.ok()
} catch (error) {
return Result.fail(`Errored when migrating revisions for user ${userUuid.value}: ${(error as Error).message}`)
@@ -194,8 +195,8 @@ export class TransitionRevisionsFromPrimaryToSecondaryDatabaseForUser implements
}
private async allowForSecondaryDatabaseToCatchUp(): Promise<void> {
const tenSecondsInMillisecondsToRebuildIndexes = 10_000
await this.timer.sleep(tenSecondsInMillisecondsToRebuildIndexes)
const twoSecondsInMilliseconds = 2_000
await this.timer.sleep(twoSecondsInMilliseconds)
}
private async hasAlreadyDataInSecondaryDatabase(userUuid: Uuid): Promise<boolean> {
@@ -206,7 +207,7 @@ export class TransitionRevisionsFromPrimaryToSecondaryDatabaseForUser implements
const hasAlreadyDataInSecondaryDatabase = totalRevisionsCountForUserInSecondary > 0
if (hasAlreadyDataInSecondaryDatabase) {
this.logger.info(
`[${userUuid.value}] User has already ${totalRevisionsCountForUserInSecondary} revisions in secondary database`,
`User ${userUuid.value} has already ${totalRevisionsCountForUserInSecondary} revisions in secondary database`,
)
}
@@ -214,57 +215,45 @@ export class TransitionRevisionsFromPrimaryToSecondaryDatabaseForUser implements
}
private async getNewRevisionsCreatedInSecondaryDatabase(userUuid: Uuid): Promise<{
alreadyExistingInSecondaryAndPrimary: string[]
newRevisionsInSecondary: string[]
updatedInSecondary: string[]
alreadyExistingInPrimary: Revision[]
newRevisionsInSecondary: Revision[]
updatedInSecondary: Revision[]
}> {
this.logger.info(`[${userUuid.value}] Checking for new revisions created in secondary database`)
const revisions = await (this.secondRevisionsRepository as RevisionRepositoryInterface).findByUserUuid({
userUuid: userUuid,
})
const totalRevisionsCountForUser = await (
this.secondRevisionsRepository as RevisionRepositoryInterface
).countByUserUuid(userUuid)
const totalPages = Math.ceil(totalRevisionsCountForUser / this.pageSize)
const alreadyExistingInPrimary: Revision[] = []
const newRevisionsInSecondary: Revision[] = []
const updatedInSecondary: Revision[] = []
const alreadyExistingInSecondaryAndPrimary: string[] = []
const newRevisionsInSecondary: string[] = []
const updatedInSecondary: string[] = []
for (let currentPage = 1; currentPage <= totalPages; currentPage++) {
const query = {
userUuid: userUuid,
offset: (currentPage - 1) * this.pageSize,
limit: this.pageSize,
for (const revision of revisions) {
const { revisionInPrimary, newerRevisionInSecondary } =
await this.checkIfRevisionExistsInPrimaryDatabase(revision)
if (revisionInPrimary !== null) {
alreadyExistingInPrimary.push(revision)
continue
}
const revisions = await (this.secondRevisionsRepository as RevisionRepositoryInterface).findByUserUuid(query)
for (const revision of revisions) {
const { identicalRevisionInPrimary, newerRevisionInSecondary } =
await this.checkIfRevisionExistsInPrimaryDatabase(revision)
if (identicalRevisionInPrimary !== null) {
alreadyExistingInSecondaryAndPrimary.push(revision.id.toString())
continue
}
if (newerRevisionInSecondary !== null) {
updatedInSecondary.push(newerRevisionInSecondary.id.toString())
continue
}
if (identicalRevisionInPrimary === null && newerRevisionInSecondary === null) {
newRevisionsInSecondary.push(revision.id.toString())
continue
}
if (newerRevisionInSecondary !== null) {
updatedInSecondary.push(newerRevisionInSecondary)
continue
}
if (revisionInPrimary === null && newerRevisionInSecondary === null) {
newRevisionsInSecondary.push(revision)
continue
}
}
return {
alreadyExistingInSecondaryAndPrimary,
newRevisionsInSecondary,
updatedInSecondary,
alreadyExistingInPrimary: alreadyExistingInPrimary,
newRevisionsInSecondary: newRevisionsInSecondary,
updatedInSecondary: updatedInSecondary,
}
}
private async checkIfRevisionExistsInPrimaryDatabase(
revision: Revision,
): Promise<{ identicalRevisionInPrimary: Revision | null; newerRevisionInSecondary: Revision | null }> {
): Promise<{ revisionInPrimary: Revision | null; newerRevisionInSecondary: Revision | null }> {
const revisionInPrimary = await this.primaryRevisionsRepository.findOneByUuid(
Uuid.create(revision.id.toString()).getValue(),
revision.props.userUuid as Uuid,
@@ -273,28 +262,27 @@ export class TransitionRevisionsFromPrimaryToSecondaryDatabaseForUser implements
if (revisionInPrimary === null) {
return {
identicalRevisionInPrimary: null,
revisionInPrimary: null,
newerRevisionInSecondary: null,
}
}
if (!revision.isIdenticalTo(revisionInPrimary)) {
this.logger.error(
`[${revision.props.userUuid
?.value}] Revision ${revision.id.toString()} is not identical in primary and secondary database. Revision in secondary database: ${JSON.stringify(
`Revision ${revision.id.toString()} is not identical in primary and secondary database. Revision in secondary database: ${JSON.stringify(
revision,
)}, revision in primary database: ${JSON.stringify(revisionInPrimary)}`,
)
return {
identicalRevisionInPrimary: null,
revisionInPrimary: null,
newerRevisionInSecondary:
revision.props.dates.updatedAt > revisionInPrimary.props.dates.updatedAt ? revision : null,
}
}
return {
identicalRevisionInPrimary: revisionInPrimary,
revisionInPrimary: revisionInPrimary,
newerRevisionInSecondary: null,
}
}
@@ -302,8 +290,7 @@ export class TransitionRevisionsFromPrimaryToSecondaryDatabaseForUser implements
private async checkIntegrityBetweenPrimaryAndSecondaryDatabase(
userUuid: Uuid,
newRevisionsInSecondaryCount: number,
updatedRevisionsInSecondary: string[],
alreadyExistingInSecondaryAndPrimary: string[],
updatedRevisionsInSecondary: Revision[],
): Promise<Result<boolean>> {
try {
const totalRevisionsCountForUserInPrimary = await this.primaryRevisionsRepository.countByUserUuid(userUuid)
@@ -334,24 +321,16 @@ export class TransitionRevisionsFromPrimaryToSecondaryDatabaseForUser implements
}
if (
updatedRevisionsInSecondary.find((updatedRevisionUuid) => updatedRevisionUuid === revision.id.toString())
updatedRevisionsInSecondary.find(
(updatedRevision) => updatedRevision.id.toString() === revision.id.toString(),
)
) {
this.logger.info(
`[${
userUuid.value
}] Skipping integrity check for revision ${revision.id.toString()} as it was updated in secondary database`,
`Skipping integrity check for revision ${revision.id.toString()} as it was updated in secondary database`,
)
continue
}
if (
alreadyExistingInSecondaryAndPrimary.find(
(alreadyExistingRevisionUuid) => alreadyExistingRevisionUuid === revision.id.toString(),
)
) {
continue
}
if (!revision.isIdenticalTo(revisionInSecondary)) {
return Result.fail(
`Revision ${revision.id.toString()} is not identical in primary and secondary database. Revision in primary database: ${JSON.stringify(
-4
View File
@@ -3,10 +3,6 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
## [1.20.49](https://github.com/standardnotes/server/compare/@standardnotes/scheduler-server@1.20.48...@standardnotes/scheduler-server@1.20.49) (2023-09-19)
**Note:** Version bump only for package @standardnotes/scheduler-server
## [1.20.48](https://github.com/standardnotes/server/compare/@standardnotes/scheduler-server@1.20.47...@standardnotes/scheduler-server@1.20.48) (2023-09-18)
**Note:** Version bump only for package @standardnotes/scheduler-server
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "@standardnotes/scheduler-server",
"version": "1.20.49",
"version": "1.20.48",
"engines": {
"node": ">=18.0.0 <21.0.0"
},
-4
View File
@@ -3,10 +3,6 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
## [1.21.34](https://github.com/standardnotes/server/compare/@standardnotes/settings@1.21.33...@standardnotes/settings@1.21.34) (2023-09-19)
**Note:** Version bump only for package @standardnotes/settings
## [1.21.33](https://github.com/standardnotes/server/compare/@standardnotes/settings@1.21.32...@standardnotes/settings@1.21.33) (2023-09-18)
**Note:** Version bump only for package @standardnotes/settings
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "@standardnotes/settings",
"version": "1.21.34",
"version": "1.21.33",
"engines": {
"node": ">=18.0.0 <21.0.0"
},
-32
View File
@@ -3,38 +3,6 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
## [1.98.6](https://github.com/standardnotes/syncing-server-js/compare/@standardnotes/syncing-server@1.98.5...@standardnotes/syncing-server@1.98.6) (2023-09-19)
### Bug Fixes
* skip removing already existing content in secondary to pick up where the transition left of ([857c6af](https://github.com/standardnotes/syncing-server-js/commit/857c6af9468ec829ff4dce9a96ba7bf9c14d55a5))
## [1.98.5](https://github.com/standardnotes/syncing-server-js/compare/@standardnotes/syncing-server@1.98.4...@standardnotes/syncing-server@1.98.5) (2023-09-19)
### Bug Fixes
* increase timeout for secondary database to catch up for indexes to be rebuilt ([b265a39](https://github.com/standardnotes/syncing-server-js/commit/b265a39b635373c36ee8c3d8e09f0631159b3574))
* logs verbosity during transitions ([e589029](https://github.com/standardnotes/syncing-server-js/commit/e589029722ab9f4debc8aa6cc78913f877eda2e3))
## [1.98.4](https://github.com/standardnotes/syncing-server-js/compare/@standardnotes/syncing-server@1.98.3...@standardnotes/syncing-server@1.98.4) (2023-09-19)
### Bug Fixes
* add checking for secondary items logs ([a1a3e9f](https://github.com/standardnotes/syncing-server-js/commit/a1a3e9f586358b943b1b490a1382e42f081f7d06))
* logs for removing already existing content and paging through diff of the content ([a40b17b](https://github.com/standardnotes/syncing-server-js/commit/a40b17b141f1d5954e1a45b969d5a941386c68d0))
## [1.98.3](https://github.com/standardnotes/syncing-server-js/compare/@standardnotes/syncing-server@1.98.2...@standardnotes/syncing-server@1.98.3) (2023-09-19)
### Bug Fixes
* logs formatting during transition for better readability ([0ae028d](https://github.com/standardnotes/syncing-server-js/commit/0ae028db739decec8c50321b18b0af515e00bd23))
## [1.98.2](https://github.com/standardnotes/syncing-server-js/compare/@standardnotes/syncing-server@1.98.1...@standardnotes/syncing-server@1.98.2) (2023-09-19)
### Bug Fixes
* **syncing-server:** paging through already existing items ([e4fcd73](https://github.com/standardnotes/syncing-server-js/commit/e4fcd738c35a4dc96e57db6ca08383a5647d61ad))
## [1.98.1](https://github.com/standardnotes/syncing-server-js/compare/@standardnotes/syncing-server@1.98.0...@standardnotes/syncing-server@1.98.1) (2023-09-18)
**Note:** Version bump only for package @standardnotes/syncing-server
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "@standardnotes/syncing-server",
"version": "1.98.6",
"version": "1.98.1",
"engines": {
"node": ">=18.0.0 <21.0.0"
},
@@ -30,7 +30,7 @@ export class TransitionRequestedEventHandler implements DomainEventHandlerInterf
}
if (await this.isAlreadyMigrated(userUuid)) {
this.logger.info(`[${event.payload.userUuid}] User already migrated.`)
this.logger.info(`User ${event.payload.userUuid} already migrated.`)
await this.domainEventPublisher.publish(
this.domainEventFactory.createTransitionStatusUpdatedEvent({
@@ -44,7 +44,7 @@ export class TransitionRequestedEventHandler implements DomainEventHandlerInterf
return
}
this.logger.info(`[${event.payload.userUuid}] Handling transition requested event`)
this.logger.info(`Handling transition requested event for user ${event.payload.userUuid}`)
await this.domainEventPublisher.publish(
this.domainEventFactory.createTransitionStatusUpdatedEvent({
@@ -60,7 +60,7 @@ export class TransitionRequestedEventHandler implements DomainEventHandlerInterf
})
if (result.isFailed()) {
this.logger.error(`[${event.payload.userUuid}] Failed to trigger transition: ${result.getError()}`)
this.logger.error(`Failed to trigger transition for user ${event.payload.userUuid}`)
await this.domainEventPublisher.publish(
this.domainEventFactory.createTransitionStatusUpdatedEvent({
@@ -90,7 +90,7 @@ export class TransitionRequestedEventHandler implements DomainEventHandlerInterf
})
if (totalItemsCountForUserInPrimary > 0) {
this.logger.info(`[${userUuid.value}] User has ${totalItemsCountForUserInPrimary} items in primary database.`)
this.logger.info(`User ${userUuid.value} has ${totalItemsCountForUserInPrimary} items in primary database.`)
}
return totalItemsCountForUserInPrimary === 0
@@ -99,7 +99,7 @@ export class TransitionRequestedEventHandler implements DomainEventHandlerInterf
private async getUserUuidFromEvent(event: TransitionRequestedEvent): Promise<Uuid | null> {
const userUuidOrError = Uuid.create(event.payload.userUuid)
if (userUuidOrError.isFailed()) {
this.logger.error(`[${event.payload.userUuid}] Failed to transition items: ${userUuidOrError.getError()}`)
this.logger.error(`Failed to transition items for user ${event.payload.userUuid}: ${userUuidOrError.getError()}`)
await this.domainEventPublisher.publish(
this.domainEventFactory.createTransitionStatusUpdatedEvent({
@@ -15,7 +15,6 @@ export interface ItemRepositoryInterface {
findByUuidAndUserUuid(uuid: string, userUuid: string): Promise<Item | null>
findByUuid(uuid: Uuid): Promise<Item | null>
remove(item: Item): Promise<void>
removeByUuid(uuid: Uuid): Promise<void>
save(item: Item): Promise<void>
markItemsAsDeleted(itemUuids: Array<string>, updatedAtTimestamp: number): Promise<void>
updateContentSize(itemUuid: string, contentSize: number): Promise<void>
@@ -18,7 +18,7 @@ export class TransitionItemsFromPrimaryToSecondaryDatabaseForUser implements Use
) {}
async execute(dto: TransitionItemsFromPrimaryToSecondaryDatabaseForUserDTO): Promise<Result<void>> {
this.logger.info(`[${dto.userUuid}] Transitioning items`)
this.logger.info(`Transitioning items for user ${dto.userUuid}`)
if (this.secondaryItemRepository === null) {
return Result.fail('Secondary item repository is not set')
@@ -31,26 +31,28 @@ export class TransitionItemsFromPrimaryToSecondaryDatabaseForUser implements Use
const userUuid = userUuidOrError.getValue()
let newItemsInSecondaryCount = 0
let updatedItemsInSecondary: string[] = []
let alreadyIdenticalInSecondaryAndPrimary: string[] = []
let updatedItemsInSecondary: Item[] = []
if (await this.hasAlreadyDataInSecondaryDatabase(userUuid)) {
const { alreadyExistingInSecondaryAndPrimary, newItemsInSecondary, updatedInSecondary } =
const { alreadyExistingInPrimary, newItemsInSecondary, updatedInSecondary } =
await this.getNewItemsCreatedInSecondaryDatabase(userUuid)
this.logger.info(
`[${dto.userUuid}] ${alreadyExistingInSecondaryAndPrimary.length} already existing identical items in primary and secondary.`,
)
alreadyIdenticalInSecondaryAndPrimary = alreadyExistingInSecondaryAndPrimary
for (const existingItem of alreadyExistingInPrimary) {
this.logger.info(`Removing item ${existingItem.uuid.value} from secondary database`)
await (this.secondaryItemRepository as ItemRepositoryInterface).remove(existingItem)
}
if (newItemsInSecondary.length > 0) {
this.logger.info(`[${dto.userUuid}] Found ${newItemsInSecondary.length} new items in secondary database.`)
this.logger.info(
`Found ${newItemsInSecondary.length} new items in secondary database for user ${userUuid.value}`,
)
}
newItemsInSecondaryCount = newItemsInSecondary.length
if (updatedInSecondary.length > 0) {
this.logger.info(`[${dto.userUuid}] Found ${updatedInSecondary.length} updated items in secondary database.`)
this.logger.info(
`Found ${updatedInSecondary.length} updated items in secondary database for user ${userUuid.value}`,
)
}
updatedItemsInSecondary = updatedInSecondary
@@ -61,19 +63,13 @@ export class TransitionItemsFromPrimaryToSecondaryDatabaseForUser implements Use
const migrationTimeStart = this.timer.getTimestampInMicroseconds()
this.logger.info(`[${dto.userUuid}] Migrating items`)
const migrationResult = await this.migrateItemsForUser(
userUuid,
updatedItemsInSecondary,
alreadyIdenticalInSecondaryAndPrimary,
)
const migrationResult = await this.migrateItemsForUser(userUuid, updatedItemsInSecondary)
if (migrationResult.isFailed()) {
if (newItemsInSecondaryCount === 0 && updatedItemsInSecondaryCount === 0) {
const cleanupResult = await this.deleteItemsForUser(userUuid, this.secondaryItemRepository)
if (cleanupResult.isFailed()) {
this.logger.error(
`[${dto.userUuid}] Failed to clean up secondary database items: ${cleanupResult.getError()}`,
`Failed to clean up secondary database items for user ${userUuid.value}: ${cleanupResult.getError()}`,
)
}
}
@@ -87,14 +83,13 @@ export class TransitionItemsFromPrimaryToSecondaryDatabaseForUser implements Use
userUuid,
newItemsInSecondaryCount,
updatedItemsInSecondary,
alreadyIdenticalInSecondaryAndPrimary,
)
if (integrityCheckResult.isFailed()) {
if (newItemsInSecondaryCount === 0 && updatedItemsInSecondaryCount === 0) {
const cleanupResult = await this.deleteItemsForUser(userUuid, this.secondaryItemRepository)
if (cleanupResult.isFailed()) {
this.logger.error(
`[${dto.userUuid}] Failed to clean up secondary database items: ${cleanupResult.getError()}`,
`Failed to clean up secondary database items for user ${userUuid.value}: ${cleanupResult.getError()}`,
)
}
}
@@ -104,7 +99,9 @@ export class TransitionItemsFromPrimaryToSecondaryDatabaseForUser implements Use
const cleanupResult = await this.deleteItemsForUser(userUuid, this.primaryItemRepository)
if (cleanupResult.isFailed()) {
this.logger.error(`[${dto.userUuid}] Failed to clean up primary database items: ${cleanupResult.getError()}`)
this.logger.error(
`Failed to clean up primary database items for user ${userUuid.value}: ${cleanupResult.getError()}`,
)
}
const migrationTimeEnd = this.timer.getTimestampInMicroseconds()
@@ -113,7 +110,7 @@ export class TransitionItemsFromPrimaryToSecondaryDatabaseForUser implements Use
const migrationDurationTimeStructure = this.timer.convertMicrosecondsToTimeStructure(migrationDuration)
this.logger.info(
`[${dto.userUuid}] Transitioned items in ${migrationDurationTimeStructure.hours}h ${migrationDurationTimeStructure.minutes}m ${migrationDurationTimeStructure.seconds}s ${migrationDurationTimeStructure.milliseconds}ms`,
`Transitioned items for user ${userUuid.value} in ${migrationDurationTimeStructure.hours}h ${migrationDurationTimeStructure.minutes}m ${migrationDurationTimeStructure.seconds}s ${migrationDurationTimeStructure.milliseconds}ms`,
)
return Result.ok()
@@ -126,61 +123,48 @@ export class TransitionItemsFromPrimaryToSecondaryDatabaseForUser implements Use
const hasAlreadyDataInSecondaryDatabase = totalItemsCountForUser > 0
if (hasAlreadyDataInSecondaryDatabase) {
this.logger.info(`[${userUuid.value}] User has already ${totalItemsCountForUser} items in secondary database`)
this.logger.info(`User ${userUuid.value} has already ${totalItemsCountForUser} items in secondary database`)
}
return hasAlreadyDataInSecondaryDatabase
}
private async allowForSecondaryDatabaseToCatchUp(): Promise<void> {
const tenSecondsInMillisecondsToRebuildIndexes = 10_000
await this.timer.sleep(tenSecondsInMillisecondsToRebuildIndexes)
const twoSecondsInMilliseconds = 2_000
await this.timer.sleep(twoSecondsInMilliseconds)
}
private async getNewItemsCreatedInSecondaryDatabase(userUuid: Uuid): Promise<{
alreadyExistingInSecondaryAndPrimary: string[]
newItemsInSecondary: string[]
updatedInSecondary: string[]
alreadyExistingInPrimary: Item[]
newItemsInSecondary: Item[]
updatedInSecondary: Item[]
}> {
this.logger.info(`[${userUuid.value}] Checking for new items in secondary database`)
const alreadyExistingInSecondaryAndPrimary: string[] = []
const updatedInSecondary: string[] = []
const newItemsInSecondary: string[] = []
const totalItemsCountForUser = await (this.secondaryItemRepository as ItemRepositoryInterface).countAll({
const items = await (this.secondaryItemRepository as ItemRepositoryInterface).findAll({
userUuid: userUuid.value,
})
const totalPages = Math.ceil(totalItemsCountForUser / this.pageSize)
for (let currentPage = 1; currentPage <= totalPages; currentPage++) {
const query: ItemQuery = {
userUuid: userUuid.value,
offset: (currentPage - 1) * this.pageSize,
limit: this.pageSize,
sortOrder: 'ASC',
sortBy: 'uuid',
}
const items = await (this.secondaryItemRepository as ItemRepositoryInterface).findAll(query)
for (const item of items) {
const { identicalItemInPrimary, newerItemInSecondary } = await this.checkIfItemExistsInPrimaryDatabase(item)
if (identicalItemInPrimary !== null) {
alreadyExistingInSecondaryAndPrimary.push(item.id.toString())
continue
}
if (newerItemInSecondary !== null) {
updatedInSecondary.push(newerItemInSecondary.id.toString())
continue
}
if (identicalItemInPrimary === null && newerItemInSecondary === null) {
newItemsInSecondary.push(item.id.toString())
continue
}
const alreadyExistingInPrimary: Item[] = []
const updatedInSecondary: Item[] = []
const newItemsInSecondary: Item[] = []
for (const item of items) {
const { itemInPrimary, newerItemInSecondary } = await this.checkIfItemExistsInPrimaryDatabase(item)
if (itemInPrimary !== null) {
alreadyExistingInPrimary.push(item)
continue
}
if (newerItemInSecondary !== null) {
updatedInSecondary.push(newerItemInSecondary)
continue
}
if (itemInPrimary === null && newerItemInSecondary === null) {
newItemsInSecondary.push(item)
continue
}
}
return {
alreadyExistingInSecondaryAndPrimary,
alreadyExistingInPrimary,
newItemsInSecondary,
updatedInSecondary,
}
@@ -188,36 +172,30 @@ export class TransitionItemsFromPrimaryToSecondaryDatabaseForUser implements Use
private async checkIfItemExistsInPrimaryDatabase(
item: Item,
): Promise<{ identicalItemInPrimary: Item | null; newerItemInSecondary: Item | null }> {
): Promise<{ itemInPrimary: Item | null; newerItemInSecondary: Item | null }> {
const itemInPrimary = await this.primaryItemRepository.findByUuid(item.uuid)
if (itemInPrimary === null) {
return { identicalItemInPrimary: null, newerItemInSecondary: null }
return { itemInPrimary: null, newerItemInSecondary: null }
}
if (!item.isIdenticalTo(itemInPrimary)) {
this.logger.error(
`[${
item.props.userUuid.value
}] Item ${item.id.toString()} is not identical in primary and secondary database. Item in secondary database: ${JSON.stringify(
`Revision ${item.id.toString()} is not identical in primary and secondary database. Revision in secondary database: ${JSON.stringify(
item,
)}, item in primary database: ${JSON.stringify(itemInPrimary)}`,
)}, revision in primary database: ${JSON.stringify(itemInPrimary)}`,
)
return {
identicalItemInPrimary: null,
itemInPrimary: null,
newerItemInSecondary: item.props.timestamps.updatedAt > itemInPrimary.props.timestamps.updatedAt ? item : null,
}
}
return { identicalItemInPrimary: itemInPrimary, newerItemInSecondary: null }
return { itemInPrimary: itemInPrimary, newerItemInSecondary: null }
}
private async migrateItemsForUser(
userUuid: Uuid,
updatedItemsInSecondary: string[],
alreadyExistingInSecondaryAndPrimary: string[],
): Promise<Result<void>> {
private async migrateItemsForUser(userUuid: Uuid, updatedItemsInSecondary: Item[]): Promise<Result<void>> {
try {
const totalItemsCountForUser = await this.primaryItemRepository.countAll({ userUuid: userUuid.value })
const totalPages = Math.ceil(totalItemsCountForUser / this.pageSize)
@@ -226,24 +204,16 @@ export class TransitionItemsFromPrimaryToSecondaryDatabaseForUser implements Use
userUuid: userUuid.value,
offset: (currentPage - 1) * this.pageSize,
limit: this.pageSize,
sortBy: 'uuid',
sortOrder: 'ASC',
}
const items = await this.primaryItemRepository.findAll(query)
for (const item of items) {
if (updatedItemsInSecondary.find((updatedItemUuid) => item.uuid.value === updatedItemUuid)) {
this.logger.info(
`[${userUuid.value}] Skipping saving item ${item.uuid.value} as it was updated in secondary database`,
)
if (updatedItemsInSecondary.find((updatedItem) => updatedItem.uuid.equals(item.uuid))) {
this.logger.info(`Skipping saving item ${item.uuid.value} as it was updated in secondary database`)
continue
}
if (alreadyExistingInSecondaryAndPrimary.find((itemUuid) => item.uuid.value === itemUuid)) {
continue
}
await (this.secondaryItemRepository as ItemRepositoryInterface).save(item)
}
}
@@ -267,8 +237,7 @@ export class TransitionItemsFromPrimaryToSecondaryDatabaseForUser implements Use
private async checkIntegrityBetweenPrimaryAndSecondaryDatabase(
userUuid: Uuid,
newItemsInSecondaryCount: number,
updatedItemsInSecondary: string[],
alreadyExistingInSecondaryAndPrimary: string[],
updatedItemsInSecondary: Item[],
): Promise<Result<boolean>> {
try {
const totalItemsCountForUserInPrimary = await this.primaryItemRepository.countAll({ userUuid: userUuid.value })
@@ -290,8 +259,6 @@ export class TransitionItemsFromPrimaryToSecondaryDatabaseForUser implements Use
userUuid: userUuid.value,
offset: (currentPage - 1) * this.pageSize,
limit: this.pageSize,
sortBy: 'uuid',
sortOrder: 'ASC',
}
const items = await this.primaryItemRepository.findAll(query)
@@ -302,17 +269,13 @@ export class TransitionItemsFromPrimaryToSecondaryDatabaseForUser implements Use
return Result.fail(`Item ${item.uuid.value} not found in secondary database`)
}
if (updatedItemsInSecondary.find((updatedItemUuid) => item.uuid.value === updatedItemUuid)) {
if (updatedItemsInSecondary.find((updatedItem) => updatedItem.uuid.equals(item.uuid))) {
this.logger.info(
`[${userUuid.value}] Skipping integrity check for item ${item.uuid.value} as it was updated in secondary database`,
`Skipping integrity check for item ${item.uuid.value} as it was updated in secondary database`,
)
continue
}
if (alreadyExistingInSecondaryAndPrimary.find((itemUuid) => item.uuid.value === itemUuid)) {
continue
}
if (!item.isIdenticalTo(itemInSecondary)) {
return Result.fail(
`Item ${
@@ -17,10 +17,6 @@ export class MongoDBItemRepository implements ItemRepositoryInterface {
private logger: Logger,
) {}
async removeByUuid(uuid: Uuid): Promise<void> {
await this.mongoRepository.deleteOne({ _id: { $eq: BSON.UUID.createFromHexString(uuid.value) } })
}
async deleteByUserUuid(userUuid: string): Promise<void> {
await this.mongoRepository.deleteMany({ userUuid })
}
@@ -16,15 +16,6 @@ export class SQLLegacyItemRepository implements ItemRepositoryInterface {
protected logger: Logger,
) {}
async removeByUuid(uuid: Uuid): Promise<void> {
await this.ormRepository
.createQueryBuilder('item')
.delete()
.from('items')
.where('uuid = :uuid', { uuid: uuid.value })
.execute()
}
async save(item: Item): Promise<void> {
const persistence = this.mapper.toProjection(item)
-4
View File
@@ -3,10 +3,6 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
## [1.10.46](https://github.com/standardnotes/server/compare/@standardnotes/websockets-server@1.10.45...@standardnotes/websockets-server@1.10.46) (2023-09-19)
**Note:** Version bump only for package @standardnotes/websockets-server
## [1.10.45](https://github.com/standardnotes/server/compare/@standardnotes/websockets-server@1.10.44...@standardnotes/websockets-server@1.10.45) (2023-09-18)
**Note:** Version bump only for package @standardnotes/websockets-server
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "@standardnotes/websockets-server",
"version": "1.10.46",
"version": "1.10.45",
"engines": {
"node": ">=18.0.0 <21.0.0"
},