Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 0 additions & 15 deletions .devcontainer/docker-compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@ services:
environment:
DATABASE_URL: postgresql://affine:affine@db:5432/affine
REDIS_SERVER_HOST: redis
AFFINE_INDEXER_SEARCH_ENDPOINT: http://indexer:9308

db:
image: pgvector/pgvector:pg16
Expand All @@ -26,19 +25,5 @@ services:
redis:
image: redis

indexer:
image: manticoresearch/manticore:${MANTICORE_VERSION:-10.1.0}
ulimits:
nproc: 65535
nofile:
soft: 65535
hard: 65535
memlock:
soft: -1
hard: -1
volumes:
- manticoresearch_data:/var/lib/manticore

volumes:
postgres-data:
manticoresearch_data:
3 changes: 0 additions & 3 deletions .docker/dev/.env.example
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,3 @@ DB_DATABASE_NAME=affine
# enable for arm64, e.g.: macOS M1+
# ELASTIC_VERSION_ARM64=-arm64
# ELASTIC_PLATFORM=linux/arm64

# manticoresearch
MANTICORE_VERSION=10.1.0
17 changes: 0 additions & 17 deletions .docker/dev/compose.yml.example
Original file line number Diff line number Diff line change
Expand Up @@ -32,22 +32,6 @@ services:
volumes:
- mailpit_data:/data

# https://manual.manticoresearch.com/Starting_the_server/Docker
manticoresearch:
image: manticoresearch/manticore:${MANTICORE_VERSION:-10.1.0}
ports:
- 9308:9308
ulimits:
nproc: 65535
nofile:
soft: 65535
hard: 65535
memlock:
soft: -1
hard: -1
volumes:
- manticoresearch_data:/var/lib/manticore

# elasticsearch:
# image: docker.elastic.co/elasticsearch/elasticsearch:${ELASTIC_VERSION:-9.0.1}${ELASTIC_VERSION_ARM64}
# platform: ${ELASTIC_PLATFORM}
Expand Down Expand Up @@ -94,6 +78,5 @@ networks:

volumes:
postgres_data:
manticoresearch_data:
mailpit_data:
elasticsearch_data:
29 changes: 6 additions & 23 deletions .docker/selfhost/schema.json
Original file line number Diff line number Diff line change
Expand Up @@ -86,18 +86,6 @@
"concurrency": 1
}
},
"queues.indexer": {
"type": "object",
"description": "The config for indexer job queue\n@default {\"concurrency\":1}",
"properties": {
"concurrency": {
"type": "number"
}
},
"default": {
"concurrency": 1
}
},
"queues.notification": {
"type": "object",
"description": "The config for notification job queue\n@default {\"concurrency\":10}",
Expand Down Expand Up @@ -1488,38 +1476,33 @@
"properties": {
"enabled": {
"type": "boolean",
"description": "Enable indexer plugin\n@default false\n@environment `AFFINE_INDEXER_ENABLED`",
"description": "Enable indexer plugin\n@default false",
"default": false
},
"provider.type": {
"type": "string",
"description": "Indexer search provider. Self-hosted uses the embedded provider by default; remote providers require an endpoint.\n@default \"embedded\"\n@environment `AFFINE_INDEXER_SEARCH_PROVIDER`",
"description": "Indexer search provider. Self-hosted uses the embedded provider by default; remote providers require an endpoint.\n@default \"embedded\"",
"default": "embedded"
},
"provider.endpoint": {
"type": "string",
"description": "Remote indexer endpoint. Not used by the embedded provider.\n@default \"\"\n@environment `AFFINE_INDEXER_SEARCH_ENDPOINT`",
"description": "Remote indexer endpoint. Not used by the embedded provider.\n@default \"\"",
"default": ""
},
"provider.apiKey": {
"type": "string",
"description": "Indexer search service api key. Optional for elasticsearch\n@default \"\"\n@environment `AFFINE_INDEXER_SEARCH_API_KEY`\n@link https://www.elastic.co/guide/server/current/api-key.html",
"description": "Indexer search service api key. Optional for remote providers\n@default \"\"\n@link https://www.elastic.co/guide/server/current/api-key.html",
"default": ""
},
"provider.username": {
"type": "string",
"description": "Indexer search service auth username, if not set, basic auth will be disabled. Optional for elasticsearch\n@default \"\"\n@environment `AFFINE_INDEXER_SEARCH_USERNAME`\n@link https://www.elastic.co/guide/en/elasticsearch/reference/current/http-clients.html",
"description": "Indexer search service auth username, if not set, basic auth will be disabled. Optional for remote providers\n@default \"\"\n@link https://www.elastic.co/guide/en/elasticsearch/reference/current/http-clients.html",
"default": ""
},
"provider.password": {
"type": "string",
"description": "Indexer search service auth password, if not set, basic auth will be disabled. Optional for elasticsearch\n@default \"\"\n@environment `AFFINE_INDEXER_SEARCH_PASSWORD`",
"description": "Indexer search service auth password, if not set, basic auth will be disabled. Optional for remote providers\n@default \"\"",
"default": ""
},
"autoIndex.batchSize": {
"type": "number",
"description": "Number of workspaces automatically indexed per batch\n@default 10",
"default": 10
}
}
},
Expand Down
3 changes: 3 additions & 0 deletions .github/actions/server-test-env/action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,9 @@ runs:
shell: bash
run: |
case '${{ inputs.indexer-provider }}' in
disabled)
default_indexer='{"enabled":false,"provider":{"type":"embedded","endpoint":""}}'
;;
embedded)
default_indexer='{"enabled":true,"provider":{"type":"embedded","endpoint":""}}'
;;
Expand Down
117 changes: 87 additions & 30 deletions .github/workflows/build-test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -933,8 +933,6 @@ jobs:
NODE_ENV: test
DATABASE_URL: postgresql://affine:affine@localhost:5432/affine
REDIS_SERVER_HOST: localhost
SERVER_CONFIG: >-
{"indexer":{"enabled":true,"provider":{"type":"elasticsearch","endpoint":"http://localhost:9200"}}}
services:
postgres:
image: pgvector/pgvector:pg16
Expand Down Expand Up @@ -1005,18 +1003,81 @@ jobs:
name: affine
fail_ci_if_error: false

server-test-manticore:
name: Server Test with Manticore
server-test-embedded:
name: Server Test with Embedded Search
runs-on: ubuntu-latest
needs:
- build-server-native
env:
NODE_ENV: test
DATABASE_URL: postgresql://affine:affine@localhost:5432/affine
REDIS_SERVER_HOST: localhost
services:
postgres:
image: pgvector/pgvector:pg16
env:
POSTGRES_PASSWORD: affine
options: >-
--health-cmd pg_isready
--health-interval 10s
--health-timeout 5s
--health-retries 5
ports:
- 5432:5432
redis:
image: redis
ports:
- 6379:6379
steps:
- uses: actions/checkout@v7

- name: Setup Node.js
uses: ./.github/actions/setup-node
with:
extra-flags: workspaces focus @affine/monorepo @affine/server
electron-install: false
full-cache: true

- name: Download server-native.node
uses: actions/download-artifact@v4
with:
name: server-native.node
path: ./packages/backend/native

- name: Prepare Server Test Environment
with:
indexer-provider: embedded
uses: ./.github/actions/server-test-env

- name: Run embedded Search provider E2E
run: >-
yarn affine @affine/server e2e:coverage
src/__tests__/e2e/indexer/aggregate.spec.ts
src/__tests__/e2e/indexer/search-docs.spec.ts
src/__tests__/e2e/indexer/search.spec.ts
--concurrency 1
--forbid-only
env:
CARGO_TARGET_DIR: '${{ github.workspace }}/target'

- name: Upload server test coverage results
uses: codecov/codecov-action@v5
with:
token: ${{ secrets.CODECOV_TOKEN }}
files: ./packages/backend/server/.coverage/lcov.info
flags: server-test
name: affine
fail_ci_if_error: false

server-test-manticoresearch:
name: Server Test with Manticore Search
runs-on: ubuntu-latest
needs:
- build-server-native
env:
NODE_ENV: test
DATABASE_URL: postgresql://affine:affine@localhost:5432/affine
REDIS_SERVER_HOST: localhost
SEARCH_MS_URL: http://localhost:9308
SERVER_CONFIG: >-
{"indexer":{"enabled":true,"provider":{"type":"manticoresearch","endpoint":"http://localhost:9308"}}}
services:
postgres:
image: pgvector/pgvector:pg16
Expand All @@ -1038,15 +1099,18 @@ jobs:
ports:
- 1025:1025
- 8025:8025
indexer:
image: manticoresearch/manticore:10.1.0
options: >-
--health-cmd "wget -q -O /dev/null http://localhost:9308/"
--health-interval 5s
--health-timeout 3s
--health-retries 12
manticore:
image: manticoresearch/manticore:29.0.2
env:
'searchd.listen': 'http:9308'
'searchd.network_timeout': '30'
ports:
- 9308:9308
options: >-
--health-cmd "wget -qO- --post-data='SHOW TABLES' 'http://127.0.0.1:9308/sql?mode=raw' >/dev/null"
--health-interval 5s
--health-timeout 5s
--health-retries 30
steps:
- uses: actions/checkout@v7

Expand All @@ -1057,31 +1121,21 @@ jobs:
electron-install: false
full-cache: true

- name: Setup Rust
uses: ./.github/actions/build-rust
with:
target: x86_64-unknown-linux-gnu
package: '@affine/server-native'
no-build: 'true'

- name: Download server-native.node
uses: actions/download-artifact@v4
with:
name: server-native.node
path: ./packages/backend/native

- name: Prepare Server Test Environment
uses: ./.github/actions/server-test-env
with:
indexer-provider: manticoresearch
uses: ./.github/actions/server-test-env

- name: Run server tests with Manticore
run: yarn affine @affine/server e2e:coverage src/__tests__/e2e/indexer/search-docs.spec.ts --forbid-only

- name: Run Manticore provider contract
run: >-
cargo test --manifest-path packages/backend/native/Cargo.toml
remote_providers_apply_search_and_delete_the_same_contract --lib
- name: Run Manticore Search provider E2E
run: yarn affine @affine/server e2e:coverage src/__tests__/e2e/indexer/manticore-provider.spec.ts --forbid-only
env:
CARGO_TARGET_DIR: '${{ github.workspace }}/target'

- name: Upload server test coverage results
uses: codecov/codecov-action@v5
Expand Down Expand Up @@ -1135,6 +1189,8 @@ jobs:
path: ./packages/backend/native

- name: Prepare Server Test Environment
with:
indexer-provider: disabled
uses: ./.github/actions/server-test-env

- name: Run server tests
Expand Down Expand Up @@ -1597,7 +1653,8 @@ jobs:
- native-unit-test
- server-test
- server-test-elasticsearch
- server-test-manticore
- server-test-embedded
- server-test-manticoresearch
- server-e2e-test
- rust-test
- rust-test-filter
Expand Down
39 changes: 1 addition & 38 deletions packages/backend/native/index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -56,10 +56,6 @@ export declare class BackendRuntime {
getWorkspaceInviteLinkById(inviteId: string): Promise<RuntimeWorkspaceInviteLinkRecord | null>
revokeWorkspaceInviteLink(workspaceId: string): Promise<boolean>
cleanupExpiredRuntimeStates(limit: number): Promise<number>
refreshWorkspaceAdminStatsDirty(batchLimit: number, owner: string, leaseTtlMs: number): Promise<RuntimeWorkspaceStatsRefreshResult>
recalibrateWorkspaceAdminStats(lastSid: number, batchLimit: number, owner: string, leaseTtlMs: number): Promise<RuntimeWorkspaceStatsRecalibrationResult>
writeWorkspaceAdminStatsDailySnapshot(owner: string, leaseTtlMs: number): Promise<RuntimeWorkspaceStatsSnapshotResult>
recalibrateWorkspaceAdminStatsDaily(batchLimit: number, owner: string, leaseTtlMs: number, lockRetryTimes: number, lockRetryDelayMs: number): Promise<RuntimeWorkspaceStatsDailyRecalibrationResult>
constructor(privateKey?: string | undefined | null, configPaths?: Array<string> | undefined | null)
start(): Promise<void>
stop(): Promise<void>
Expand All @@ -68,10 +64,7 @@ export declare class BackendRuntime {
runMigrations(): Promise<void>
searchAuthorized(actorUserId: string, workspaceId: string, request: RuntimeSearchRequest): Promise<SearchOperationOutput>
aggregateAuthorized(actorUserId: string, workspaceId: string, request: RuntimeAggregateRequest): Promise<SearchOperationOutput>
indexSearchDocument(workspaceId: string, docId: string): Promise<void>
deleteSearchDocument(workspaceId: string, docId: string): Promise<void>
reconcileSearchWorkspace(workspaceId: string): Promise<void>
deleteSearchWorkspace(workspaceId: string): Promise<void>
reconcileSearchProjection(limit?: number | undefined | null): Promise<number>
filterReadableDocs(actorUserId: string, workspaceId: string, docIds: Array<string>): Promise<Array<string>>
searchStatus(): Promise<any>
embeddingHealth(): Promise<EmbeddingHealth>
Expand Down Expand Up @@ -113,7 +106,6 @@ export declare class StorageRuntime {
rebuildWorkspaceDocBlobRefs(workspaceId: string, limit: number): Promise<RuntimeDocBlobRefsResult>
reconcileWorkspaceDocuments(workspaceId: string): Promise<RuntimeDocumentCleanupReconcileResult>
executeDocumentCleanupCandidates(workspaceId: string | undefined | null, gracePeriodDays: number, limit: number): Promise<RuntimeDocumentCleanupExecuteResult>
ackDocumentCleanupEffect(workspaceId: string, docId: string, cleanupVersion: string, effect: string): Promise<RuntimeDocumentCleanupAckResult>
constructor()
start(): Promise<void>
configure(configJson: string): void
Expand Down Expand Up @@ -1261,16 +1253,11 @@ export interface RuntimeDocHistoryInput {
historyMaxAgeMs: number
}

export interface RuntimeDocumentCleanupAckResult {
completed: boolean
}

export interface RuntimeDocumentCleanupEffect {
workspaceId: string
docId: string
cleanupVersion: string
commentObjectsDone: boolean
searchDone: boolean
}

export interface RuntimeDocumentCleanupExecuteResult {
Expand Down Expand Up @@ -1551,30 +1538,6 @@ export interface RuntimeWorkspaceInviteQuotaUsage {
targetDomains: Array<RuntimeQuotaTargetDomainInput>
}

export interface RuntimeWorkspaceStatsDailyRecalibrationResult {
processed: number
lastSid: number
snapshotted: number
skipped: boolean
}

export interface RuntimeWorkspaceStatsRecalibrationResult {
processed: number
lastSid: number
skipped: boolean
}

export interface RuntimeWorkspaceStatsRefreshResult {
processed: number
backlog: number
skipped: boolean
}

export interface RuntimeWorkspaceStatsSnapshotResult {
snapshotted: number
skipped: boolean
}

export declare function safeFetch(request: SafeFetchRequest): Promise<SafeFetchResponse>

export type SafeFetchMethod = 'get'|
Expand Down
Loading
Loading