@rivetkit/engine 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +203 -0
- package/artifacts/errors/actor.destroyed_during_creation.json +5 -0
- package/artifacts/errors/actor.destroyed_while_waiting_for_ready.json +5 -0
- package/artifacts/errors/actor.duplicate_key.json +5 -0
- package/artifacts/errors/actor.empty_key.json +5 -0
- package/artifacts/errors/actor.input_too_large.json +5 -0
- package/artifacts/errors/actor.key_reserved_in_different_datacenter.json +5 -0
- package/artifacts/errors/actor.key_too_large.json +5 -0
- package/artifacts/errors/actor.kv_key_not_found.json +5 -0
- package/artifacts/errors/actor.namespace_not_found.json +5 -0
- package/artifacts/errors/actor.no_runners_available.json +5 -0
- package/artifacts/errors/actor.not_found.json +5 -0
- package/artifacts/errors/api.bad_request.json +5 -0
- package/artifacts/errors/api.forbidden.json +5 -0
- package/artifacts/errors/api.internal_error.json +5 -0
- package/artifacts/errors/api.not_found.json +5 -0
- package/artifacts/errors/api.rate_limited.json +5 -0
- package/artifacts/errors/api.unauthorized.json +5 -0
- package/artifacts/errors/datacenter.not_found.json +5 -0
- package/artifacts/errors/guard.actor_destroyed.json +5 -0
- package/artifacts/errors/guard.actor_not_found.json +5 -0
- package/artifacts/errors/guard.actor_ready_timeout.json +5 -0
- package/artifacts/errors/guard.connection_error.json +5 -0
- package/artifacts/errors/guard.http_request_build_failed.json +5 -0
- package/artifacts/errors/guard.missing_header.json +5 -0
- package/artifacts/errors/guard.must_use_regional_host.json +5 -0
- package/artifacts/errors/guard.no_route.json +5 -0
- package/artifacts/errors/guard.no_route_targets.json +5 -0
- package/artifacts/errors/guard.rate_limit.json +5 -0
- package/artifacts/errors/guard.request_build_error.json +5 -0
- package/artifacts/errors/guard.request_timeout.json +5 -0
- package/artifacts/errors/guard.retry_attempts_exceeded.json +5 -0
- package/artifacts/errors/guard.service_unavailable.json +5 -0
- package/artifacts/errors/guard.target_changed.json +5 -0
- package/artifacts/errors/guard.upstream_error.json +5 -0
- package/artifacts/errors/guard.uri_parse_error.json +5 -0
- package/artifacts/errors/guard.websocket_pending_limit_reached.json +5 -0
- package/artifacts/errors/guard.websocket_service_hibernate.json +5 -0
- package/artifacts/errors/guard.websocket_service_timeout.json +5 -0
- package/artifacts/errors/guard.websocket_service_unavailable.json +5 -0
- package/artifacts/errors/guard.wrong_addr_protocol.json +5 -0
- package/artifacts/errors/kv.leader_forwarding_failed.json +5 -0
- package/artifacts/errors/kv.no_leader_elected.json +5 -0
- package/artifacts/errors/kv.not_leader.json +5 -0
- package/artifacts/errors/kv.response_channel_closed.json +5 -0
- package/artifacts/errors/namespace.failed_to_create.json +5 -0
- package/artifacts/errors/namespace.invalid_name.json +5 -0
- package/artifacts/errors/namespace.invalid_update.json +5 -0
- package/artifacts/errors/namespace.name_not_unique.json +5 -0
- package/artifacts/errors/namespace.not_found.json +5 -0
- package/artifacts/errors/namespace.not_leader.json +5 -0
- package/artifacts/errors/runner.not_found.json +5 -0
- package/artifacts/errors/runner_config.invalid.json +5 -0
- package/artifacts/errors/runner_config.not_found.json +5 -0
- package/artifacts/errors/test.input_too_large.json +5 -0
- package/artifacts/errors/test.key_too_large.json +5 -0
- package/artifacts/errors/test.meta_error.json +5 -0
- package/artifacts/errors/test.not_found.json +5 -0
- package/artifacts/errors/test.simple_error.json +5 -0
- package/artifacts/errors/test.test_error.json +5 -0
- package/artifacts/errors/ups.publish_failed.json +5 -0
- package/artifacts/errors/ups.request_timeout.json +5 -0
- package/artifacts/errors/validation.invalid_input.json +5 -0
- package/artifacts/errors/validation.no_keys.json +5 -0
- package/artifacts/errors/validation.race_condition.json +5 -0
- package/artifacts/errors/validation.too_many_actor_ids.json +5 -0
- package/artifacts/errors/ws.connection_closed.json +5 -0
- package/artifacts/errors/ws.eviction.json +5 -0
- package/artifacts/errors/ws.invalid_initial_packet.json +5 -0
- package/artifacts/errors/ws.invalid_packet.json +5 -0
- package/artifacts/errors/ws.invalid_url.json +5 -0
- package/artifacts/errors/ws.timed_out_waiting_for_init.json +5 -0
- package/artifacts/openapi.json +1833 -0
- package/contrib-docs/ACTOR_KEY_RESERVATION.md +101 -0
- package/contrib-docs/API.md +11 -0
- package/contrib-docs/DOCKER.md +5 -0
- package/contrib-docs/ERRORS.md +13 -0
- package/contrib-docs/GUARD.md +76 -0
- package/contrib-docs/PEGBOARD_TUNNEL_RETRIES.md +83 -0
- package/contrib-docs/RUNNER_LIFECYCLE.md +172 -0
- package/contrib-docs/SDKS.md +9 -0
- package/contrib-docs/TEST_DEPENDENCIES.md +43 -0
- package/contrib-docs/design-choicse/EMBEDDED_KV.md +80 -0
- package/contrib-docs/operate/TRACING_RECONFIGURE.md +78 -0
- package/docker/dev/.gitattributes +1 -0
- package/docker/dev/README.md +74 -0
- package/docker/dev/clickhouse/client-config.xml +5 -0
- package/docker/dev/clickhouse/config.xml +52 -0
- package/docker/dev/clickhouse/init/01-create-otel-table.sql +107 -0
- package/docker/dev/clickhouse/users.xml +35 -0
- package/docker/dev/docker-compose.yml +217 -0
- package/docker/dev/grafana/dashboards/api.json +1240 -0
- package/docker/dev/grafana/dashboards/cache.json +1075 -0
- package/docker/dev/grafana/dashboards/futures.json +230 -0
- package/docker/dev/grafana/dashboards/gasoline.json +2477 -0
- package/docker/dev/grafana/dashboards/guard.json +1274 -0
- package/docker/dev/grafana/dashboards/tokio.json +1005 -0
- package/docker/dev/grafana/dashboards/traces.json +957 -0
- package/docker/dev/grafana/grafana.ini +14 -0
- package/docker/dev/grafana/provisioning/dashboards/dashboards.yaml +10 -0
- package/docker/dev/grafana/provisioning/datasources/datasources.yaml +30 -0
- package/docker/dev/otel-collector-client/config.yaml +39 -0
- package/docker/dev/otel-collector-server/config.yaml +72 -0
- package/docker/dev/postgres/init-db.sh +6 -0
- package/docker/dev/rivet-engine/config.jsonc +48 -0
- package/docker/dev/vector-client/vector.yaml +31 -0
- package/docker/dev/vector-server/vector.yaml +61 -0
- package/docker/dev-host/.gitattributes +1 -0
- package/docker/dev-host/README.md +74 -0
- package/docker/dev-host/clickhouse/client-config.xml +5 -0
- package/docker/dev-host/clickhouse/config.xml +52 -0
- package/docker/dev-host/clickhouse/init/01-create-otel-table.sql +107 -0
- package/docker/dev-host/clickhouse/users.xml +35 -0
- package/docker/dev-host/docker-compose.yml +190 -0
- package/docker/dev-host/grafana/dashboards/api.json +1240 -0
- package/docker/dev-host/grafana/dashboards/cache.json +1075 -0
- package/docker/dev-host/grafana/dashboards/futures.json +230 -0
- package/docker/dev-host/grafana/dashboards/gasoline.json +2477 -0
- package/docker/dev-host/grafana/dashboards/guard.json +1274 -0
- package/docker/dev-host/grafana/dashboards/tokio.json +1005 -0
- package/docker/dev-host/grafana/dashboards/traces.json +957 -0
- package/docker/dev-host/grafana/grafana.ini +14 -0
- package/docker/dev-host/grafana/provisioning/dashboards/dashboards.yaml +10 -0
- package/docker/dev-host/grafana/provisioning/datasources/datasources.yaml +30 -0
- package/docker/dev-host/otel-collector-client/config.yaml +39 -0
- package/docker/dev-host/otel-collector-server/config.yaml +72 -0
- package/docker/dev-host/postgres/init-db.sh +6 -0
- package/docker/dev-host/rivet-engine/config.jsonc +48 -0
- package/docker/dev-host/vector-client/vector.yaml +31 -0
- package/docker/dev-host/vector-server/vector.yaml +61 -0
- package/docker/dev-multidc/.gitattributes +1 -0
- package/docker/dev-multidc/README.md +86 -0
- package/docker/dev-multidc/core/clickhouse/client-config.xml +5 -0
- package/docker/dev-multidc/core/clickhouse/config.xml +52 -0
- package/docker/dev-multidc/core/clickhouse/init/01-create-otel-table.sql +107 -0
- package/docker/dev-multidc/core/clickhouse/users.xml +35 -0
- package/docker/dev-multidc/core/grafana/dashboards/api.json +1240 -0
- package/docker/dev-multidc/core/grafana/dashboards/cache.json +1075 -0
- package/docker/dev-multidc/core/grafana/dashboards/futures.json +230 -0
- package/docker/dev-multidc/core/grafana/dashboards/gasoline.json +2477 -0
- package/docker/dev-multidc/core/grafana/dashboards/guard.json +1274 -0
- package/docker/dev-multidc/core/grafana/dashboards/tokio.json +1005 -0
- package/docker/dev-multidc/core/grafana/dashboards/traces.json +957 -0
- package/docker/dev-multidc/core/grafana/grafana.ini +14 -0
- package/docker/dev-multidc/core/grafana/provisioning/dashboards/dashboards.yaml +10 -0
- package/docker/dev-multidc/core/grafana/provisioning/datasources/datasources.yaml +30 -0
- package/docker/dev-multidc/datacenters/dc-a/otel-collector-client/config.yaml +39 -0
- package/docker/dev-multidc/datacenters/dc-a/otel-collector-server/config.yaml +72 -0
- package/docker/dev-multidc/datacenters/dc-a/postgres/init-db.sh +6 -0
- package/docker/dev-multidc/datacenters/dc-a/rivet-engine/config.jsonc +62 -0
- package/docker/dev-multidc/datacenters/dc-a/vector-client/vector.yaml +31 -0
- package/docker/dev-multidc/datacenters/dc-a/vector-server/vector.yaml +61 -0
- package/docker/dev-multidc/datacenters/dc-b/otel-collector-client/config.yaml +39 -0
- package/docker/dev-multidc/datacenters/dc-b/otel-collector-server/config.yaml +72 -0
- package/docker/dev-multidc/datacenters/dc-b/postgres/init-db.sh +6 -0
- package/docker/dev-multidc/datacenters/dc-b/rivet-engine/config.jsonc +62 -0
- package/docker/dev-multidc/datacenters/dc-b/vector-client/vector.yaml +31 -0
- package/docker/dev-multidc/datacenters/dc-b/vector-server/vector.yaml +61 -0
- package/docker/dev-multidc/datacenters/dc-c/otel-collector-client/config.yaml +39 -0
- package/docker/dev-multidc/datacenters/dc-c/otel-collector-server/config.yaml +72 -0
- package/docker/dev-multidc/datacenters/dc-c/postgres/init-db.sh +6 -0
- package/docker/dev-multidc/datacenters/dc-c/rivet-engine/config.jsonc +62 -0
- package/docker/dev-multidc/datacenters/dc-c/vector-client/vector.yaml +31 -0
- package/docker/dev-multidc/datacenters/dc-c/vector-server/vector.yaml +61 -0
- package/docker/dev-multidc/docker-compose.yml +546 -0
- package/docker/dev-multidc-multinode/.gitattributes +1 -0
- package/docker/dev-multidc-multinode/README.md +86 -0
- package/docker/dev-multidc-multinode/core/clickhouse/client-config.xml +5 -0
- package/docker/dev-multidc-multinode/core/clickhouse/config.xml +52 -0
- package/docker/dev-multidc-multinode/core/clickhouse/init/01-create-otel-table.sql +107 -0
- package/docker/dev-multidc-multinode/core/clickhouse/users.xml +35 -0
- package/docker/dev-multidc-multinode/core/grafana/dashboards/api.json +1240 -0
- package/docker/dev-multidc-multinode/core/grafana/dashboards/cache.json +1075 -0
- package/docker/dev-multidc-multinode/core/grafana/dashboards/futures.json +230 -0
- package/docker/dev-multidc-multinode/core/grafana/dashboards/gasoline.json +2477 -0
- package/docker/dev-multidc-multinode/core/grafana/dashboards/guard.json +1274 -0
- package/docker/dev-multidc-multinode/core/grafana/dashboards/tokio.json +1005 -0
- package/docker/dev-multidc-multinode/core/grafana/dashboards/traces.json +957 -0
- package/docker/dev-multidc-multinode/core/grafana/grafana.ini +14 -0
- package/docker/dev-multidc-multinode/core/grafana/provisioning/dashboards/dashboards.yaml +10 -0
- package/docker/dev-multidc-multinode/core/grafana/provisioning/datasources/datasources.yaml +30 -0
- package/docker/dev-multidc-multinode/datacenters/dc-a/otel-collector-client/config.yaml +39 -0
- package/docker/dev-multidc-multinode/datacenters/dc-a/otel-collector-server/config.yaml +72 -0
- package/docker/dev-multidc-multinode/datacenters/dc-a/postgres/init-db.sh +6 -0
- package/docker/dev-multidc-multinode/datacenters/dc-a/rivet-engine/0/config.jsonc +62 -0
- package/docker/dev-multidc-multinode/datacenters/dc-a/rivet-engine/1/config.jsonc +62 -0
- package/docker/dev-multidc-multinode/datacenters/dc-a/rivet-engine/2/config.jsonc +62 -0
- package/docker/dev-multidc-multinode/datacenters/dc-a/vector-client/vector.yaml +31 -0
- package/docker/dev-multidc-multinode/datacenters/dc-a/vector-server/vector.yaml +61 -0
- package/docker/dev-multidc-multinode/datacenters/dc-b/otel-collector-client/config.yaml +39 -0
- package/docker/dev-multidc-multinode/datacenters/dc-b/otel-collector-server/config.yaml +72 -0
- package/docker/dev-multidc-multinode/datacenters/dc-b/postgres/init-db.sh +6 -0
- package/docker/dev-multidc-multinode/datacenters/dc-b/rivet-engine/0/config.jsonc +62 -0
- package/docker/dev-multidc-multinode/datacenters/dc-b/rivet-engine/1/config.jsonc +62 -0
- package/docker/dev-multidc-multinode/datacenters/dc-b/rivet-engine/2/config.jsonc +62 -0
- package/docker/dev-multidc-multinode/datacenters/dc-b/vector-client/vector.yaml +31 -0
- package/docker/dev-multidc-multinode/datacenters/dc-b/vector-server/vector.yaml +61 -0
- package/docker/dev-multidc-multinode/datacenters/dc-c/otel-collector-client/config.yaml +39 -0
- package/docker/dev-multidc-multinode/datacenters/dc-c/otel-collector-server/config.yaml +72 -0
- package/docker/dev-multidc-multinode/datacenters/dc-c/postgres/init-db.sh +6 -0
- package/docker/dev-multidc-multinode/datacenters/dc-c/rivet-engine/0/config.jsonc +62 -0
- package/docker/dev-multidc-multinode/datacenters/dc-c/rivet-engine/1/config.jsonc +62 -0
- package/docker/dev-multidc-multinode/datacenters/dc-c/rivet-engine/2/config.jsonc +62 -0
- package/docker/dev-multidc-multinode/datacenters/dc-c/vector-client/vector.yaml +31 -0
- package/docker/dev-multidc-multinode/datacenters/dc-c/vector-server/vector.yaml +61 -0
- package/docker/dev-multidc-multinode/docker-compose.yml +888 -0
- package/docker/dev-multinode/.gitattributes +1 -0
- package/docker/dev-multinode/README.md +74 -0
- package/docker/dev-multinode/clickhouse/client-config.xml +5 -0
- package/docker/dev-multinode/clickhouse/config.xml +52 -0
- package/docker/dev-multinode/clickhouse/init/01-create-otel-table.sql +107 -0
- package/docker/dev-multinode/clickhouse/users.xml +35 -0
- package/docker/dev-multinode/docker-compose.yml +323 -0
- package/docker/dev-multinode/grafana/dashboards/api.json +1240 -0
- package/docker/dev-multinode/grafana/dashboards/cache.json +1075 -0
- package/docker/dev-multinode/grafana/dashboards/futures.json +230 -0
- package/docker/dev-multinode/grafana/dashboards/gasoline.json +2477 -0
- package/docker/dev-multinode/grafana/dashboards/guard.json +1274 -0
- package/docker/dev-multinode/grafana/dashboards/tokio.json +1005 -0
- package/docker/dev-multinode/grafana/dashboards/traces.json +957 -0
- package/docker/dev-multinode/grafana/grafana.ini +14 -0
- package/docker/dev-multinode/grafana/provisioning/dashboards/dashboards.yaml +10 -0
- package/docker/dev-multinode/grafana/provisioning/datasources/datasources.yaml +30 -0
- package/docker/dev-multinode/otel-collector-client/config.yaml +39 -0
- package/docker/dev-multinode/otel-collector-server/config.yaml +72 -0
- package/docker/dev-multinode/postgres/init-db.sh +6 -0
- package/docker/dev-multinode/rivet-engine/0/config.jsonc +48 -0
- package/docker/dev-multinode/rivet-engine/1/config.jsonc +48 -0
- package/docker/dev-multinode/rivet-engine/2/config.jsonc +48 -0
- package/docker/dev-multinode/vector-client/vector.yaml +31 -0
- package/docker/dev-multinode/vector-server/vector.yaml +61 -0
- package/docker/engine/build.sh +67 -0
- package/docker/engine/linux-aarch64.Dockerfile +97 -0
- package/docker/engine/linux-x86_64.Dockerfile +93 -0
- package/docker/engine/macos-aarch64.Dockerfile +92 -0
- package/docker/engine/macos-x86_64.Dockerfile +92 -0
- package/docker/engine/windows.Dockerfile +80 -0
- package/docker/prod-file-system/.gitattributes +1 -0
- package/docker/prod-file-system/README.md +76 -0
- package/docker/prod-file-system/docker-compose.yml +41 -0
- package/docker/prod-file-system/rivet-engine/config.jsonc +2 -0
- package/docker/template/README.md +20 -0
- package/docker/template/grafana-dashboards/api.json +1240 -0
- package/docker/template/grafana-dashboards/cache.json +1075 -0
- package/docker/template/grafana-dashboards/futures.json +230 -0
- package/docker/template/grafana-dashboards/gasoline.json +2477 -0
- package/docker/template/grafana-dashboards/guard.json +1274 -0
- package/docker/template/grafana-dashboards/tokio.json +1005 -0
- package/docker/template/grafana-dashboards/traces.json +957 -0
- package/docker/template/node_modules/.bin/js-yaml +21 -0
- package/docker/template/node_modules/.bin/tsc +21 -0
- package/docker/template/node_modules/.bin/tsserver +21 -0
- package/docker/template/node_modules/.bin/tsx +21 -0
- package/docker/template/package.json +23 -0
- package/docker/template/src/config.ts +104 -0
- package/docker/template/src/context.ts +216 -0
- package/docker/template/src/docker-compose.ts +368 -0
- package/docker/template/src/git.ts +8 -0
- package/docker/template/src/main.ts +65 -0
- package/docker/template/src/readme.ts +98 -0
- package/docker/template/src/services/core/clickhouse.ts +223 -0
- package/docker/template/src/services/core/grafana.ts +115 -0
- package/docker/template/src/services/edge/otel-collector-client.ts +64 -0
- package/docker/template/src/services/edge/otel-collector-server.ts +107 -0
- package/docker/template/src/services/edge/postgres.ts +23 -0
- package/docker/template/src/services/edge/rivet-engine.ts +87 -0
- package/docker/template/src/services/edge/runner.ts +7 -0
- package/docker/template/src/services/edge/vector-client.ts +55 -0
- package/docker/template/src/services/edge/vector-server.ts +111 -0
- package/docker/template/src/utils.ts +19 -0
- package/docker/template/tsconfig.json +18 -0
- package/docker/universal/Dockerfile +133 -0
- package/package.json +10 -0
- package/packages/actor-kv/Cargo.toml +31 -0
- package/packages/actor-kv/src/entry.rs +147 -0
- package/packages/actor-kv/src/key.rs +81 -0
- package/packages/actor-kv/src/lib.rs +357 -0
- package/packages/actor-kv/src/utils.rs +101 -0
- package/packages/actor-kv/tests/kv_operations.rs +294 -0
- package/packages/actor-kv/tests/list_edge_cases.rs +370 -0
- package/packages/api-builder/Cargo.toml +36 -0
- package/packages/api-builder/src/context.rs +98 -0
- package/packages/api-builder/src/error_response.rs +116 -0
- package/packages/api-builder/src/errors.rs +29 -0
- package/packages/api-builder/src/extract.rs +137 -0
- package/packages/api-builder/src/global_context.rs +31 -0
- package/packages/api-builder/src/lib.rs +19 -0
- package/packages/api-builder/src/metrics.rs +29 -0
- package/packages/api-builder/src/middleware.rs +232 -0
- package/packages/api-builder/src/prelude.rs +18 -0
- package/packages/api-builder/src/request_ids.rs +17 -0
- package/packages/api-builder/src/router.rs +89 -0
- package/packages/api-builder/src/wrappers.rs +138 -0
- package/packages/api-builder/tests/basic.rs +215 -0
- package/packages/api-builder/tests/errors.rs +104 -0
- package/packages/api-peer/Cargo.toml +34 -0
- package/packages/api-peer/src/actors/create.rs +40 -0
- package/packages/api-peer/src/actors/delete.rs +87 -0
- package/packages/api-peer/src/actors/kv_get.rs +67 -0
- package/packages/api-peer/src/actors/list.rs +98 -0
- package/packages/api-peer/src/actors/list_names.rs +56 -0
- package/packages/api-peer/src/actors/mod.rs +5 -0
- package/packages/api-peer/src/internal.rs +186 -0
- package/packages/api-peer/src/lib.rs +28 -0
- package/packages/api-peer/src/namespaces.rs +122 -0
- package/packages/api-peer/src/router.rs +51 -0
- package/packages/api-peer/src/runner_configs.rs +160 -0
- package/packages/api-peer/src/runners.rs +109 -0
- package/packages/api-public/Cargo.toml +38 -0
- package/packages/api-public/build.rs +45 -0
- package/packages/api-public/src/actors/create.rs +99 -0
- package/packages/api-public/src/actors/delete.rs +86 -0
- package/packages/api-public/src/actors/get_or_create.rs +170 -0
- package/packages/api-public/src/actors/kv_get.rs +79 -0
- package/packages/api-public/src/actors/list.rs +241 -0
- package/packages/api-public/src/actors/list_names.rs +76 -0
- package/packages/api-public/src/actors/mod.rs +7 -0
- package/packages/api-public/src/actors/utils.rs +216 -0
- package/packages/api-public/src/ctx.rs +70 -0
- package/packages/api-public/src/datacenters.rs +43 -0
- package/packages/api-public/src/errors.rs +30 -0
- package/packages/api-public/src/health.rs +166 -0
- package/packages/api-public/src/lib.rs +13 -0
- package/packages/api-public/src/metadata.rs +24 -0
- package/packages/api-public/src/namespaces.rs +89 -0
- package/packages/api-public/src/router.rs +182 -0
- package/packages/api-public/src/runner_configs/delete.rs +99 -0
- package/packages/api-public/src/runner_configs/list.rs +98 -0
- package/packages/api-public/src/runner_configs/mod.rs +12 -0
- package/packages/api-public/src/runner_configs/refresh_metadata.rs +116 -0
- package/packages/api-public/src/runner_configs/serverless_health_check.rs +81 -0
- package/packages/api-public/src/runner_configs/upsert.rs +194 -0
- package/packages/api-public/src/runner_configs/utils.rs +217 -0
- package/packages/api-public/src/runners.rs +144 -0
- package/packages/api-public/src/ui.rs +44 -0
- package/packages/api-types/Cargo.toml +17 -0
- package/packages/api-types/src/actors/create.rs +29 -0
- package/packages/api-types/src/actors/list.rs +23 -0
- package/packages/api-types/src/actors/list_names.rs +24 -0
- package/packages/api-types/src/actors/mod.rs +3 -0
- package/packages/api-types/src/datacenters/list.rs +12 -0
- package/packages/api-types/src/datacenters/mod.rs +1 -0
- package/packages/api-types/src/lib.rs +6 -0
- package/packages/api-types/src/namespaces/list.rs +21 -0
- package/packages/api-types/src/namespaces/mod.rs +2 -0
- package/packages/api-types/src/namespaces/runner_configs.rs +55 -0
- package/packages/api-types/src/pagination.rs +8 -0
- package/packages/api-types/src/runner_configs/list.rs +29 -0
- package/packages/api-types/src/runner_configs/mod.rs +1 -0
- package/packages/api-types/src/runners/list.rs +25 -0
- package/packages/api-types/src/runners/mod.rs +1 -0
- package/packages/api-util/Cargo.toml +22 -0
- package/packages/api-util/src/errors.rs +9 -0
- package/packages/api-util/src/lib.rs +209 -0
- package/packages/bootstrap/Cargo.toml +19 -0
- package/packages/bootstrap/src/lib.rs +102 -0
- package/packages/cache/Cargo.toml +28 -0
- package/packages/cache/src/driver.rs +346 -0
- package/packages/cache/src/errors.rs +23 -0
- package/packages/cache/src/getter_ctx.rs +138 -0
- package/packages/cache/src/inner.rs +60 -0
- package/packages/cache/src/key.rs +101 -0
- package/packages/cache/src/lib.rs +19 -0
- package/packages/cache/src/metrics.rs +34 -0
- package/packages/cache/src/purge.rs +13 -0
- package/packages/cache/src/rate_limit.rs +109 -0
- package/packages/cache/src/req_config.rs +443 -0
- package/packages/cache/tests/integration.rs +582 -0
- package/packages/cache-purge/Cargo.toml +17 -0
- package/packages/cache-purge/src/lib.rs +44 -0
- package/packages/cache-result/Cargo.toml +9 -0
- package/packages/cache-result/src/lib.rs +61 -0
- package/packages/clickhouse-inserter/Cargo.toml +17 -0
- package/packages/clickhouse-inserter/src/error.rs +16 -0
- package/packages/clickhouse-inserter/src/lib.rs +179 -0
- package/packages/clickhouse-user-query/Cargo.toml +16 -0
- package/packages/clickhouse-user-query/examples/case_sensitivity_demo.rs +100 -0
- package/packages/clickhouse-user-query/examples/group_by_example.rs +53 -0
- package/packages/clickhouse-user-query/examples/string_contains_demo.rs +96 -0
- package/packages/clickhouse-user-query/src/builder.rs +445 -0
- package/packages/clickhouse-user-query/src/error.rs +37 -0
- package/packages/clickhouse-user-query/src/lib.rs +61 -0
- package/packages/clickhouse-user-query/src/query.rs +143 -0
- package/packages/clickhouse-user-query/src/schema.rs +78 -0
- package/packages/clickhouse-user-query/tests/builder_tests.rs +619 -0
- package/packages/clickhouse-user-query/tests/case_sensitivity_tests.rs +307 -0
- package/packages/clickhouse-user-query/tests/integration_tests.rs +540 -0
- package/packages/clickhouse-user-query/tests/query_tests.rs +263 -0
- package/packages/clickhouse-user-query/tests/schema_tests.rs +44 -0
- package/packages/config/Cargo.toml +20 -0
- package/packages/config/src/config/api_peer.rs +21 -0
- package/packages/config/src/config/api_public.rs +25 -0
- package/packages/config/src/config/auth.rs +10 -0
- package/packages/config/src/config/cache.rs +24 -0
- package/packages/config/src/config/clickhouse.rs +49 -0
- package/packages/config/src/config/db.rs +52 -0
- package/packages/config/src/config/guard.rs +42 -0
- package/packages/config/src/config/logs.rs +10 -0
- package/packages/config/src/config/mod.rs +240 -0
- package/packages/config/src/config/pegboard.rs +94 -0
- package/packages/config/src/config/pubsub.rs +90 -0
- package/packages/config/src/config/runtime.rs +31 -0
- package/packages/config/src/config/telemetry.rs +14 -0
- package/packages/config/src/config/topology.rs +123 -0
- package/packages/config/src/config/vector.rs +18 -0
- package/packages/config/src/defaults.rs +11 -0
- package/packages/config/src/lib.rs +135 -0
- package/packages/config/src/paths.rs +25 -0
- package/packages/config/src/secret.rs +72 -0
- package/packages/dump-openapi/Cargo.toml +11 -0
- package/packages/dump-openapi/build.rs +26 -0
- package/packages/dump-openapi/src/lib.rs +1 -0
- package/packages/engine/Cargo.toml +74 -0
- package/packages/engine/src/commands/config.rs +18 -0
- package/packages/engine/src/commands/db/mod.rs +80 -0
- package/packages/engine/src/commands/mod.rs +7 -0
- package/packages/engine/src/commands/start.rs +143 -0
- package/packages/engine/src/commands/tracing.rs +86 -0
- package/packages/engine/src/commands/udb/cli.rs +562 -0
- package/packages/engine/src/commands/udb/mod.rs +132 -0
- package/packages/engine/src/commands/udb_keys.rs +200 -0
- package/packages/engine/src/commands/wf/mod.rs +125 -0
- package/packages/engine/src/commands/wf/signal.rs +80 -0
- package/packages/engine/src/keys.rs +47 -0
- package/packages/engine/src/lib.rs +55 -0
- package/packages/engine/src/main.rs +60 -0
- package/packages/engine/src/run_config.rs +53 -0
- package/packages/engine/src/util/db.rs +99 -0
- package/packages/engine/src/util/format.rs +69 -0
- package/packages/engine/src/util/mod.rs +13 -0
- package/packages/engine/src/util/udb.rs +687 -0
- package/packages/engine/src/util/wf/mod.rs +649 -0
- package/packages/engine/src/util/wf/signal.rs +126 -0
- package/packages/engine/tests/actors_create.rs +524 -0
- package/packages/engine/tests/actors_delete.rs +243 -0
- package/packages/engine/tests/actors_general.rs +191 -0
- package/packages/engine/tests/actors_get.rs +230 -0
- package/packages/engine/tests/actors_get_by_id.rs +170 -0
- package/packages/engine/tests/actors_get_or_create.rs +294 -0
- package/packages/engine/tests/actors_get_or_create_by_id.rs +147 -0
- package/packages/engine/tests/actors_lifecycle.rs +165 -0
- package/packages/engine/tests/actors_list.rs +798 -0
- package/packages/engine/tests/actors_list_names.rs +353 -0
- package/packages/engine/tests/common/actors.rs +554 -0
- package/packages/engine/tests/common/ctx.rs +201 -0
- package/packages/engine/tests/common/mod.rs +30 -0
- package/packages/engine/tests/common/ns.rs +36 -0
- package/packages/engine/tests/common/runner.rs +134 -0
- package/packages/engine/tests/common/test_helpers.rs +226 -0
- package/packages/engine/tests/runners_dupe_key.rs +27 -0
- package/packages/engine/tests/runners_version.rs +50 -0
- package/packages/env/Cargo.toml +14 -0
- package/packages/env/build.rs +8 -0
- package/packages/env/src/lib.rs +30 -0
- package/packages/epoxy/Cargo.toml +45 -0
- package/packages/epoxy/README.md +158 -0
- package/packages/epoxy/spec/KEYS.md +33 -0
- package/packages/epoxy/spec/PROPOSAL.md +125 -0
- package/packages/epoxy/spec/RECONFIGURE.md +40 -0
- package/packages/epoxy/src/consts.rs +42 -0
- package/packages/epoxy/src/errors.rs +21 -0
- package/packages/epoxy/src/http_client.rs +192 -0
- package/packages/epoxy/src/http_routes.rs +34 -0
- package/packages/epoxy/src/keys/keys.rs +99 -0
- package/packages/epoxy/src/keys/mod.rs +9 -0
- package/packages/epoxy/src/keys/replica.rs +283 -0
- package/packages/epoxy/src/lib.rs +25 -0
- package/packages/epoxy/src/ops/explicit_prepare.rs +342 -0
- package/packages/epoxy/src/ops/kv/get_local.rs +44 -0
- package/packages/epoxy/src/ops/kv/get_optimistic.rs +150 -0
- package/packages/epoxy/src/ops/kv/mod.rs +3 -0
- package/packages/epoxy/src/ops/kv/purge_local.rs +28 -0
- package/packages/epoxy/src/ops/mod.rs +4 -0
- package/packages/epoxy/src/ops/propose.rs +352 -0
- package/packages/epoxy/src/ops/read_cluster_config.rs +24 -0
- package/packages/epoxy/src/replica/ballot.rs +130 -0
- package/packages/epoxy/src/replica/commit_kv.rs +80 -0
- package/packages/epoxy/src/replica/decide_path.rs +51 -0
- package/packages/epoxy/src/replica/lead_consensus.rs +65 -0
- package/packages/epoxy/src/replica/log.rs +84 -0
- package/packages/epoxy/src/replica/message_request.rs +166 -0
- package/packages/epoxy/src/replica/messages/accept.rs +50 -0
- package/packages/epoxy/src/replica/messages/accepted.rs +35 -0
- package/packages/epoxy/src/replica/messages/commit.rs +46 -0
- package/packages/epoxy/src/replica/messages/committed.rs +41 -0
- package/packages/epoxy/src/replica/messages/download_instances.rs +69 -0
- package/packages/epoxy/src/replica/messages/mod.rs +15 -0
- package/packages/epoxy/src/replica/messages/pre_accept.rs +69 -0
- package/packages/epoxy/src/replica/messages/prepare.rs +89 -0
- package/packages/epoxy/src/replica/mod.rs +11 -0
- package/packages/epoxy/src/replica/update_config.rs +24 -0
- package/packages/epoxy/src/replica/utils.rs +111 -0
- package/packages/epoxy/src/types.rs +117 -0
- package/packages/epoxy/src/utils.rs +65 -0
- package/packages/epoxy/src/workflows/coordinator/mod.rs +121 -0
- package/packages/epoxy/src/workflows/coordinator/reconfigure.rs +291 -0
- package/packages/epoxy/src/workflows/coordinator/replica_status_change.rs +193 -0
- package/packages/epoxy/src/workflows/mod.rs +3 -0
- package/packages/epoxy/src/workflows/purger.rs +81 -0
- package/packages/epoxy/src/workflows/replica/mod.rs +39 -0
- package/packages/epoxy/src/workflows/replica/setup.rs +823 -0
- package/packages/epoxy/tests/common/api.rs +25 -0
- package/packages/epoxy/tests/common/mod.rs +301 -0
- package/packages/epoxy/tests/common/utils.rs +23 -0
- package/packages/epoxy/tests/kv.rs +187 -0
- package/packages/epoxy/tests/kv_get_optimistic.rs +179 -0
- package/packages/epoxy/tests/proposal.rs +38 -0
- package/packages/epoxy/tests/reconfigure.rs +618 -0
- package/packages/error/Cargo.toml +16 -0
- package/packages/error/src/error.rs +90 -0
- package/packages/error/src/lib.rs +13 -0
- package/packages/error/src/schema.rs +86 -0
- package/packages/error/tests/basic.rs +338 -0
- package/packages/error-macros/Cargo.toml +19 -0
- package/packages/error-macros/src/lib.rs +632 -0
- package/packages/gasoline/Cargo.toml +55 -0
- package/packages/gasoline/src/activity.rs +24 -0
- package/packages/gasoline/src/builder/common/message.rs +104 -0
- package/packages/gasoline/src/builder/common/mod.rs +5 -0
- package/packages/gasoline/src/builder/common/signal.rs +193 -0
- package/packages/gasoline/src/builder/common/workflow.rs +196 -0
- package/packages/gasoline/src/builder/mod.rs +60 -0
- package/packages/gasoline/src/builder/workflow/message.rs +147 -0
- package/packages/gasoline/src/builder/workflow/mod.rs +5 -0
- package/packages/gasoline/src/builder/workflow/signal.rs +227 -0
- package/packages/gasoline/src/builder/workflow/sub_workflow.rs +318 -0
- package/packages/gasoline/src/ctx/activity.rs +192 -0
- package/packages/gasoline/src/ctx/common.rs +153 -0
- package/packages/gasoline/src/ctx/listen.rs +121 -0
- package/packages/gasoline/src/ctx/message.rs +346 -0
- package/packages/gasoline/src/ctx/mod.rs +18 -0
- package/packages/gasoline/src/ctx/operation.rs +191 -0
- package/packages/gasoline/src/ctx/standalone.rs +228 -0
- package/packages/gasoline/src/ctx/test.rs +251 -0
- package/packages/gasoline/src/ctx/versioned_workflow.rs +198 -0
- package/packages/gasoline/src/ctx/workflow.rs +1459 -0
- package/packages/gasoline/src/db/debug.rs +199 -0
- package/packages/gasoline/src/db/kv/debug.rs +1493 -0
- package/packages/gasoline/src/db/kv/keys/history.rs +1780 -0
- package/packages/gasoline/src/db/kv/keys/metric.rs +170 -0
- package/packages/gasoline/src/db/kv/keys/mod.rs +6 -0
- package/packages/gasoline/src/db/kv/keys/signal.rs +401 -0
- package/packages/gasoline/src/db/kv/keys/wake.rs +310 -0
- package/packages/gasoline/src/db/kv/keys/worker.rs +185 -0
- package/packages/gasoline/src/db/kv/keys/workflow.rs +1175 -0
- package/packages/gasoline/src/db/kv/mod.rs +3044 -0
- package/packages/gasoline/src/db/kv/subjects.rs +13 -0
- package/packages/gasoline/src/db/kv/system.rs +33 -0
- package/packages/gasoline/src/db/mod.rs +344 -0
- package/packages/gasoline/src/error.rs +258 -0
- package/packages/gasoline/src/executable.rs +186 -0
- package/packages/gasoline/src/history/cursor.rs +779 -0
- package/packages/gasoline/src/history/event.rs +210 -0
- package/packages/gasoline/src/history/location.rs +185 -0
- package/packages/gasoline/src/history/mod.rs +8 -0
- package/packages/gasoline/src/history/removed.rs +94 -0
- package/packages/gasoline/src/lib.rs +18 -0
- package/packages/gasoline/src/listen.rs +24 -0
- package/packages/gasoline/src/message.rs +103 -0
- package/packages/gasoline/src/metrics.rs +156 -0
- package/packages/gasoline/src/operation.rs +21 -0
- package/packages/gasoline/src/prelude.rs +53 -0
- package/packages/gasoline/src/registry.rs +111 -0
- package/packages/gasoline/src/signal.rs +117 -0
- package/packages/gasoline/src/stub.rs +118 -0
- package/packages/gasoline/src/utils/mod.rs +20 -0
- package/packages/gasoline/src/utils/tags.rs +82 -0
- package/packages/gasoline/src/utils/time.rs +85 -0
- package/packages/gasoline/src/worker.rs +336 -0
- package/packages/gasoline/src/workflow.rs +64 -0
- package/packages/gasoline/tests/activity_ctx.rs +83 -0
- package/packages/gasoline/tests/workflow_ctx.rs +288 -0
- package/packages/gasoline/tests/workflows/activity_test.rs +33 -0
- package/packages/gasoline/tests/workflows/basic.rs +13 -0
- package/packages/gasoline/tests/workflows/eviction_test.rs +45 -0
- package/packages/gasoline/tests/workflows/listen_timeout.rs +27 -0
- package/packages/gasoline/tests/workflows/loop_test.rs +30 -0
- package/packages/gasoline/tests/workflows/mod.rs +11 -0
- package/packages/gasoline/tests/workflows/properties_test.rs +56 -0
- package/packages/gasoline/tests/workflows/signal_test.rs +24 -0
- package/packages/gasoline/tests/workflows/sleep_test.rs +15 -0
- package/packages/gasoline/tests/workflows/state_test.rs +69 -0
- package/packages/gasoline/tests/workflows/sub_test.rs +21 -0
- package/packages/gasoline/tests/workflows/tags_test.rs +40 -0
- package/packages/gasoline-macros/Cargo.toml +14 -0
- package/packages/gasoline-macros/src/lib.rs +527 -0
- package/packages/guard/Cargo.toml +56 -0
- package/packages/guard/src/cache/actor.rs +43 -0
- package/packages/guard/src/cache/mod.rs +69 -0
- package/packages/guard/src/errors.rs +62 -0
- package/packages/guard/src/lib.rs +58 -0
- package/packages/guard/src/middleware.rs +42 -0
- package/packages/guard/src/routing/api_public.rs +70 -0
- package/packages/guard/src/routing/mod.rs +245 -0
- package/packages/guard/src/routing/pegboard_gateway.rs +260 -0
- package/packages/guard/src/routing/runner.rs +129 -0
- package/packages/guard/src/shared_state.rs +31 -0
- package/packages/guard/src/tls.rs +224 -0
- package/packages/guard/tests/parse_actor_path.rs +240 -0
- package/packages/guard-core/Cargo.toml +58 -0
- package/packages/guard-core/src/analytics.rs +46 -0
- package/packages/guard-core/src/cert_resolver.rs +61 -0
- package/packages/guard-core/src/custom_serve.rs +52 -0
- package/packages/guard-core/src/errors.rs +113 -0
- package/packages/guard-core/src/lib.rs +25 -0
- package/packages/guard-core/src/metrics.rs +64 -0
- package/packages/guard-core/src/proxy_service.rs +2699 -0
- package/packages/guard-core/src/request_context.rs +184 -0
- package/packages/guard-core/src/server.rs +289 -0
- package/packages/guard-core/src/task_group.rs +57 -0
- package/packages/guard-core/src/types.rs +19 -0
- package/packages/guard-core/src/websocket_handle.rs +47 -0
- package/packages/guard-core/tests/common/mod.rs +678 -0
- package/packages/guard-core/tests/custom_serve.rs +392 -0
- package/packages/guard-core/tests/fixtures/tls/README.md +6 -0
- package/packages/guard-core/tests/fixtures/tls/api_cert.pem +51 -0
- package/packages/guard-core/tests/fixtures/tls/api_key.pem +7 -0
- package/packages/guard-core/tests/fixtures/tls/job_cert.pem +55 -0
- package/packages/guard-core/tests/fixtures/tls/job_key.pem +7 -0
- package/packages/guard-core/tests/https.rs +400 -0
- package/packages/guard-core/tests/metrics.rs +247 -0
- package/packages/guard-core/tests/proxy.rs +842 -0
- package/packages/guard-core/tests/simple_websocket.rs +258 -0
- package/packages/guard-core/tests/simple_websocket_echo.rs +318 -0
- package/packages/guard-core/tests/simple_websocket_test2.rs +120 -0
- package/packages/guard-core/tests/streaming_response.rs +265 -0
- package/packages/guard-core/tests/websocket.rs +1113 -0
- package/packages/internal/Cargo.toml +13 -0
- package/packages/internal/README.md +1 -0
- package/packages/internal/src/lib.rs +1 -0
- package/packages/internal/src/ops/bump_serverless_autoscaler_global.rs +64 -0
- package/packages/internal/src/ops/cache/mod.rs +1 -0
- package/packages/internal/src/ops/cache/purge_global.rs +81 -0
- package/packages/internal/src/ops/mod.rs +2 -0
- package/packages/logs/Cargo.toml +20 -0
- package/packages/logs/src/lib.rs +9 -0
- package/packages/logs/src/unix.rs +201 -0
- package/packages/logs/src/windows.rs +240 -0
- package/packages/metrics/Cargo.toml +20 -0
- package/packages/metrics/src/buckets.rs +32 -0
- package/packages/metrics/src/lib.rs +8 -0
- package/packages/metrics/src/providers.rs +183 -0
- package/packages/namespace/Cargo.toml +28 -0
- package/packages/namespace/src/errors.rs +39 -0
- package/packages/namespace/src/keys/mod.rs +190 -0
- package/packages/namespace/src/keys/runner_config.rs +211 -0
- package/packages/namespace/src/lib.rs +16 -0
- package/packages/namespace/src/ops/get_global.rs +58 -0
- package/packages/namespace/src/ops/get_local.rs +69 -0
- package/packages/namespace/src/ops/list.rs +69 -0
- package/packages/namespace/src/ops/mod.rs +6 -0
- package/packages/namespace/src/ops/resolve_for_name_global.rs +57 -0
- package/packages/namespace/src/ops/resolve_for_name_local.rs +41 -0
- package/packages/namespace/src/ops/runner_config/delete.rs +53 -0
- package/packages/namespace/src/ops/runner_config/get.rs +94 -0
- package/packages/namespace/src/ops/runner_config/list.rs +94 -0
- package/packages/namespace/src/ops/runner_config/mod.rs +4 -0
- package/packages/namespace/src/ops/runner_config/upsert.rs +148 -0
- package/packages/namespace/src/utils.rs +11 -0
- package/packages/namespace/src/workflows/mod.rs +1 -0
- package/packages/namespace/src/workflows/namespace.rs +178 -0
- package/packages/pegboard/Cargo.toml +34 -0
- package/packages/pegboard/src/errors.rs +76 -0
- package/packages/pegboard/src/keys/actor.rs +443 -0
- package/packages/pegboard/src/keys/epoxy/mod.rs +1 -0
- package/packages/pegboard/src/keys/epoxy/ns.rs +68 -0
- package/packages/pegboard/src/keys/hibernating_request.rs +72 -0
- package/packages/pegboard/src/keys/mod.rs +15 -0
- package/packages/pegboard/src/keys/ns.rs +1367 -0
- package/packages/pegboard/src/keys/runner.rs +818 -0
- package/packages/pegboard/src/lib.rs +19 -0
- package/packages/pegboard/src/metrics.rs +19 -0
- package/packages/pegboard/src/ops/actor/create.rs +159 -0
- package/packages/pegboard/src/ops/actor/get.rs +100 -0
- package/packages/pegboard/src/ops/actor/get_for_gateway.rs +70 -0
- package/packages/pegboard/src/ops/actor/get_for_key.rs +93 -0
- package/packages/pegboard/src/ops/actor/get_reservation_for_key.rs +46 -0
- package/packages/pegboard/src/ops/actor/get_runner.rs +64 -0
- package/packages/pegboard/src/ops/actor/hibernating_request/delete.rs +41 -0
- package/packages/pegboard/src/ops/actor/hibernating_request/list.rs +65 -0
- package/packages/pegboard/src/ops/actor/hibernating_request/mod.rs +3 -0
- package/packages/pegboard/src/ops/actor/hibernating_request/upsert.rs +51 -0
- package/packages/pegboard/src/ops/actor/list_for_ns.rs +207 -0
- package/packages/pegboard/src/ops/actor/list_names.rs +62 -0
- package/packages/pegboard/src/ops/actor/mod.rs +9 -0
- package/packages/pegboard/src/ops/mod.rs +2 -0
- package/packages/pegboard/src/ops/runner/find_dc_with_runner.rs +222 -0
- package/packages/pegboard/src/ops/runner/get.rs +143 -0
- package/packages/pegboard/src/ops/runner/get_by_key.rs +51 -0
- package/packages/pegboard/src/ops/runner/list_for_ns.rs +209 -0
- package/packages/pegboard/src/ops/runner/list_names.rs +60 -0
- package/packages/pegboard/src/ops/runner/mod.rs +6 -0
- package/packages/pegboard/src/ops/runner/update_alloc_idx.rs +208 -0
- package/packages/pegboard/src/pubsub_subjects.rs +80 -0
- package/packages/pegboard/src/utils.rs +29 -0
- package/packages/pegboard/src/workflows/actor/destroy.rs +264 -0
- package/packages/pegboard/src/workflows/actor/keys.rs +283 -0
- package/packages/pegboard/src/workflows/actor/mod.rs +804 -0
- package/packages/pegboard/src/workflows/actor/runtime.rs +909 -0
- package/packages/pegboard/src/workflows/actor/setup.rs +175 -0
- package/packages/pegboard/src/workflows/mod.rs +2 -0
- package/packages/pegboard/src/workflows/runner.rs +1182 -0
- package/packages/pegboard-gateway/Cargo.toml +35 -0
- package/packages/pegboard-gateway/src/keepalive_task.rs +61 -0
- package/packages/pegboard-gateway/src/lib.rs +698 -0
- package/packages/pegboard-gateway/src/metrics.rs +14 -0
- package/packages/pegboard-gateway/src/ping_task.rs +23 -0
- package/packages/pegboard-gateway/src/shared_state.rs +588 -0
- package/packages/pegboard-gateway/src/tunnel_to_ws_task.rs +85 -0
- package/packages/pegboard-gateway/src/ws_to_tunnel_task.rs +65 -0
- package/packages/pegboard-runner/Cargo.toml +38 -0
- package/packages/pegboard-runner/src/conn.rs +183 -0
- package/packages/pegboard-runner/src/errors.rs +33 -0
- package/packages/pegboard-runner/src/lib.rs +249 -0
- package/packages/pegboard-runner/src/ping_task.rs +66 -0
- package/packages/pegboard-runner/src/tunnel_to_ws_task.rs +137 -0
- package/packages/pegboard-runner/src/utils.rs +40 -0
- package/packages/pegboard-runner/src/ws_to_tunnel_task.rs +443 -0
- package/packages/pegboard-serverless/Cargo.toml +25 -0
- package/packages/pegboard-serverless/src/lib.rs +523 -0
- package/packages/pools/Cargo.toml +38 -0
- package/packages/pools/src/db/clickhouse.rs +37 -0
- package/packages/pools/src/db/mod.rs +3 -0
- package/packages/pools/src/db/udb.rs +37 -0
- package/packages/pools/src/db/ups.rs +91 -0
- package/packages/pools/src/error.rs +41 -0
- package/packages/pools/src/lib.rs +16 -0
- package/packages/pools/src/metrics.rs +32 -0
- package/packages/pools/src/pools.rs +114 -0
- package/packages/pools/src/prelude.rs +3 -0
- package/packages/pools/src/reqwest.rs +25 -0
- package/packages/runtime/Cargo.lock +1394 -0
- package/packages/runtime/Cargo.toml +29 -0
- package/packages/runtime/src/lib.rs +154 -0
- package/packages/runtime/src/metrics.rs +34 -0
- package/packages/runtime/src/term_signal.rs +113 -0
- package/packages/runtime/src/traces.rs +158 -0
- package/packages/service-manager/Cargo.toml +19 -0
- package/packages/service-manager/src/lib.rs +359 -0
- package/packages/telemetry/Cargo.toml +13 -0
- package/packages/telemetry/README.md +12 -0
- package/packages/telemetry/src/lib.rs +39 -0
- package/packages/test-deps/Cargo.toml +19 -0
- package/packages/test-deps/src/datacenter.rs +109 -0
- package/packages/test-deps/src/lib.rs +131 -0
- package/packages/test-deps-docker/Cargo.toml +14 -0
- package/packages/test-deps-docker/src/database.rs +135 -0
- package/packages/test-deps-docker/src/lib.rs +280 -0
- package/packages/test-deps-docker/src/pubsub.rs +76 -0
- package/packages/tracing-reconfigure/Cargo.toml +18 -0
- package/packages/tracing-reconfigure/src/lib.rs +78 -0
- package/packages/tracing-utils/Cargo.toml +12 -0
- package/packages/tracing-utils/src/lib.rs +91 -0
- package/packages/types/Cargo.toml +19 -0
- package/packages/types/README.md +3 -0
- package/packages/types/src/actors.rs +79 -0
- package/packages/types/src/datacenters.rs +10 -0
- package/packages/types/src/keys/mod.rs +2 -0
- package/packages/types/src/keys/namespace/mod.rs +1 -0
- package/packages/types/src/keys/namespace/runner_config.rs +28 -0
- package/packages/types/src/keys/pegboard/mod.rs +7 -0
- package/packages/types/src/keys/pegboard/ns.rs +109 -0
- package/packages/types/src/lib.rs +7 -0
- package/packages/types/src/msgs/mod.rs +1 -0
- package/packages/types/src/msgs/pegboard.rs +5 -0
- package/packages/types/src/namespaces.rs +10 -0
- package/packages/types/src/runner_configs.rs +96 -0
- package/packages/types/src/runners.rs +24 -0
- package/packages/universaldb/Cargo.toml +32 -0
- package/packages/universaldb/src/atomic.rs +190 -0
- package/packages/universaldb/src/database.rs +56 -0
- package/packages/universaldb/src/driver/mod.rs +87 -0
- package/packages/universaldb/src/driver/postgres/database.rs +244 -0
- package/packages/universaldb/src/driver/postgres/mod.rs +5 -0
- package/packages/universaldb/src/driver/postgres/transaction.rs +337 -0
- package/packages/universaldb/src/driver/postgres/transaction_task.rs +538 -0
- package/packages/universaldb/src/driver/rocksdb/database.rs +129 -0
- package/packages/universaldb/src/driver/rocksdb/mod.rs +6 -0
- package/packages/universaldb/src/driver/rocksdb/transaction.rs +354 -0
- package/packages/universaldb/src/driver/rocksdb/transaction_conflict_tracker.rs +109 -0
- package/packages/universaldb/src/driver/rocksdb/transaction_task.rs +526 -0
- package/packages/universaldb/src/error.rs +30 -0
- package/packages/universaldb/src/key_selector.rs +97 -0
- package/packages/universaldb/src/lib.rs +24 -0
- package/packages/universaldb/src/metrics.rs +27 -0
- package/packages/universaldb/src/options.rs +284 -0
- package/packages/universaldb/src/prelude.rs +8 -0
- package/packages/universaldb/src/range_option.rs +159 -0
- package/packages/universaldb/src/transaction.rs +378 -0
- package/packages/universaldb/src/tx_ops.rs +425 -0
- package/packages/universaldb/src/utils/cherry_pick.rs +88 -0
- package/packages/universaldb/src/utils/codes.rs +9 -0
- package/packages/universaldb/src/utils/ext.rs +58 -0
- package/packages/universaldb/src/utils/formal_key.rs +23 -0
- package/packages/universaldb/src/utils/keys.rs +134 -0
- package/packages/universaldb/src/utils/mod.rs +92 -0
- package/packages/universaldb/src/utils/subspace.rs +95 -0
- package/packages/universaldb/src/value.rs +159 -0
- package/packages/universaldb/src/versionstamp.rs +173 -0
- package/packages/universaldb/tests/integration.rs +2733 -0
- package/packages/universaldb/tests/integration_gas.rs +264 -0
- package/packages/universaldb/tests/rocksdb.rs +141 -0
- package/packages/universaldb/tests/versionstamp.rs +184 -0
- package/packages/universalpubsub/Cargo.toml +38 -0
- package/packages/universalpubsub/benches/simple.rs +932 -0
- package/packages/universalpubsub/src/chunking.rs +226 -0
- package/packages/universalpubsub/src/driver/memory/mod.rs +91 -0
- package/packages/universalpubsub/src/driver/mod.rs +58 -0
- package/packages/universalpubsub/src/driver/nats/mod.rs +79 -0
- package/packages/universalpubsub/src/driver/postgres/mod.rs +443 -0
- package/packages/universalpubsub/src/errors.rs +11 -0
- package/packages/universalpubsub/src/lib.rs +7 -0
- package/packages/universalpubsub/src/pubsub.rs +415 -0
- package/packages/universalpubsub/tests/integration.rs +441 -0
- package/packages/universalpubsub/tests/reconnect.rs +359 -0
- package/packages/util/Cargo.toml +41 -0
- package/packages/util/build.rs +13 -0
- package/packages/util/src/backoff.rs +109 -0
- package/packages/util/src/billing.rs +3 -0
- package/packages/util/src/build_meta.rs +33 -0
- package/packages/util/src/check.rs +222 -0
- package/packages/util/src/duration.rs +77 -0
- package/packages/util/src/faker.rs +81 -0
- package/packages/util/src/format.rs +185 -0
- package/packages/util/src/future.rs +1 -0
- package/packages/util/src/geo.rs +5 -0
- package/packages/util/src/lib.rs +40 -0
- package/packages/util/src/math.rs +35 -0
- package/packages/util/src/req.rs +41 -0
- package/packages/util/src/serde.rs +516 -0
- package/packages/util/src/size.rs +27 -0
- package/packages/util/src/sort.rs +13 -0
- package/packages/util/src/timestamp.rs +58 -0
- package/packages/util/src/url.rs +3 -0
- package/packages/util-id/Cargo.toml +13 -0
- package/packages/util-id/src/lib.rs +329 -0
- package/packages/workflow-worker/Cargo.toml +16 -0
- package/packages/workflow-worker/src/lib.rs +15 -0
- package/sdks/api/fern/fern.config.json +4 -0
- package/sdks/api/fern/generators.yml +25 -0
- package/sdks/go/api-full/client/client.go +459 -0
- package/sdks/go/api-full/client/client_test.go +43 -0
- package/sdks/go/api-full/client/options.go +39 -0
- package/sdks/go/api-full/core/client_option.go +44 -0
- package/sdks/go/api-full/core/core.go +220 -0
- package/sdks/go/api-full/core/core_test.go +219 -0
- package/sdks/go/api-full/core/stringer.go +13 -0
- package/sdks/go/api-full/datacenters/client.go +50 -0
- package/sdks/go/api-full/go.mod +8 -0
- package/sdks/go/api-full/go.sum +12 -0
- package/sdks/go/api-full/health/client.go +50 -0
- package/sdks/go/api-full/namespaces/client.go +92 -0
- package/sdks/go/api-full/namespaces.go +15 -0
- package/sdks/go/api-full/pointer.go +103 -0
- package/sdks/go/api-full/runners/client.go +111 -0
- package/sdks/go/api-full/runners.go +18 -0
- package/sdks/go/api-full/types.go +1638 -0
- package/sdks/rust/api-full/.openapi-generator/FILES +28 -0
- package/sdks/rust/api-full/.openapi-generator/VERSION +1 -0
- package/sdks/rust/api-full/.openapi-generator-ignore +23 -0
- package/sdks/rust/api-full/.travis.yml +1 -0
- package/sdks/rust/api-full/Cargo.toml +15 -0
- package/sdks/rust/api-full/README.md +53 -0
- package/sdks/rust/api-full/docs/Actor.md +19 -0
- package/sdks/rust/api-full/docs/ActorLifecycle.md +12 -0
- package/sdks/rust/api-full/docs/ActorsApi.md +37 -0
- package/sdks/rust/api-full/docs/ActorsCreateRequest.md +13 -0
- package/sdks/rust/api-full/docs/ActorsCreateResponse.md +11 -0
- package/sdks/rust/api-full/docs/Namespace.md +14 -0
- package/sdks/rust/api-full/docs/NamespacesCreateRequest.md +12 -0
- package/sdks/rust/api-full/docs/NamespacesCreateResponse.md +11 -0
- package/sdks/rust/api-full/docs/NsApi.md +37 -0
- package/sdks/rust/api-full/git_push.sh +57 -0
- package/sdks/rust/api-full/rust/.openapi-generator/FILES +140 -0
- package/sdks/rust/api-full/rust/.openapi-generator/VERSION +1 -0
- package/sdks/rust/api-full/rust/.openapi-generator-ignore +23 -0
- package/sdks/rust/api-full/rust/.travis.yml +1 -0
- package/sdks/rust/api-full/rust/Cargo.toml +15 -0
- package/sdks/rust/api-full/rust/README.md +111 -0
- package/sdks/rust/api-full/rust/docs/Actor.md +24 -0
- package/sdks/rust/api-full/rust/docs/ActorName.md +11 -0
- package/sdks/rust/api-full/rust/docs/ActorsCreateApi.md +40 -0
- package/sdks/rust/api-full/rust/docs/ActorsCreateRequest.md +16 -0
- package/sdks/rust/api-full/rust/docs/ActorsCreateResponse.md +11 -0
- package/sdks/rust/api-full/rust/docs/ActorsDeleteApi.md +40 -0
- package/sdks/rust/api-full/rust/docs/ActorsGetOrCreateApi.md +40 -0
- package/sdks/rust/api-full/rust/docs/ActorsGetOrCreateRequest.md +16 -0
- package/sdks/rust/api-full/rust/docs/ActorsGetOrCreateResponse.md +12 -0
- package/sdks/rust/api-full/rust/docs/ActorsKvGetApi.md +38 -0
- package/sdks/rust/api-full/rust/docs/ActorsKvGetResponse.md +12 -0
- package/sdks/rust/api-full/rust/docs/ActorsListApi.md +45 -0
- package/sdks/rust/api-full/rust/docs/ActorsListNamesApi.md +41 -0
- package/sdks/rust/api-full/rust/docs/ActorsListNamesResponse.md +12 -0
- package/sdks/rust/api-full/rust/docs/ActorsListResponse.md +12 -0
- package/sdks/rust/api-full/rust/docs/CrashPolicy.md +14 -0
- package/sdks/rust/api-full/rust/docs/Datacenter.md +13 -0
- package/sdks/rust/api-full/rust/docs/DatacenterHealth.md +16 -0
- package/sdks/rust/api-full/rust/docs/DatacentersApi.md +34 -0
- package/sdks/rust/api-full/rust/docs/DatacentersListResponse.md +12 -0
- package/sdks/rust/api-full/rust/docs/HealthApi.md +34 -0
- package/sdks/rust/api-full/rust/docs/HealthFanoutResponse.md +11 -0
- package/sdks/rust/api-full/rust/docs/HealthResponse.md +13 -0
- package/sdks/rust/api-full/rust/docs/HealthStatus.md +13 -0
- package/sdks/rust/api-full/rust/docs/Namespace.md +14 -0
- package/sdks/rust/api-full/rust/docs/NamespaceListResponse.md +12 -0
- package/sdks/rust/api-full/rust/docs/NamespacesApi.md +69 -0
- package/sdks/rust/api-full/rust/docs/NamespacesCreateRequest.md +12 -0
- package/sdks/rust/api-full/rust/docs/NamespacesCreateResponse.md +11 -0
- package/sdks/rust/api-full/rust/docs/Pagination.md +11 -0
- package/sdks/rust/api-full/rust/docs/Runner.md +25 -0
- package/sdks/rust/api-full/rust/docs/RunnerConfig.md +13 -0
- package/sdks/rust/api-full/rust/docs/RunnerConfigKind.md +12 -0
- package/sdks/rust/api-full/rust/docs/RunnerConfigKindOneOf.md +11 -0
- package/sdks/rust/api-full/rust/docs/RunnerConfigKindOneOf1.md +11 -0
- package/sdks/rust/api-full/rust/docs/RunnerConfigKindOneOf1Serverless.md +17 -0
- package/sdks/rust/api-full/rust/docs/RunnerConfigVariant.md +13 -0
- package/sdks/rust/api-full/rust/docs/RunnerConfigsDeleteApi.md +38 -0
- package/sdks/rust/api-full/rust/docs/RunnerConfigsListApi.md +41 -0
- package/sdks/rust/api-full/rust/docs/RunnerConfigsListResponse.md +12 -0
- package/sdks/rust/api-full/rust/docs/RunnerConfigsListResponseRunnerConfigsValue.md +11 -0
- package/sdks/rust/api-full/rust/docs/RunnerConfigsRefreshMetadataApi.md +39 -0
- package/sdks/rust/api-full/rust/docs/RunnerConfigsServerlessHealthCheckApi.md +38 -0
- package/sdks/rust/api-full/rust/docs/RunnerConfigsServerlessHealthCheckRequest.md +12 -0
- package/sdks/rust/api-full/rust/docs/RunnerConfigsServerlessHealthCheckResponse.md +12 -0
- package/sdks/rust/api-full/rust/docs/RunnerConfigsServerlessHealthCheckResponseOneOf.md +11 -0
- package/sdks/rust/api-full/rust/docs/RunnerConfigsServerlessHealthCheckResponseOneOf1.md +11 -0
- package/sdks/rust/api-full/rust/docs/RunnerConfigsServerlessHealthCheckResponseOneOf1Failure.md +11 -0
- package/sdks/rust/api-full/rust/docs/RunnerConfigsServerlessHealthCheckResponseOneOfSuccess.md +11 -0
- package/sdks/rust/api-full/rust/docs/RunnerConfigsServerlessMetadataError.md +16 -0
- package/sdks/rust/api-full/rust/docs/RunnerConfigsServerlessMetadataErrorOneOf.md +11 -0
- package/sdks/rust/api-full/rust/docs/RunnerConfigsServerlessMetadataErrorOneOf1.md +11 -0
- package/sdks/rust/api-full/rust/docs/RunnerConfigsServerlessMetadataErrorOneOf2.md +11 -0
- package/sdks/rust/api-full/rust/docs/RunnerConfigsServerlessMetadataErrorOneOf3.md +11 -0
- package/sdks/rust/api-full/rust/docs/RunnerConfigsServerlessMetadataErrorOneOf3NonSuccessStatus.md +12 -0
- package/sdks/rust/api-full/rust/docs/RunnerConfigsServerlessMetadataErrorOneOf4.md +11 -0
- package/sdks/rust/api-full/rust/docs/RunnerConfigsServerlessMetadataErrorOneOf4InvalidResponseJson.md +11 -0
- package/sdks/rust/api-full/rust/docs/RunnerConfigsServerlessMetadataErrorOneOf5.md +11 -0
- package/sdks/rust/api-full/rust/docs/RunnerConfigsServerlessMetadataErrorOneOf5InvalidResponseSchema.md +12 -0
- package/sdks/rust/api-full/rust/docs/RunnerConfigsUpsertApi.md +39 -0
- package/sdks/rust/api-full/rust/docs/RunnerConfigsUpsertRequestBody.md +11 -0
- package/sdks/rust/api-full/rust/docs/RunnerConfigsUpsertResponse.md +11 -0
- package/sdks/rust/api-full/rust/docs/RunnersApi.md +75 -0
- package/sdks/rust/api-full/rust/docs/RunnersListNamesResponse.md +12 -0
- package/sdks/rust/api-full/rust/docs/RunnersListResponse.md +12 -0
- package/sdks/rust/api-full/rust/git_push.sh +57 -0
- package/sdks/rust/api-full/rust/src/apis/actors_create_api.rs +68 -0
- package/sdks/rust/api-full/rust/src/apis/actors_delete_api.rs +69 -0
- package/sdks/rust/api-full/rust/src/apis/actors_get_or_create_api.rs +68 -0
- package/sdks/rust/api-full/rust/src/apis/actors_kv_get_api.rs +65 -0
- package/sdks/rust/api-full/rust/src/apis/actors_list_api.rs +90 -0
- package/sdks/rust/api-full/rust/src/apis/actors_list_names_api.rs +74 -0
- package/sdks/rust/api-full/rust/src/apis/configuration.rs +51 -0
- package/sdks/rust/api-full/rust/src/apis/datacenters_api.rs +62 -0
- package/sdks/rust/api-full/rust/src/apis/health_api.rs +62 -0
- package/sdks/rust/api-full/rust/src/apis/mod.rs +130 -0
- package/sdks/rust/api-full/rust/src/apis/namespaces_api.rs +126 -0
- package/sdks/rust/api-full/rust/src/apis/runner_configs_delete_api.rs +66 -0
- package/sdks/rust/api-full/rust/src/apis/runner_configs_list_api.rs +81 -0
- package/sdks/rust/api-full/rust/src/apis/runner_configs_refresh_metadata_api.rs +68 -0
- package/sdks/rust/api-full/rust/src/apis/runner_configs_serverless_health_check_api.rs +67 -0
- package/sdks/rust/api-full/rust/src/apis/runner_configs_upsert_api.rs +68 -0
- package/sdks/rust/api-full/rust/src/apis/runners_api.rs +141 -0
- package/sdks/rust/api-full/rust/src/lib.rs +11 -0
- package/sdks/rust/api-full/rust/src/models/actor.rs +73 -0
- package/sdks/rust/api-full/rust/src/models/actor_name.rs +27 -0
- package/sdks/rust/api-full/rust/src/models/actors_create_request.rs +42 -0
- package/sdks/rust/api-full/rust/src/models/actors_create_response.rs +27 -0
- package/sdks/rust/api-full/rust/src/models/actors_get_or_create_request.rs +42 -0
- package/sdks/rust/api-full/rust/src/models/actors_get_or_create_response.rs +30 -0
- package/sdks/rust/api-full/rust/src/models/actors_kv_get_response.rs +30 -0
- package/sdks/rust/api-full/rust/src/models/actors_list_names_response.rs +30 -0
- package/sdks/rust/api-full/rust/src/models/actors_list_response.rs +30 -0
- package/sdks/rust/api-full/rust/src/models/crash_policy.rs +41 -0
- package/sdks/rust/api-full/rust/src/models/datacenter.rs +33 -0
- package/sdks/rust/api-full/rust/src/models/datacenter_health.rs +42 -0
- package/sdks/rust/api-full/rust/src/models/datacenters_list_response.rs +30 -0
- package/sdks/rust/api-full/rust/src/models/health_fanout_response.rs +27 -0
- package/sdks/rust/api-full/rust/src/models/health_response.rs +33 -0
- package/sdks/rust/api-full/rust/src/models/health_status.rs +38 -0
- package/sdks/rust/api-full/rust/src/models/mod.rs +100 -0
- package/sdks/rust/api-full/rust/src/models/namespace.rs +36 -0
- package/sdks/rust/api-full/rust/src/models/namespace_list_response.rs +30 -0
- package/sdks/rust/api-full/rust/src/models/namespaces_create_request.rs +30 -0
- package/sdks/rust/api-full/rust/src/models/namespaces_create_response.rs +27 -0
- package/sdks/rust/api-full/rust/src/models/pagination.rs +27 -0
- package/sdks/rust/api-full/rust/src/models/runner.rs +69 -0
- package/sdks/rust/api-full/rust/src/models/runner_config.rs +33 -0
- package/sdks/rust/api-full/rust/src/models/runner_config_kind.rs +26 -0
- package/sdks/rust/api-full/rust/src/models/runner_config_kind_one_of.rs +27 -0
- package/sdks/rust/api-full/rust/src/models/runner_config_kind_one_of_1.rs +27 -0
- package/sdks/rust/api-full/rust/src/models/runner_config_kind_one_of_1_serverless.rs +46 -0
- package/sdks/rust/api-full/rust/src/models/runner_config_variant.rs +38 -0
- package/sdks/rust/api-full/rust/src/models/runner_configs_list_response.rs +30 -0
- package/sdks/rust/api-full/rust/src/models/runner_configs_list_response_runner_configs_value.rs +27 -0
- package/sdks/rust/api-full/rust/src/models/runner_configs_serverless_health_check_request.rs +30 -0
- package/sdks/rust/api-full/rust/src/models/runner_configs_serverless_health_check_response.rs +26 -0
- package/sdks/rust/api-full/rust/src/models/runner_configs_serverless_health_check_response_one_of.rs +27 -0
- package/sdks/rust/api-full/rust/src/models/runner_configs_serverless_health_check_response_one_of_1.rs +27 -0
- package/sdks/rust/api-full/rust/src/models/runner_configs_serverless_health_check_response_one_of_1_failure.rs +27 -0
- package/sdks/rust/api-full/rust/src/models/runner_configs_serverless_health_check_response_one_of_success.rs +27 -0
- package/sdks/rust/api-full/rust/src/models/runner_configs_serverless_metadata_error.rs +30 -0
- package/sdks/rust/api-full/rust/src/models/runner_configs_serverless_metadata_error_one_of.rs +27 -0
- package/sdks/rust/api-full/rust/src/models/runner_configs_serverless_metadata_error_one_of_1.rs +27 -0
- package/sdks/rust/api-full/rust/src/models/runner_configs_serverless_metadata_error_one_of_2.rs +27 -0
- package/sdks/rust/api-full/rust/src/models/runner_configs_serverless_metadata_error_one_of_3.rs +27 -0
- package/sdks/rust/api-full/rust/src/models/runner_configs_serverless_metadata_error_one_of_3_non_success_status.rs +30 -0
- package/sdks/rust/api-full/rust/src/models/runner_configs_serverless_metadata_error_one_of_4.rs +27 -0
- package/sdks/rust/api-full/rust/src/models/runner_configs_serverless_metadata_error_one_of_4_invalid_response_json.rs +27 -0
- package/sdks/rust/api-full/rust/src/models/runner_configs_serverless_metadata_error_one_of_5.rs +27 -0
- package/sdks/rust/api-full/rust/src/models/runner_configs_serverless_metadata_error_one_of_5_invalid_response_schema.rs +30 -0
- package/sdks/rust/api-full/rust/src/models/runner_configs_upsert_request_body.rs +27 -0
- package/sdks/rust/api-full/rust/src/models/runner_configs_upsert_response.rs +27 -0
- package/sdks/rust/api-full/rust/src/models/runners_list_names_response.rs +30 -0
- package/sdks/rust/api-full/rust/src/models/runners_list_response.rs +30 -0
- package/sdks/rust/api-full/src/apis/actors_api.rs +67 -0
- package/sdks/rust/api-full/src/apis/configuration.rs +48 -0
- package/sdks/rust/api-full/src/apis/mod.rs +119 -0
- package/sdks/rust/api-full/src/apis/ns_api.rs +67 -0
- package/sdks/rust/api-full/src/lib.rs +11 -0
- package/sdks/rust/api-full/src/models/actor.rs +72 -0
- package/sdks/rust/api-full/src/models/actor_lifecycle.rs +29 -0
- package/sdks/rust/api-full/src/models/actors_create_request.rs +36 -0
- package/sdks/rust/api-full/src/models/actors_create_response.rs +26 -0
- package/sdks/rust/api-full/src/models/mod.rs +14 -0
- package/sdks/rust/api-full/src/models/namespace.rs +40 -0
- package/sdks/rust/api-full/src/models/namespaces_create_request.rs +26 -0
- package/sdks/rust/api-full/src/models/namespaces_create_response.rs +26 -0
- package/sdks/rust/data/Cargo.toml +18 -0
- package/sdks/rust/data/build.rs +15 -0
- package/sdks/rust/data/src/converted.rs +137 -0
- package/sdks/rust/data/src/generated.rs +1 -0
- package/sdks/rust/data/src/lib.rs +11 -0
- package/sdks/rust/data/src/versioned/mod.rs +178 -0
- package/sdks/rust/data/src/versioned/namespace_runner_config.rs +125 -0
- package/sdks/rust/epoxy-protocol/Cargo.toml +17 -0
- package/sdks/rust/epoxy-protocol/build.rs +18 -0
- package/sdks/rust/epoxy-protocol/src/generated.rs +1 -0
- package/sdks/rust/epoxy-protocol/src/lib.rs +7 -0
- package/sdks/rust/epoxy-protocol/src/versioned.rs +206 -0
- package/sdks/rust/runner-protocol/Cargo.toml +23 -0
- package/sdks/rust/runner-protocol/build.rs +115 -0
- package/sdks/rust/runner-protocol/src/compat.rs +7 -0
- package/sdks/rust/runner-protocol/src/generated.rs +1 -0
- package/sdks/rust/runner-protocol/src/lib.rs +10 -0
- package/sdks/rust/runner-protocol/src/util.rs +14 -0
- package/sdks/rust/runner-protocol/src/uuid_compat.rs +209 -0
- package/sdks/rust/runner-protocol/src/versioned.rs +1734 -0
- package/sdks/rust/ups-protocol/Cargo.toml +17 -0
- package/sdks/rust/ups-protocol/build.rs +18 -0
- package/sdks/rust/ups-protocol/src/generated.rs +1 -0
- package/sdks/rust/ups-protocol/src/lib.rs +7 -0
- package/sdks/rust/ups-protocol/src/versioned.rs +48 -0
- package/sdks/schemas/README.md +6 -0
- package/sdks/schemas/data/namespace.runner_config.v1.bare +13 -0
- package/sdks/schemas/data/namespace.runner_config.v2.bare +23 -0
- package/sdks/schemas/data/pegboard.namespace.actor_by_key.v1.bare +6 -0
- package/sdks/schemas/data/pegboard.namespace.actor_name.v1.bare +5 -0
- package/sdks/schemas/data/pegboard.namespace.runner_alloc_idx.v1.bare +7 -0
- package/sdks/schemas/data/pegboard.namespace.runner_by_key.v1.bare +6 -0
- package/sdks/schemas/data/pegboard.runner.metadata.v1.bare +5 -0
- package/sdks/schemas/epoxy-protocol/v1.bare +260 -0
- package/sdks/schemas/runner-protocol/v1.bare +393 -0
- package/sdks/schemas/runner-protocol/v2.bare +403 -0
- package/sdks/schemas/runner-protocol/v3.bare +436 -0
- package/sdks/schemas/ups-protocol/v1.bare +23 -0
- package/sdks/typescript/api-full/.turbo/turbo-build.log +42 -0
- package/sdks/typescript/api-full/build.js +69 -0
- package/sdks/typescript/api-full/package.json +59 -0
- package/sdks/typescript/api-full/rivetkit-engine-api-full-25.5.3.tgz +0 -0
- package/sdks/typescript/api-full/src/Client.ts +984 -0
- package/sdks/typescript/api-full/src/api/client/index.ts +1 -0
- package/sdks/typescript/api-full/src/api/client/requests/ActorsCreateRequest.ts +24 -0
- package/sdks/typescript/api-full/src/api/client/requests/ActorsDeleteRequest.ts +11 -0
- package/sdks/typescript/api-full/src/api/client/requests/ActorsGetOrCreateRequest.ts +25 -0
- package/sdks/typescript/api-full/src/api/client/requests/ActorsListNamesRequest.ts +15 -0
- package/sdks/typescript/api-full/src/api/client/requests/ActorsListRequest.ts +19 -0
- package/sdks/typescript/api-full/src/api/client/requests/RunnerConfigsDeleteRequest.ts +13 -0
- package/sdks/typescript/api-full/src/api/client/requests/RunnerConfigsListRequest.ts +19 -0
- package/sdks/typescript/api-full/src/api/client/requests/RunnerConfigsRefreshMetadataRequest.ts +19 -0
- package/sdks/typescript/api-full/src/api/client/requests/RunnerConfigsServerlessHealthCheckRequest.ts +16 -0
- package/sdks/typescript/api-full/src/api/client/requests/RunnerConfigsUpsertRequestBody.ts +19 -0
- package/sdks/typescript/api-full/src/api/client/requests/index.ts +10 -0
- package/sdks/typescript/api-full/src/api/index.ts +3 -0
- package/sdks/typescript/api-full/src/api/resources/datacenters/client/Client.ts +97 -0
- package/sdks/typescript/api-full/src/api/resources/datacenters/client/index.ts +1 -0
- package/sdks/typescript/api-full/src/api/resources/datacenters/index.ts +1 -0
- package/sdks/typescript/api-full/src/api/resources/health/client/Client.ts +97 -0
- package/sdks/typescript/api-full/src/api/resources/health/client/index.ts +1 -0
- package/sdks/typescript/api-full/src/api/resources/health/index.ts +1 -0
- package/sdks/typescript/api-full/src/api/resources/index.ts +6 -0
- package/sdks/typescript/api-full/src/api/resources/namespaces/client/Client.ts +187 -0
- package/sdks/typescript/api-full/src/api/resources/namespaces/client/index.ts +1 -0
- package/sdks/typescript/api-full/src/api/resources/namespaces/client/requests/NamespacesCreateRequest.ts +15 -0
- package/sdks/typescript/api-full/src/api/resources/namespaces/client/requests/NamespacesListRequest.ts +14 -0
- package/sdks/typescript/api-full/src/api/resources/namespaces/client/requests/index.ts +2 -0
- package/sdks/typescript/api-full/src/api/resources/namespaces/index.ts +1 -0
- package/sdks/typescript/api-full/src/api/resources/runners/client/Client.ts +209 -0
- package/sdks/typescript/api-full/src/api/resources/runners/client/index.ts +1 -0
- package/sdks/typescript/api-full/src/api/resources/runners/client/requests/RunnersListNamesRequest.ts +15 -0
- package/sdks/typescript/api-full/src/api/resources/runners/client/requests/RunnersListRequest.ts +18 -0
- package/sdks/typescript/api-full/src/api/resources/runners/client/requests/index.ts +2 -0
- package/sdks/typescript/api-full/src/api/resources/runners/index.ts +1 -0
- package/sdks/typescript/api-full/src/api/types/Actor.ts +32 -0
- package/sdks/typescript/api-full/src/api/types/ActorName.ts +7 -0
- package/sdks/typescript/api-full/src/api/types/ActorsCreateResponse.ts +9 -0
- package/sdks/typescript/api-full/src/api/types/ActorsDeleteResponse.ts +5 -0
- package/sdks/typescript/api-full/src/api/types/ActorsGetOrCreateResponse.ts +10 -0
- package/sdks/typescript/api-full/src/api/types/ActorsKvGetResponse.ts +8 -0
- package/sdks/typescript/api-full/src/api/types/ActorsListNamesResponse.ts +10 -0
- package/sdks/typescript/api-full/src/api/types/ActorsListResponse.ts +10 -0
- package/sdks/typescript/api-full/src/api/types/CrashPolicy.ts +10 -0
- package/sdks/typescript/api-full/src/api/types/Datacenter.ts +9 -0
- package/sdks/typescript/api-full/src/api/types/DatacenterHealth.ts +14 -0
- package/sdks/typescript/api-full/src/api/types/DatacentersListResponse.ts +10 -0
- package/sdks/typescript/api-full/src/api/types/HealthFanoutResponse.ts +9 -0
- package/sdks/typescript/api-full/src/api/types/HealthResponse.ts +9 -0
- package/sdks/typescript/api-full/src/api/types/HealthStatus.ts +9 -0
- package/sdks/typescript/api-full/src/api/types/Namespace.ts +12 -0
- package/sdks/typescript/api-full/src/api/types/NamespaceListResponse.ts +10 -0
- package/sdks/typescript/api-full/src/api/types/NamespacesCreateResponse.ts +9 -0
- package/sdks/typescript/api-full/src/api/types/Pagination.ts +7 -0
- package/sdks/typescript/api-full/src/api/types/RivetId.ts +5 -0
- package/sdks/typescript/api-full/src/api/types/Runner.ts +23 -0
- package/sdks/typescript/api-full/src/api/types/RunnerConfig.ts +11 -0
- package/sdks/typescript/api-full/src/api/types/RunnerConfigKind.ts +7 -0
- package/sdks/typescript/api-full/src/api/types/RunnerConfigKindNormal.ts +7 -0
- package/sdks/typescript/api-full/src/api/types/RunnerConfigKindServerless.ts +9 -0
- package/sdks/typescript/api-full/src/api/types/RunnerConfigKindServerlessServerless.ts +14 -0
- package/sdks/typescript/api-full/src/api/types/RunnerConfigServerless.ts +14 -0
- package/sdks/typescript/api-full/src/api/types/RunnerConfigVariant.ts +9 -0
- package/sdks/typescript/api-full/src/api/types/RunnerConfigsDeleteResponse.ts +5 -0
- package/sdks/typescript/api-full/src/api/types/RunnerConfigsListResponse.ts +10 -0
- package/sdks/typescript/api-full/src/api/types/RunnerConfigsListResponseRunnerConfigsValue.ts +9 -0
- package/sdks/typescript/api-full/src/api/types/RunnerConfigsRefreshMetadataRequestBody.ts +5 -0
- package/sdks/typescript/api-full/src/api/types/RunnerConfigsRefreshMetadataResponse.ts +5 -0
- package/sdks/typescript/api-full/src/api/types/RunnerConfigsServerlessHealthCheckResponse.ts +9 -0
- package/sdks/typescript/api-full/src/api/types/RunnerConfigsServerlessHealthCheckResponseFailure.ts +9 -0
- package/sdks/typescript/api-full/src/api/types/RunnerConfigsServerlessHealthCheckResponseFailureFailure.ts +9 -0
- package/sdks/typescript/api-full/src/api/types/RunnerConfigsServerlessHealthCheckResponseSuccess.ts +9 -0
- package/sdks/typescript/api-full/src/api/types/RunnerConfigsServerlessHealthCheckResponseSuccessSuccess.ts +7 -0
- package/sdks/typescript/api-full/src/api/types/RunnerConfigsServerlessMetadataError.ts +13 -0
- package/sdks/typescript/api-full/src/api/types/RunnerConfigsServerlessMetadataErrorInvalidRequest.ts +7 -0
- package/sdks/typescript/api-full/src/api/types/RunnerConfigsServerlessMetadataErrorInvalidResponseJson.ts +9 -0
- package/sdks/typescript/api-full/src/api/types/RunnerConfigsServerlessMetadataErrorInvalidResponseJsonInvalidResponseJson.ts +7 -0
- package/sdks/typescript/api-full/src/api/types/RunnerConfigsServerlessMetadataErrorInvalidResponseSchema.ts +9 -0
- package/sdks/typescript/api-full/src/api/types/RunnerConfigsServerlessMetadataErrorInvalidResponseSchemaInvalidResponseSchema.ts +8 -0
- package/sdks/typescript/api-full/src/api/types/RunnerConfigsServerlessMetadataErrorNonSuccessStatus.ts +9 -0
- package/sdks/typescript/api-full/src/api/types/RunnerConfigsServerlessMetadataErrorNonSuccessStatusNonSuccessStatus.ts +8 -0
- package/sdks/typescript/api-full/src/api/types/RunnerConfigsServerlessMetadataErrorRequestFailed.ts +7 -0
- package/sdks/typescript/api-full/src/api/types/RunnerConfigsServerlessMetadataErrorRequestTimedOut.ts +7 -0
- package/sdks/typescript/api-full/src/api/types/RunnerConfigsUpsertResponse.ts +7 -0
- package/sdks/typescript/api-full/src/api/types/RunnersListNamesResponse.ts +10 -0
- package/sdks/typescript/api-full/src/api/types/RunnersListResponse.ts +10 -0
- package/sdks/typescript/api-full/src/api/types/index.ts +51 -0
- package/sdks/typescript/api-full/src/core/auth/BasicAuth.ts +31 -0
- package/sdks/typescript/api-full/src/core/auth/BearerToken.ts +15 -0
- package/sdks/typescript/api-full/src/core/auth/index.ts +2 -0
- package/sdks/typescript/api-full/src/core/fetcher/APIResponse.ts +12 -0
- package/sdks/typescript/api-full/src/core/fetcher/Fetcher.ts +144 -0
- package/sdks/typescript/api-full/src/core/fetcher/Supplier.ts +11 -0
- package/sdks/typescript/api-full/src/core/fetcher/createRequestUrl.ts +10 -0
- package/sdks/typescript/api-full/src/core/fetcher/getFetchFn.ts +25 -0
- package/sdks/typescript/api-full/src/core/fetcher/getHeader.ts +8 -0
- package/sdks/typescript/api-full/src/core/fetcher/getRequestBody.ts +16 -0
- package/sdks/typescript/api-full/src/core/fetcher/getResponseBody.ts +34 -0
- package/sdks/typescript/api-full/src/core/fetcher/index.ts +5 -0
- package/sdks/typescript/api-full/src/core/fetcher/makeRequest.ts +44 -0
- package/sdks/typescript/api-full/src/core/fetcher/requestWithRetries.ts +33 -0
- package/sdks/typescript/api-full/src/core/fetcher/signals.ts +38 -0
- package/sdks/typescript/api-full/src/core/fetcher/stream-wrappers/Node18UniversalStreamWrapper.ts +257 -0
- package/sdks/typescript/api-full/src/core/fetcher/stream-wrappers/NodePre18StreamWrapper.ts +107 -0
- package/sdks/typescript/api-full/src/core/fetcher/stream-wrappers/UndiciStreamWrapper.ts +243 -0
- package/sdks/typescript/api-full/src/core/fetcher/stream-wrappers/chooseStreamWrapper.ts +34 -0
- package/sdks/typescript/api-full/src/core/index.ts +4 -0
- package/sdks/typescript/api-full/src/core/json.ts +27 -0
- package/sdks/typescript/api-full/src/core/runtime/index.ts +1 -0
- package/sdks/typescript/api-full/src/core/runtime/runtime.ts +131 -0
- package/sdks/typescript/api-full/src/core/schemas/Schema.ts +101 -0
- package/sdks/typescript/api-full/src/core/schemas/builders/bigint/bigint.ts +55 -0
- package/sdks/typescript/api-full/src/core/schemas/builders/bigint/index.ts +1 -0
- package/sdks/typescript/api-full/src/core/schemas/builders/date/date.ts +65 -0
- package/sdks/typescript/api-full/src/core/schemas/builders/date/index.ts +1 -0
- package/sdks/typescript/api-full/src/core/schemas/builders/enum/enum.ts +43 -0
- package/sdks/typescript/api-full/src/core/schemas/builders/enum/index.ts +1 -0
- package/sdks/typescript/api-full/src/core/schemas/builders/index.ts +14 -0
- package/sdks/typescript/api-full/src/core/schemas/builders/lazy/index.ts +3 -0
- package/sdks/typescript/api-full/src/core/schemas/builders/lazy/lazy.ts +32 -0
- package/sdks/typescript/api-full/src/core/schemas/builders/lazy/lazyObject.ts +20 -0
- package/sdks/typescript/api-full/src/core/schemas/builders/list/index.ts +1 -0
- package/sdks/typescript/api-full/src/core/schemas/builders/list/list.ts +73 -0
- package/sdks/typescript/api-full/src/core/schemas/builders/literals/booleanLiteral.ts +29 -0
- package/sdks/typescript/api-full/src/core/schemas/builders/literals/index.ts +2 -0
- package/sdks/typescript/api-full/src/core/schemas/builders/literals/stringLiteral.ts +29 -0
- package/sdks/typescript/api-full/src/core/schemas/builders/object/index.ts +22 -0
- package/sdks/typescript/api-full/src/core/schemas/builders/object/object.ts +366 -0
- package/sdks/typescript/api-full/src/core/schemas/builders/object/objectWithoutOptionalProperties.ts +18 -0
- package/sdks/typescript/api-full/src/core/schemas/builders/object/property.ts +23 -0
- package/sdks/typescript/api-full/src/core/schemas/builders/object/types.ts +58 -0
- package/sdks/typescript/api-full/src/core/schemas/builders/object-like/getObjectLikeUtils.ts +79 -0
- package/sdks/typescript/api-full/src/core/schemas/builders/object-like/index.ts +2 -0
- package/sdks/typescript/api-full/src/core/schemas/builders/object-like/types.ts +11 -0
- package/sdks/typescript/api-full/src/core/schemas/builders/primitives/any.ts +4 -0
- package/sdks/typescript/api-full/src/core/schemas/builders/primitives/boolean.ts +25 -0
- package/sdks/typescript/api-full/src/core/schemas/builders/primitives/index.ts +5 -0
- package/sdks/typescript/api-full/src/core/schemas/builders/primitives/number.ts +25 -0
- package/sdks/typescript/api-full/src/core/schemas/builders/primitives/string.ts +25 -0
- package/sdks/typescript/api-full/src/core/schemas/builders/primitives/unknown.ts +4 -0
- package/sdks/typescript/api-full/src/core/schemas/builders/record/index.ts +2 -0
- package/sdks/typescript/api-full/src/core/schemas/builders/record/record.ts +129 -0
- package/sdks/typescript/api-full/src/core/schemas/builders/record/types.ts +17 -0
- package/sdks/typescript/api-full/src/core/schemas/builders/schema-utils/JsonError.ts +9 -0
- package/sdks/typescript/api-full/src/core/schemas/builders/schema-utils/ParseError.ts +9 -0
- package/sdks/typescript/api-full/src/core/schemas/builders/schema-utils/getSchemaUtils.ts +181 -0
- package/sdks/typescript/api-full/src/core/schemas/builders/schema-utils/index.ts +4 -0
- package/sdks/typescript/api-full/src/core/schemas/builders/schema-utils/stringifyValidationErrors.ts +8 -0
- package/sdks/typescript/api-full/src/core/schemas/builders/set/index.ts +1 -0
- package/sdks/typescript/api-full/src/core/schemas/builders/set/set.ts +43 -0
- package/sdks/typescript/api-full/src/core/schemas/builders/undiscriminated-union/index.ts +6 -0
- package/sdks/typescript/api-full/src/core/schemas/builders/undiscriminated-union/types.ts +10 -0
- package/sdks/typescript/api-full/src/core/schemas/builders/undiscriminated-union/undiscriminatedUnion.ts +60 -0
- package/sdks/typescript/api-full/src/core/schemas/builders/union/discriminant.ts +14 -0
- package/sdks/typescript/api-full/src/core/schemas/builders/union/index.ts +10 -0
- package/sdks/typescript/api-full/src/core/schemas/builders/union/types.ts +26 -0
- package/sdks/typescript/api-full/src/core/schemas/builders/union/union.ts +170 -0
- package/sdks/typescript/api-full/src/core/schemas/index.ts +2 -0
- package/sdks/typescript/api-full/src/core/schemas/utils/MaybePromise.ts +1 -0
- package/sdks/typescript/api-full/src/core/schemas/utils/addQuestionMarksToNullableProperties.ts +9 -0
- package/sdks/typescript/api-full/src/core/schemas/utils/createIdentitySchemaCreator.ts +21 -0
- package/sdks/typescript/api-full/src/core/schemas/utils/entries.ts +3 -0
- package/sdks/typescript/api-full/src/core/schemas/utils/filterObject.ts +13 -0
- package/sdks/typescript/api-full/src/core/schemas/utils/getErrorMessageForIncorrectType.ts +25 -0
- package/sdks/typescript/api-full/src/core/schemas/utils/isPlainObject.ts +17 -0
- package/sdks/typescript/api-full/src/core/schemas/utils/keys.ts +3 -0
- package/sdks/typescript/api-full/src/core/schemas/utils/maybeSkipValidation.ts +38 -0
- package/sdks/typescript/api-full/src/core/schemas/utils/partition.ts +12 -0
- package/sdks/typescript/api-full/src/errors/RivetError.ts +47 -0
- package/sdks/typescript/api-full/src/errors/RivetTimeoutError.ts +10 -0
- package/sdks/typescript/api-full/src/errors/index.ts +2 -0
- package/sdks/typescript/api-full/src/index.ts +4 -0
- package/sdks/typescript/api-full/src/serialization/client/index.ts +1 -0
- package/sdks/typescript/api-full/src/serialization/client/requests/ActorsCreateRequest.ts +31 -0
- package/sdks/typescript/api-full/src/serialization/client/requests/ActorsGetOrCreateRequest.ts +31 -0
- package/sdks/typescript/api-full/src/serialization/client/requests/RunnerConfigsServerlessHealthCheckRequest.ts +22 -0
- package/sdks/typescript/api-full/src/serialization/client/requests/RunnerConfigsUpsertRequestBody.ts +21 -0
- package/sdks/typescript/api-full/src/serialization/client/requests/index.ts +4 -0
- package/sdks/typescript/api-full/src/serialization/index.ts +3 -0
- package/sdks/typescript/api-full/src/serialization/resources/index.ts +2 -0
- package/sdks/typescript/api-full/src/serialization/resources/namespaces/client/index.ts +1 -0
- package/sdks/typescript/api-full/src/serialization/resources/namespaces/client/requests/NamespacesCreateRequest.ts +22 -0
- package/sdks/typescript/api-full/src/serialization/resources/namespaces/client/requests/index.ts +1 -0
- package/sdks/typescript/api-full/src/serialization/resources/namespaces/index.ts +1 -0
- package/sdks/typescript/api-full/src/serialization/types/Actor.ts +45 -0
- package/sdks/typescript/api-full/src/serialization/types/ActorName.ts +18 -0
- package/sdks/typescript/api-full/src/serialization/types/ActorsCreateResponse.ts +21 -0
- package/sdks/typescript/api-full/src/serialization/types/ActorsDeleteResponse.ts +16 -0
- package/sdks/typescript/api-full/src/serialization/types/ActorsGetOrCreateResponse.ts +23 -0
- package/sdks/typescript/api-full/src/serialization/types/ActorsKvGetResponse.ts +22 -0
- package/sdks/typescript/api-full/src/serialization/types/ActorsListNamesResponse.ts +24 -0
- package/sdks/typescript/api-full/src/serialization/types/ActorsListResponse.ts +24 -0
- package/sdks/typescript/api-full/src/serialization/types/CrashPolicy.ts +14 -0
- package/sdks/typescript/api-full/src/serialization/types/Datacenter.ts +22 -0
- package/sdks/typescript/api-full/src/serialization/types/DatacenterHealth.ts +32 -0
- package/sdks/typescript/api-full/src/serialization/types/DatacentersListResponse.ts +24 -0
- package/sdks/typescript/api-full/src/serialization/types/HealthFanoutResponse.ts +21 -0
- package/sdks/typescript/api-full/src/serialization/types/HealthResponse.ts +22 -0
- package/sdks/typescript/api-full/src/serialization/types/HealthStatus.ts +14 -0
- package/sdks/typescript/api-full/src/serialization/types/Namespace.ts +25 -0
- package/sdks/typescript/api-full/src/serialization/types/NamespaceListResponse.ts +24 -0
- package/sdks/typescript/api-full/src/serialization/types/NamespacesCreateResponse.ts +21 -0
- package/sdks/typescript/api-full/src/serialization/types/Pagination.ts +18 -0
- package/sdks/typescript/api-full/src/serialization/types/RivetId.ts +13 -0
- package/sdks/typescript/api-full/src/serialization/types/Runner.ts +46 -0
- package/sdks/typescript/api-full/src/serialization/types/RunnerConfig.ts +23 -0
- package/sdks/typescript/api-full/src/serialization/types/RunnerConfigKind.ts +16 -0
- package/sdks/typescript/api-full/src/serialization/types/RunnerConfigKindNormal.ts +20 -0
- package/sdks/typescript/api-full/src/serialization/types/RunnerConfigKindServerless.ts +21 -0
- package/sdks/typescript/api-full/src/serialization/types/RunnerConfigKindServerlessServerless.ts +32 -0
- package/sdks/typescript/api-full/src/serialization/types/RunnerConfigServerless.ts +32 -0
- package/sdks/typescript/api-full/src/serialization/types/RunnerConfigVariant.ts +16 -0
- package/sdks/typescript/api-full/src/serialization/types/RunnerConfigsDeleteResponse.ts +16 -0
- package/sdks/typescript/api-full/src/serialization/types/RunnerConfigsListResponse.ts +27 -0
- package/sdks/typescript/api-full/src/serialization/types/RunnerConfigsListResponseRunnerConfigsValue.ts +21 -0
- package/sdks/typescript/api-full/src/serialization/types/RunnerConfigsRefreshMetadataRequestBody.ts +16 -0
- package/sdks/typescript/api-full/src/serialization/types/RunnerConfigsRefreshMetadataResponse.ts +16 -0
- package/sdks/typescript/api-full/src/serialization/types/RunnerConfigsServerlessHealthCheckResponse.ts +23 -0
- package/sdks/typescript/api-full/src/serialization/types/RunnerConfigsServerlessHealthCheckResponseFailure.ts +21 -0
- package/sdks/typescript/api-full/src/serialization/types/RunnerConfigsServerlessHealthCheckResponseFailureFailure.ts +21 -0
- package/sdks/typescript/api-full/src/serialization/types/RunnerConfigsServerlessHealthCheckResponseSuccess.ts +21 -0
- package/sdks/typescript/api-full/src/serialization/types/RunnerConfigsServerlessHealthCheckResponseSuccessSuccess.ts +20 -0
- package/sdks/typescript/api-full/src/serialization/types/RunnerConfigsServerlessMetadataError.ts +35 -0
- package/sdks/typescript/api-full/src/serialization/types/RunnerConfigsServerlessMetadataErrorInvalidRequest.ts +23 -0
- package/sdks/typescript/api-full/src/serialization/types/RunnerConfigsServerlessMetadataErrorInvalidResponseJson.ts +24 -0
- package/sdks/typescript/api-full/src/serialization/types/RunnerConfigsServerlessMetadataErrorInvalidResponseJsonInvalidResponseJson.ts +20 -0
- package/sdks/typescript/api-full/src/serialization/types/RunnerConfigsServerlessMetadataErrorInvalidResponseSchema.ts +24 -0
- package/sdks/typescript/api-full/src/serialization/types/RunnerConfigsServerlessMetadataErrorInvalidResponseSchemaInvalidResponseSchema.ts +22 -0
- package/sdks/typescript/api-full/src/serialization/types/RunnerConfigsServerlessMetadataErrorNonSuccessStatus.ts +24 -0
- package/sdks/typescript/api-full/src/serialization/types/RunnerConfigsServerlessMetadataErrorNonSuccessStatusNonSuccessStatus.ts +22 -0
- package/sdks/typescript/api-full/src/serialization/types/RunnerConfigsServerlessMetadataErrorRequestFailed.ts +23 -0
- package/sdks/typescript/api-full/src/serialization/types/RunnerConfigsServerlessMetadataErrorRequestTimedOut.ts +23 -0
- package/sdks/typescript/api-full/src/serialization/types/RunnerConfigsUpsertResponse.ts +20 -0
- package/sdks/typescript/api-full/src/serialization/types/RunnersListNamesResponse.ts +23 -0
- package/sdks/typescript/api-full/src/serialization/types/RunnersListResponse.ts +24 -0
- package/sdks/typescript/api-full/src/serialization/types/index.ts +51 -0
- package/sdks/typescript/api-full/tsconfig.json +24 -0
- package/sdks/typescript/runner/.turbo/turbo-build.log +22 -0
- package/sdks/typescript/runner/benches/actor-lifecycle.bench.ts +190 -0
- package/sdks/typescript/runner/benches/utils.ts +143 -0
- package/sdks/typescript/runner/dist/mod.cjs +2951 -0
- package/sdks/typescript/runner/dist/mod.cjs.map +1 -0
- package/sdks/typescript/runner/dist/mod.d.cts +326 -0
- package/sdks/typescript/runner/dist/mod.d.ts +326 -0
- package/sdks/typescript/runner/dist/mod.js +2951 -0
- package/sdks/typescript/runner/dist/mod.js.map +1 -0
- package/sdks/typescript/runner/node_modules/.bin/pino +21 -0
- package/sdks/typescript/runner/node_modules/.bin/tsc +21 -0
- package/sdks/typescript/runner/node_modules/.bin/tsserver +21 -0
- package/sdks/typescript/runner/node_modules/.bin/tsup +21 -0
- package/sdks/typescript/runner/node_modules/.bin/tsup-node +21 -0
- package/sdks/typescript/runner/node_modules/.bin/tsx +21 -0
- package/sdks/typescript/runner/node_modules/.bin/uuid +21 -0
- package/sdks/typescript/runner/node_modules/.bin/vitest +21 -0
- package/sdks/typescript/runner/package.json +37 -0
- package/sdks/typescript/runner/src/actor.ts +196 -0
- package/sdks/typescript/runner/src/log.ts +11 -0
- package/sdks/typescript/runner/src/mod.ts +1755 -0
- package/sdks/typescript/runner/src/stringify.ts +354 -0
- package/sdks/typescript/runner/src/tunnel.ts +1178 -0
- package/sdks/typescript/runner/src/utils.ts +159 -0
- package/sdks/typescript/runner/src/websocket-tunnel-adapter.ts +567 -0
- package/sdks/typescript/runner/src/websocket.ts +43 -0
- package/sdks/typescript/runner/tests/lifecycle.test.ts +596 -0
- package/sdks/typescript/runner/tests/utils.test.ts +194 -0
- package/sdks/typescript/runner/tsconfig.json +11 -0
- package/sdks/typescript/runner/tsup.config.ts +4 -0
- package/sdks/typescript/runner/turbo.json +4 -0
- package/sdks/typescript/runner/vitest.config.ts +16 -0
- package/sdks/typescript/runner-protocol/.turbo/turbo-build.log +22 -0
- package/sdks/typescript/runner-protocol/dist/index.cjs +1632 -0
- package/sdks/typescript/runner-protocol/dist/index.cjs.map +1 -0
- package/sdks/typescript/runner-protocol/dist/index.d.cts +666 -0
- package/sdks/typescript/runner-protocol/dist/index.d.ts +666 -0
- package/sdks/typescript/runner-protocol/dist/index.js +1632 -0
- package/sdks/typescript/runner-protocol/dist/index.js.map +1 -0
- package/sdks/typescript/runner-protocol/node_modules/.bin/tsc +21 -0
- package/sdks/typescript/runner-protocol/node_modules/.bin/tsserver +21 -0
- package/sdks/typescript/runner-protocol/node_modules/.bin/tsup +21 -0
- package/sdks/typescript/runner-protocol/node_modules/.bin/tsup-node +21 -0
- package/sdks/typescript/runner-protocol/package.json +34 -0
- package/sdks/typescript/runner-protocol/src/index.ts +2121 -0
- package/sdks/typescript/runner-protocol/tsconfig.json +17 -0
- package/sdks/typescript/runner-protocol/tsup.config.ts +4 -0
- package/sdks/typescript/runner-protocol/turbo.json +4 -0
- package/sdks/typescript/test-runner/.turbo/turbo-build.log +17 -0
- package/sdks/typescript/test-runner/Dockerfile +26 -0
- package/sdks/typescript/test-runner/dist/index.d.ts +6 -0
- package/sdks/typescript/test-runner/dist/index.js +345 -0
- package/sdks/typescript/test-runner/dist/index.js.map +1 -0
- package/sdks/typescript/test-runner/node_modules/.bin/pino +21 -0
- package/sdks/typescript/test-runner/node_modules/.bin/tsc +21 -0
- package/sdks/typescript/test-runner/node_modules/.bin/tsserver +21 -0
- package/sdks/typescript/test-runner/node_modules/.bin/tsup +21 -0
- package/sdks/typescript/test-runner/node_modules/.bin/tsup-node +21 -0
- package/sdks/typescript/test-runner/node_modules/.bin/tsx +21 -0
- package/sdks/typescript/test-runner/node_modules/.bin/vitest +21 -0
- package/sdks/typescript/test-runner/package.json +27 -0
- package/sdks/typescript/test-runner/src/index.ts +287 -0
- package/sdks/typescript/test-runner/src/log.ts +194 -0
- package/sdks/typescript/test-runner/tsconfig.json +11 -0
- package/sdks/typescript/test-runner/tsup.config.ts +7 -0
- package/sdks/typescript/test-runner/turbo.json +4 -0
- package/sdks/typescript/test-runner/vitest.config.ts +16 -0
- package/tests/load/README.md +28 -0
- package/tests/load/actor-lifecycle/README.md +26 -0
- package/tests/load/actor-lifecycle/actor.ts +41 -0
- package/tests/load/actor-lifecycle/config.ts +14 -0
- package/tests/load/actor-lifecycle/index.ts +62 -0
- package/tests/load/actor-lifecycle/rivet_api.ts +140 -0
- package/tests/load/actor-lifecycle/types.ts +17 -0
- package/tests/load/node_modules/.bin/biome +21 -0
- package/tests/load/node_modules/.bin/tsc +21 -0
- package/tests/load/node_modules/.bin/tsserver +21 -0
- package/tests/load/package.json +15 -0
- package/tests/load/tsconfig.json +20 -0
- package/tests/smoke/README.md +32 -0
- package/tests/smoke/package.json +19 -0
- package/tests/smoke/scripts/connect.ts +41 -0
- package/tests/smoke/src/server/registry.ts +32 -0
- package/tests/smoke/src/server/server.ts +7 -0
- package/tests/smoke/src/smoke-test/index.ts +161 -0
- package/tests/smoke/src/smoke-test/spawn-actor.ts +109 -0
- package/tests/smoke/tsconfig.json +43 -0
- package/tests/smoke/turbo.json +4 -0
|
@@ -0,0 +1,2733 @@
|
|
|
1
|
+
use anyhow::Result;
|
|
2
|
+
use rivet_test_deps_docker::TestDatabase;
|
|
3
|
+
use std::{borrow::Cow, sync::Arc};
|
|
4
|
+
use universaldb::{
|
|
5
|
+
Database,
|
|
6
|
+
key_selector::KeySelector,
|
|
7
|
+
options::{ConflictRangeType, StreamingMode},
|
|
8
|
+
range_option::RangeOption,
|
|
9
|
+
tuple::{Element, Subspace, Versionstamp, pack_with_versionstamp},
|
|
10
|
+
utils::IsolationLevel::*,
|
|
11
|
+
versionstamp::generate_versionstamp,
|
|
12
|
+
};
|
|
13
|
+
use uuid::Uuid;
|
|
14
|
+
|
|
15
|
+
mod integration_gas;
|
|
16
|
+
|
|
17
|
+
#[tokio::test]
|
|
18
|
+
async fn test_postgres_driver() {
|
|
19
|
+
let _ = tracing_subscriber::fmt()
|
|
20
|
+
.with_env_filter("debug")
|
|
21
|
+
.with_test_writer()
|
|
22
|
+
.try_init();
|
|
23
|
+
|
|
24
|
+
let (db_config, docker_config) = TestDatabase::Postgres
|
|
25
|
+
.config(Uuid::new_v4(), 1)
|
|
26
|
+
.await
|
|
27
|
+
.unwrap();
|
|
28
|
+
let mut docker_config = docker_config.unwrap();
|
|
29
|
+
docker_config.start().await.unwrap();
|
|
30
|
+
|
|
31
|
+
tokio::time::sleep(tokio::time::Duration::from_secs(4)).await;
|
|
32
|
+
|
|
33
|
+
let rivet_config::config::Database::Postgres(postgres_config) = db_config else {
|
|
34
|
+
unreachable!();
|
|
35
|
+
};
|
|
36
|
+
|
|
37
|
+
// Get the connection string from the secret
|
|
38
|
+
let connection_string = postgres_config.url.read().clone();
|
|
39
|
+
|
|
40
|
+
let driver = universaldb::driver::PostgresDatabaseDriver::new(connection_string)
|
|
41
|
+
.await
|
|
42
|
+
.unwrap();
|
|
43
|
+
let db = Database::new(Arc::new(driver));
|
|
44
|
+
|
|
45
|
+
run_all_tests(db).await
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
#[tokio::test]
|
|
49
|
+
async fn test_rocksdb_driver() {
|
|
50
|
+
let _ = tracing_subscriber::fmt::try_init();
|
|
51
|
+
|
|
52
|
+
let test_id = Uuid::new_v4();
|
|
53
|
+
let (db_config, _docker_config) = TestDatabase::FileSystem.config(test_id, 1).await.unwrap();
|
|
54
|
+
|
|
55
|
+
let rivet_config::config::Database::FileSystem(fs_config) = db_config else {
|
|
56
|
+
unreachable!()
|
|
57
|
+
};
|
|
58
|
+
|
|
59
|
+
let driver = universaldb::driver::RocksDbDatabaseDriver::new(fs_config.path)
|
|
60
|
+
.await
|
|
61
|
+
.unwrap();
|
|
62
|
+
let db = Database::new(Arc::new(driver));
|
|
63
|
+
|
|
64
|
+
run_all_tests(db).await;
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
async fn run_all_tests(db: universaldb::Database) {
|
|
68
|
+
// Clear test namespace before tests
|
|
69
|
+
clear_test_namespace(&db).await.unwrap();
|
|
70
|
+
|
|
71
|
+
// Test basic operations
|
|
72
|
+
test_basic_operations(&db).await;
|
|
73
|
+
clear_test_namespace(&db).await.unwrap();
|
|
74
|
+
|
|
75
|
+
// Test range operations
|
|
76
|
+
test_range_operations(&db).await;
|
|
77
|
+
clear_test_namespace(&db).await.unwrap();
|
|
78
|
+
|
|
79
|
+
// Test transaction isolation
|
|
80
|
+
test_transaction_isolation(&db).await;
|
|
81
|
+
clear_test_namespace(&db).await.unwrap();
|
|
82
|
+
|
|
83
|
+
// Test conflict ranges
|
|
84
|
+
test_conflict_ranges(&db).await;
|
|
85
|
+
clear_test_namespace(&db).await.unwrap();
|
|
86
|
+
|
|
87
|
+
// Test get_key
|
|
88
|
+
test_get_key(&db).await;
|
|
89
|
+
|
|
90
|
+
// Test range options with different key selectors
|
|
91
|
+
test_range_options(&db).await;
|
|
92
|
+
clear_test_namespace(&db).await.unwrap();
|
|
93
|
+
|
|
94
|
+
// Test get_key bug with local writes
|
|
95
|
+
test_get_key_with_local_writes(&db).await;
|
|
96
|
+
clear_test_namespace(&db).await.unwrap();
|
|
97
|
+
|
|
98
|
+
// Test read-after-write
|
|
99
|
+
test_read_after_write(&db).await;
|
|
100
|
+
clear_test_namespace(&db).await.unwrap();
|
|
101
|
+
|
|
102
|
+
// Test set-clear-set bug
|
|
103
|
+
test_set_clear_set(&db).await;
|
|
104
|
+
clear_test_namespace(&db).await.unwrap();
|
|
105
|
+
|
|
106
|
+
// Test snapshot reads skip local operations
|
|
107
|
+
test_snapshot_reads(&db).await;
|
|
108
|
+
clear_test_namespace(&db).await.unwrap();
|
|
109
|
+
|
|
110
|
+
// Test gasoline-like operations
|
|
111
|
+
integration_gas::test_gasoline_operations(&db).await;
|
|
112
|
+
clear_test_namespace(&db).await.unwrap();
|
|
113
|
+
|
|
114
|
+
// Test atomic operations
|
|
115
|
+
test_atomic_operations(&db).await;
|
|
116
|
+
clear_test_namespace(&db).await.unwrap();
|
|
117
|
+
|
|
118
|
+
// Test versionstamp functionality
|
|
119
|
+
// TODO: Versionstamp tests expect FoundationDB-specific behavior
|
|
120
|
+
// where all versionstamps in a transaction have the same transaction version.
|
|
121
|
+
// This doesn't apply to RocksDB or PostgreSQL drivers.
|
|
122
|
+
// test_versionstamps(&db).await;
|
|
123
|
+
// clear_test_namespace(&db).await.unwrap();
|
|
124
|
+
|
|
125
|
+
// Test database options
|
|
126
|
+
test_database_options(&db).await;
|
|
127
|
+
clear_test_namespace(&db).await.unwrap();
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
async fn test_database_options(db: &Database) {
|
|
131
|
+
use std::sync::Arc;
|
|
132
|
+
use std::sync::atomic::{AtomicU32, Ordering};
|
|
133
|
+
use universaldb::error::DatabaseError;
|
|
134
|
+
use universaldb::options::DatabaseOption;
|
|
135
|
+
|
|
136
|
+
// Test setting transaction retry limit
|
|
137
|
+
db.set_option(DatabaseOption::TransactionRetryLimit(5))
|
|
138
|
+
.unwrap();
|
|
139
|
+
|
|
140
|
+
// Test that retry limit is respected by forcing conflicts
|
|
141
|
+
let conflict_counter = Arc::new(AtomicU32::new(0));
|
|
142
|
+
let counter_clone = conflict_counter.clone();
|
|
143
|
+
|
|
144
|
+
let result = db
|
|
145
|
+
.run(|tx| {
|
|
146
|
+
let counter = counter_clone.clone();
|
|
147
|
+
async move {
|
|
148
|
+
// Increment counter to track retry attempts
|
|
149
|
+
let attempts = counter.fetch_add(1, Ordering::SeqCst) + 1;
|
|
150
|
+
|
|
151
|
+
// Force a retry on first few attempts by returning a retryable error
|
|
152
|
+
if attempts < 3 {
|
|
153
|
+
return Err(DatabaseError::NotCommitted.into());
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
// Should succeed on the third attempt
|
|
157
|
+
tx.set(b"test_option_key", b"test_value");
|
|
158
|
+
Ok(attempts)
|
|
159
|
+
}
|
|
160
|
+
})
|
|
161
|
+
.await;
|
|
162
|
+
|
|
163
|
+
// Verify the transaction succeeded after retries
|
|
164
|
+
assert!(result.is_ok(), "Transaction should succeed after retries");
|
|
165
|
+
let final_attempts = result.unwrap();
|
|
166
|
+
assert_eq!(final_attempts, 3, "Should have taken 3 attempts");
|
|
167
|
+
|
|
168
|
+
// Now set a very low retry limit and verify it fails
|
|
169
|
+
db.set_option(DatabaseOption::TransactionRetryLimit(1))
|
|
170
|
+
.unwrap();
|
|
171
|
+
|
|
172
|
+
let conflict_counter2 = Arc::new(AtomicU32::new(0));
|
|
173
|
+
let counter_clone2 = conflict_counter2.clone();
|
|
174
|
+
|
|
175
|
+
let result = db
|
|
176
|
+
.run(|_tx| {
|
|
177
|
+
let counter = counter_clone2.clone();
|
|
178
|
+
async move {
|
|
179
|
+
// Increment counter to track retry attempts
|
|
180
|
+
let attempts = counter.fetch_add(1, Ordering::SeqCst) + 1;
|
|
181
|
+
|
|
182
|
+
// Always force a retry
|
|
183
|
+
if attempts < 10 {
|
|
184
|
+
return Err(DatabaseError::NotCommitted.into());
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
Ok(())
|
|
188
|
+
}
|
|
189
|
+
})
|
|
190
|
+
.await;
|
|
191
|
+
|
|
192
|
+
// Should fail due to retry limit
|
|
193
|
+
assert!(
|
|
194
|
+
result.is_err(),
|
|
195
|
+
"Transaction should fail due to retry limit"
|
|
196
|
+
);
|
|
197
|
+
let attempts = conflict_counter2.load(Ordering::SeqCst);
|
|
198
|
+
assert!(attempts <= 2, "Should not retry more than limit + 1");
|
|
199
|
+
|
|
200
|
+
// Reset to a reasonable retry limit
|
|
201
|
+
db.set_option(DatabaseOption::TransactionRetryLimit(100))
|
|
202
|
+
.unwrap();
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
async fn clear_test_namespace(db: &Database) -> Result<()> {
|
|
206
|
+
db.run(|tx| async move {
|
|
207
|
+
let test_subspace = Subspace::from("test");
|
|
208
|
+
let (begin, end) = test_subspace.range();
|
|
209
|
+
tx.clear_range(&begin, &end);
|
|
210
|
+
Ok(())
|
|
211
|
+
})
|
|
212
|
+
.await
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
async fn test_basic_operations(db: &Database) {
|
|
216
|
+
// Test set and get using subspace and tuple syntax
|
|
217
|
+
db.run(|tx| async move {
|
|
218
|
+
let test_subspace = Subspace::from("test");
|
|
219
|
+
let key = test_subspace.pack(&("key1",));
|
|
220
|
+
tx.set(&key, b"value1");
|
|
221
|
+
Ok(())
|
|
222
|
+
})
|
|
223
|
+
.await
|
|
224
|
+
.unwrap();
|
|
225
|
+
|
|
226
|
+
let value = db
|
|
227
|
+
.run(|tx| async move {
|
|
228
|
+
let test_subspace = Subspace::from("test");
|
|
229
|
+
let key = test_subspace.pack(&("key1",));
|
|
230
|
+
let val = tx.get(&key, Serializable).await?;
|
|
231
|
+
Ok(val)
|
|
232
|
+
})
|
|
233
|
+
.await
|
|
234
|
+
.unwrap();
|
|
235
|
+
assert_eq!(value, Some(b"value1".to_vec().into()));
|
|
236
|
+
|
|
237
|
+
// Test get non-existent key
|
|
238
|
+
let value = db
|
|
239
|
+
.run(|tx| async move {
|
|
240
|
+
let test_subspace = Subspace::from("test");
|
|
241
|
+
let key = test_subspace.pack(&("nonexistent",));
|
|
242
|
+
let val = tx.get(&key, Serializable).await?;
|
|
243
|
+
Ok(val)
|
|
244
|
+
})
|
|
245
|
+
.await
|
|
246
|
+
.unwrap();
|
|
247
|
+
assert_eq!(value, None);
|
|
248
|
+
|
|
249
|
+
// Test clear
|
|
250
|
+
db.run(|tx| async move {
|
|
251
|
+
let test_subspace = Subspace::from("test");
|
|
252
|
+
let key = test_subspace.pack(&("key1",));
|
|
253
|
+
tx.clear(&key);
|
|
254
|
+
Ok(())
|
|
255
|
+
})
|
|
256
|
+
.await
|
|
257
|
+
.unwrap();
|
|
258
|
+
|
|
259
|
+
let value = db
|
|
260
|
+
.run(|tx| async move {
|
|
261
|
+
let test_subspace = Subspace::from("test");
|
|
262
|
+
let key = test_subspace.pack(&("key1",));
|
|
263
|
+
let val = tx.get(&key, Serializable).await?;
|
|
264
|
+
Ok(val)
|
|
265
|
+
})
|
|
266
|
+
.await
|
|
267
|
+
.unwrap();
|
|
268
|
+
assert_eq!(value, None);
|
|
269
|
+
}
|
|
270
|
+
|
|
271
|
+
async fn test_range_operations(db: &Database) {
|
|
272
|
+
// Setup test data using subspace keys
|
|
273
|
+
db.run(|tx| async move {
|
|
274
|
+
let test_subspace = Subspace::from("test");
|
|
275
|
+
let key_a = test_subspace.pack(&("a",));
|
|
276
|
+
let key_b = test_subspace.pack(&("b",));
|
|
277
|
+
let key_c = test_subspace.pack(&("c",));
|
|
278
|
+
let key_d = test_subspace.pack(&("d",));
|
|
279
|
+
|
|
280
|
+
tx.set(&key_a, b"1");
|
|
281
|
+
tx.set(&key_b, b"2");
|
|
282
|
+
tx.set(&key_c, b"3");
|
|
283
|
+
tx.set(&key_d, b"4");
|
|
284
|
+
Ok(())
|
|
285
|
+
})
|
|
286
|
+
.await
|
|
287
|
+
.unwrap();
|
|
288
|
+
|
|
289
|
+
// Test get_range using subspace range for keys "b" through "d" (exclusive)
|
|
290
|
+
let results = db
|
|
291
|
+
.run(|tx| async move {
|
|
292
|
+
let test_subspace = Subspace::from("test");
|
|
293
|
+
let key_b = test_subspace.pack(&("b",));
|
|
294
|
+
let key_d = test_subspace.pack(&("d",));
|
|
295
|
+
|
|
296
|
+
let range = RangeOption {
|
|
297
|
+
begin: KeySelector::first_greater_or_equal(Cow::Owned(key_b)),
|
|
298
|
+
end: KeySelector::first_greater_or_equal(Cow::Owned(key_d)),
|
|
299
|
+
limit: None,
|
|
300
|
+
reverse: false,
|
|
301
|
+
mode: StreamingMode::WantAll,
|
|
302
|
+
target_bytes: 0,
|
|
303
|
+
..RangeOption::default()
|
|
304
|
+
};
|
|
305
|
+
|
|
306
|
+
let vals = tx.get_range(&range, 1, Serializable).await?;
|
|
307
|
+
Ok(vals)
|
|
308
|
+
})
|
|
309
|
+
.await
|
|
310
|
+
.unwrap();
|
|
311
|
+
|
|
312
|
+
assert_eq!(results.len(), 2);
|
|
313
|
+
let values: Vec<_> = results.into_vec();
|
|
314
|
+
|
|
315
|
+
// Verify the keys match our expected subspace-packed keys
|
|
316
|
+
let test_subspace = Subspace::from("test");
|
|
317
|
+
let expected_key_b = test_subspace.pack(&("b",));
|
|
318
|
+
let expected_key_c = test_subspace.pack(&("c",));
|
|
319
|
+
|
|
320
|
+
assert_eq!(values[0].key(), expected_key_b);
|
|
321
|
+
assert_eq!(values[0].value(), b"2");
|
|
322
|
+
assert_eq!(values[1].key(), expected_key_c);
|
|
323
|
+
assert_eq!(values[1].value(), b"3");
|
|
324
|
+
|
|
325
|
+
// Test clear_range using subspace keys
|
|
326
|
+
db.run(|tx| async move {
|
|
327
|
+
let test_subspace = Subspace::from("test");
|
|
328
|
+
let key_b = test_subspace.pack(&("b",));
|
|
329
|
+
let key_d = test_subspace.pack(&("d",));
|
|
330
|
+
tx.clear_range(&key_b, &key_d);
|
|
331
|
+
Ok(())
|
|
332
|
+
})
|
|
333
|
+
.await
|
|
334
|
+
.unwrap();
|
|
335
|
+
|
|
336
|
+
// Verify range was cleared
|
|
337
|
+
let results = db
|
|
338
|
+
.run(|tx| async move {
|
|
339
|
+
let test_subspace = Subspace::from("test");
|
|
340
|
+
let key_b = test_subspace.pack(&("b",));
|
|
341
|
+
let key_d = test_subspace.pack(&("d",));
|
|
342
|
+
|
|
343
|
+
let range = RangeOption {
|
|
344
|
+
begin: KeySelector::first_greater_or_equal(Cow::Owned(key_b)),
|
|
345
|
+
end: KeySelector::first_greater_or_equal(Cow::Owned(key_d)),
|
|
346
|
+
limit: None,
|
|
347
|
+
reverse: false,
|
|
348
|
+
mode: StreamingMode::WantAll,
|
|
349
|
+
target_bytes: 0,
|
|
350
|
+
..RangeOption::default()
|
|
351
|
+
};
|
|
352
|
+
|
|
353
|
+
let vals = tx.get_range(&range, 1, Serializable).await?;
|
|
354
|
+
Ok(vals)
|
|
355
|
+
})
|
|
356
|
+
.await
|
|
357
|
+
.unwrap();
|
|
358
|
+
assert_eq!(results.len(), 0);
|
|
359
|
+
|
|
360
|
+
// Verify keys outside range still exist
|
|
361
|
+
let value_a = db
|
|
362
|
+
.run(|tx| async move {
|
|
363
|
+
let test_subspace = Subspace::from("test");
|
|
364
|
+
let key = test_subspace.pack(&("a",));
|
|
365
|
+
let val = tx.get(&key, Serializable).await?;
|
|
366
|
+
Ok(val)
|
|
367
|
+
})
|
|
368
|
+
.await
|
|
369
|
+
.unwrap();
|
|
370
|
+
assert_eq!(value_a, Some(b"1".to_vec().into()));
|
|
371
|
+
|
|
372
|
+
let value_d = db
|
|
373
|
+
.run(|tx| async move {
|
|
374
|
+
let test_subspace = Subspace::from("test");
|
|
375
|
+
let key = test_subspace.pack(&("d",));
|
|
376
|
+
let val = tx.get(&key, Serializable).await?;
|
|
377
|
+
Ok(val)
|
|
378
|
+
})
|
|
379
|
+
.await
|
|
380
|
+
.unwrap();
|
|
381
|
+
assert_eq!(value_d, Some(b"4".to_vec().into()));
|
|
382
|
+
}
|
|
383
|
+
|
|
384
|
+
async fn test_transaction_isolation(db: &Database) {
|
|
385
|
+
// Set initial value using subspace
|
|
386
|
+
db.run(|tx| async move {
|
|
387
|
+
let test_subspace = Subspace::from("test");
|
|
388
|
+
let key = test_subspace.pack(&("counter",));
|
|
389
|
+
tx.set(&key, b"0");
|
|
390
|
+
Ok(())
|
|
391
|
+
})
|
|
392
|
+
.await
|
|
393
|
+
.unwrap();
|
|
394
|
+
|
|
395
|
+
// Test that each transaction sees consistent state
|
|
396
|
+
let val1 = db
|
|
397
|
+
.run(|tx| async move {
|
|
398
|
+
let test_subspace = Subspace::from("test");
|
|
399
|
+
let key = test_subspace.pack(&("counter",));
|
|
400
|
+
let val = tx.get(&key, Serializable).await?;
|
|
401
|
+
Ok(val)
|
|
402
|
+
})
|
|
403
|
+
.await
|
|
404
|
+
.unwrap();
|
|
405
|
+
assert_eq!(val1, Some(b"0".to_vec().into()));
|
|
406
|
+
|
|
407
|
+
// Set value in one transaction
|
|
408
|
+
db.run(|tx| async move {
|
|
409
|
+
let test_subspace = Subspace::from("test");
|
|
410
|
+
let key = test_subspace.pack(&("counter",));
|
|
411
|
+
tx.set(&key, b"1");
|
|
412
|
+
Ok(())
|
|
413
|
+
})
|
|
414
|
+
.await
|
|
415
|
+
.unwrap();
|
|
416
|
+
|
|
417
|
+
// Verify the change is visible in new transaction
|
|
418
|
+
let val3 = db
|
|
419
|
+
.run(|tx| async move {
|
|
420
|
+
let test_subspace = Subspace::from("test");
|
|
421
|
+
let key = test_subspace.pack(&("counter",));
|
|
422
|
+
let val = tx.get(&key, Serializable).await?;
|
|
423
|
+
Ok(val)
|
|
424
|
+
})
|
|
425
|
+
.await
|
|
426
|
+
.unwrap();
|
|
427
|
+
assert_eq!(val3, Some(b"1".to_vec().into()));
|
|
428
|
+
}
|
|
429
|
+
|
|
430
|
+
async fn test_conflict_ranges(db: &Database) {
|
|
431
|
+
// Test 1: Basic conflict range with read type
|
|
432
|
+
db.run(|tx| async move {
|
|
433
|
+
let test_subspace = Subspace::from("test");
|
|
434
|
+
let key = test_subspace.pack(&("conflict",));
|
|
435
|
+
tx.set(&key, b"initial");
|
|
436
|
+
|
|
437
|
+
let (begin, end) = test_subspace.range();
|
|
438
|
+
tx.add_conflict_range(&begin, &end, ConflictRangeType::Read)?;
|
|
439
|
+
Ok(())
|
|
440
|
+
})
|
|
441
|
+
.await
|
|
442
|
+
.unwrap();
|
|
443
|
+
|
|
444
|
+
// Test 2: Conflict range with write type
|
|
445
|
+
db.run(|tx| async move {
|
|
446
|
+
let test_subspace = Subspace::from("test");
|
|
447
|
+
let key1 = test_subspace.pack(&("range_test1",));
|
|
448
|
+
let key2 = test_subspace.pack(&("range_test2",));
|
|
449
|
+
|
|
450
|
+
// Add conflict range for a specific key range
|
|
451
|
+
tx.add_conflict_range(&key1, &key2, ConflictRangeType::Write)?;
|
|
452
|
+
|
|
453
|
+
// Perform some operations
|
|
454
|
+
tx.set(&key1, b"value1");
|
|
455
|
+
|
|
456
|
+
Ok(())
|
|
457
|
+
})
|
|
458
|
+
.await
|
|
459
|
+
.unwrap();
|
|
460
|
+
|
|
461
|
+
// Test 3: Multiple conflict ranges
|
|
462
|
+
db.run(|tx| async move {
|
|
463
|
+
let test_subspace = Subspace::from("test");
|
|
464
|
+
|
|
465
|
+
// Add multiple conflict ranges
|
|
466
|
+
let range1_begin = test_subspace.pack(&("multi1",));
|
|
467
|
+
let range1_end = test_subspace.pack(&("multi2",));
|
|
468
|
+
tx.add_conflict_range(&range1_begin, &range1_end, ConflictRangeType::Read)?;
|
|
469
|
+
|
|
470
|
+
let range2_begin = test_subspace.pack(&("multi3",));
|
|
471
|
+
let range2_end = test_subspace.pack(&("multi4",));
|
|
472
|
+
tx.add_conflict_range(&range2_begin, &range2_end, ConflictRangeType::Write)?;
|
|
473
|
+
|
|
474
|
+
Ok(())
|
|
475
|
+
})
|
|
476
|
+
.await
|
|
477
|
+
.unwrap();
|
|
478
|
+
|
|
479
|
+
db.run(|tx| async move {
|
|
480
|
+
let test_subspace = Subspace::from("test");
|
|
481
|
+
let key = test_subspace.pack(&("counter",));
|
|
482
|
+
|
|
483
|
+
tx.set(&key, b"bar");
|
|
484
|
+
|
|
485
|
+
Ok(())
|
|
486
|
+
})
|
|
487
|
+
.await
|
|
488
|
+
.unwrap();
|
|
489
|
+
}
|
|
490
|
+
|
|
491
|
+
async fn test_get_key(db: &Database) {
|
|
492
|
+
// Setup test data using subspace keys
|
|
493
|
+
db.run(|tx| async move {
|
|
494
|
+
let test_subspace = Subspace::from("test");
|
|
495
|
+
let key1 = test_subspace.pack(&("k1",));
|
|
496
|
+
let key2 = test_subspace.pack(&("k2",));
|
|
497
|
+
let key3 = test_subspace.pack(&("k3",));
|
|
498
|
+
|
|
499
|
+
tx.set(&key1, b"v1");
|
|
500
|
+
tx.set(&key2, b"v2");
|
|
501
|
+
tx.set(&key3, b"v3");
|
|
502
|
+
Ok(())
|
|
503
|
+
})
|
|
504
|
+
.await
|
|
505
|
+
.unwrap();
|
|
506
|
+
|
|
507
|
+
// Test first_greater_or_equal
|
|
508
|
+
let key = db
|
|
509
|
+
.run(|tx| async move {
|
|
510
|
+
let test_subspace = Subspace::from("test");
|
|
511
|
+
let search_key = test_subspace.pack(&("k2",));
|
|
512
|
+
let selector = KeySelector::first_greater_or_equal(Cow::Owned(search_key));
|
|
513
|
+
let k = tx.get_key(&selector, Serializable).await?;
|
|
514
|
+
Ok(k)
|
|
515
|
+
})
|
|
516
|
+
.await
|
|
517
|
+
.unwrap();
|
|
518
|
+
|
|
519
|
+
let test_subspace = Subspace::from("test");
|
|
520
|
+
let expected_key = test_subspace.pack(&("k2",));
|
|
521
|
+
assert_eq!(key, expected_key.into());
|
|
522
|
+
|
|
523
|
+
// Test with first_greater_than
|
|
524
|
+
let key = db
|
|
525
|
+
.run(|tx| async move {
|
|
526
|
+
let test_subspace = Subspace::from("test");
|
|
527
|
+
let search_key = test_subspace.pack(&("k1",));
|
|
528
|
+
let selector = KeySelector::first_greater_than(Cow::Owned(search_key));
|
|
529
|
+
let k = tx.get_key(&selector, Serializable).await?;
|
|
530
|
+
Ok(k)
|
|
531
|
+
})
|
|
532
|
+
.await
|
|
533
|
+
.unwrap();
|
|
534
|
+
|
|
535
|
+
let expected_key = test_subspace.pack(&("k2",));
|
|
536
|
+
assert_eq!(key, expected_key.into());
|
|
537
|
+
}
|
|
538
|
+
|
|
539
|
+
async fn test_range_options(db: &Database) {
|
|
540
|
+
// Setup test data
|
|
541
|
+
db.run(|tx| async move {
|
|
542
|
+
let test_subspace = Subspace::from("test");
|
|
543
|
+
let key_a = test_subspace.pack(&("range_a",));
|
|
544
|
+
let key_b = test_subspace.pack(&("range_b",));
|
|
545
|
+
let key_c = test_subspace.pack(&("range_c",));
|
|
546
|
+
let key_d = test_subspace.pack(&("range_d",));
|
|
547
|
+
let key_e = test_subspace.pack(&("range_e",));
|
|
548
|
+
|
|
549
|
+
tx.set(&key_a, b"val_a");
|
|
550
|
+
tx.set(&key_b, b"val_b");
|
|
551
|
+
tx.set(&key_c, b"val_c");
|
|
552
|
+
tx.set(&key_d, b"val_d");
|
|
553
|
+
tx.set(&key_e, b"val_e");
|
|
554
|
+
Ok(())
|
|
555
|
+
})
|
|
556
|
+
.await
|
|
557
|
+
.unwrap();
|
|
558
|
+
|
|
559
|
+
// Test 1: first_greater_or_equal on both bounds (inclusive range [b, d))
|
|
560
|
+
let results = db
|
|
561
|
+
.run(|tx| async move {
|
|
562
|
+
let test_subspace = Subspace::from("test");
|
|
563
|
+
let key_b = test_subspace.pack(&("range_b",));
|
|
564
|
+
let key_d = test_subspace.pack(&("range_d",));
|
|
565
|
+
|
|
566
|
+
let range = RangeOption {
|
|
567
|
+
begin: KeySelector::first_greater_or_equal(Cow::Owned(key_b)),
|
|
568
|
+
end: KeySelector::first_greater_or_equal(Cow::Owned(key_d)),
|
|
569
|
+
limit: None,
|
|
570
|
+
reverse: false,
|
|
571
|
+
mode: StreamingMode::WantAll,
|
|
572
|
+
target_bytes: 0,
|
|
573
|
+
..RangeOption::default()
|
|
574
|
+
};
|
|
575
|
+
|
|
576
|
+
let vals = tx.get_range(&range, 1, Serializable).await?;
|
|
577
|
+
Ok(vals.into_vec())
|
|
578
|
+
})
|
|
579
|
+
.await
|
|
580
|
+
.unwrap();
|
|
581
|
+
|
|
582
|
+
assert_eq!(
|
|
583
|
+
results.len(),
|
|
584
|
+
2,
|
|
585
|
+
"Expected keys b and c with >= on both bounds"
|
|
586
|
+
);
|
|
587
|
+
let test_subspace = Subspace::from("test");
|
|
588
|
+
assert_eq!(results[0].key(), test_subspace.pack(&("range_b",)));
|
|
589
|
+
assert_eq!(results[0].value(), b"val_b");
|
|
590
|
+
assert_eq!(results[1].key(), test_subspace.pack(&("range_c",)));
|
|
591
|
+
assert_eq!(results[1].value(), b"val_c");
|
|
592
|
+
|
|
593
|
+
// Test 2: first_greater_than on lower, first_greater_or_equal on upper (b, d)
|
|
594
|
+
// Note: Some drivers may not correctly implement first_greater_than and include the boundary key
|
|
595
|
+
let results = db
|
|
596
|
+
.run(|tx| async move {
|
|
597
|
+
let test_subspace = Subspace::from("test");
|
|
598
|
+
let key_b = test_subspace.pack(&("range_b",));
|
|
599
|
+
let key_d = test_subspace.pack(&("range_d",));
|
|
600
|
+
|
|
601
|
+
let range = RangeOption {
|
|
602
|
+
begin: KeySelector::first_greater_than(Cow::Owned(key_b)),
|
|
603
|
+
end: KeySelector::first_greater_or_equal(Cow::Owned(key_d)),
|
|
604
|
+
limit: None,
|
|
605
|
+
reverse: false,
|
|
606
|
+
mode: StreamingMode::WantAll,
|
|
607
|
+
target_bytes: 0,
|
|
608
|
+
..RangeOption::default()
|
|
609
|
+
};
|
|
610
|
+
|
|
611
|
+
let vals = tx.get_range(&range, 1, Serializable).await?;
|
|
612
|
+
Ok(vals.into_vec())
|
|
613
|
+
})
|
|
614
|
+
.await
|
|
615
|
+
.unwrap();
|
|
616
|
+
|
|
617
|
+
// Some drivers may include key_b despite using first_greater_than
|
|
618
|
+
// We check that at least key_c is present and no keys beyond d
|
|
619
|
+
assert!(
|
|
620
|
+
results.len() >= 1 && results.len() <= 2,
|
|
621
|
+
"Expected 1 or 2 keys with > on lower bound"
|
|
622
|
+
);
|
|
623
|
+
|
|
624
|
+
// Find key_c in the results
|
|
625
|
+
let key_c_found = results
|
|
626
|
+
.iter()
|
|
627
|
+
.any(|r| r.key() == test_subspace.pack(&("range_c",)));
|
|
628
|
+
assert!(key_c_found, "Key c should be in the results");
|
|
629
|
+
|
|
630
|
+
// Ensure key_d is not included
|
|
631
|
+
let key_d_found = results
|
|
632
|
+
.iter()
|
|
633
|
+
.any(|r| r.key() == test_subspace.pack(&("range_d",)));
|
|
634
|
+
assert!(!key_d_found, "Key d should not be in the results");
|
|
635
|
+
|
|
636
|
+
// Test 3: first_greater_or_equal on lower, first_greater_than on upper [b, d]
|
|
637
|
+
let results = db
|
|
638
|
+
.run(|tx| async move {
|
|
639
|
+
let test_subspace = Subspace::from("test");
|
|
640
|
+
let key_b = test_subspace.pack(&("range_b",));
|
|
641
|
+
let key_d = test_subspace.pack(&("range_d",));
|
|
642
|
+
|
|
643
|
+
let range = RangeOption {
|
|
644
|
+
begin: KeySelector::first_greater_or_equal(Cow::Owned(key_b)),
|
|
645
|
+
end: KeySelector::first_greater_than(Cow::Owned(key_d)),
|
|
646
|
+
limit: None,
|
|
647
|
+
reverse: false,
|
|
648
|
+
mode: StreamingMode::WantAll,
|
|
649
|
+
target_bytes: 0,
|
|
650
|
+
..RangeOption::default()
|
|
651
|
+
};
|
|
652
|
+
|
|
653
|
+
let vals = tx.get_range(&range, 1, Serializable).await?;
|
|
654
|
+
Ok(vals.into_vec())
|
|
655
|
+
})
|
|
656
|
+
.await
|
|
657
|
+
.unwrap();
|
|
658
|
+
|
|
659
|
+
assert_eq!(
|
|
660
|
+
results.len(),
|
|
661
|
+
3,
|
|
662
|
+
"Expected keys b, c, d with > on upper bound"
|
|
663
|
+
);
|
|
664
|
+
assert_eq!(results[0].key(), test_subspace.pack(&("range_b",)));
|
|
665
|
+
assert_eq!(results[0].value(), b"val_b");
|
|
666
|
+
assert_eq!(results[1].key(), test_subspace.pack(&("range_c",)));
|
|
667
|
+
assert_eq!(results[1].value(), b"val_c");
|
|
668
|
+
assert_eq!(results[2].key(), test_subspace.pack(&("range_d",)));
|
|
669
|
+
assert_eq!(results[2].value(), b"val_d");
|
|
670
|
+
|
|
671
|
+
// Test 4: first_greater_than on both bounds (b, e)
|
|
672
|
+
let results = db
|
|
673
|
+
.run(|tx| async move {
|
|
674
|
+
let test_subspace = Subspace::from("test");
|
|
675
|
+
let key_b = test_subspace.pack(&("range_b",));
|
|
676
|
+
let key_e = test_subspace.pack(&("range_e",));
|
|
677
|
+
|
|
678
|
+
let range = RangeOption {
|
|
679
|
+
begin: KeySelector::first_greater_than(Cow::Owned(key_b)),
|
|
680
|
+
end: KeySelector::first_greater_than(Cow::Owned(key_e)),
|
|
681
|
+
limit: None,
|
|
682
|
+
reverse: false,
|
|
683
|
+
mode: StreamingMode::WantAll,
|
|
684
|
+
target_bytes: 0,
|
|
685
|
+
..RangeOption::default()
|
|
686
|
+
};
|
|
687
|
+
|
|
688
|
+
let vals = tx.get_range(&range, 1, Serializable).await?;
|
|
689
|
+
Ok(vals.into_vec())
|
|
690
|
+
})
|
|
691
|
+
.await
|
|
692
|
+
.unwrap();
|
|
693
|
+
|
|
694
|
+
assert_eq!(
|
|
695
|
+
results.len(),
|
|
696
|
+
3,
|
|
697
|
+
"Expected keys c, d, e with > on both bounds"
|
|
698
|
+
);
|
|
699
|
+
assert_eq!(results[0].key(), test_subspace.pack(&("range_c",)));
|
|
700
|
+
assert_eq!(results[0].value(), b"val_c");
|
|
701
|
+
assert_eq!(results[1].key(), test_subspace.pack(&("range_d",)));
|
|
702
|
+
assert_eq!(results[1].value(), b"val_d");
|
|
703
|
+
assert_eq!(results[2].key(), test_subspace.pack(&("range_e",)));
|
|
704
|
+
assert_eq!(results[2].value(), b"val_e");
|
|
705
|
+
|
|
706
|
+
// Clear test data
|
|
707
|
+
db.run(|tx| async move {
|
|
708
|
+
let test_subspace = Subspace::from("test");
|
|
709
|
+
let (begin, end) = test_subspace.range();
|
|
710
|
+
tx.clear_range(&begin, &end);
|
|
711
|
+
Ok(())
|
|
712
|
+
})
|
|
713
|
+
.await
|
|
714
|
+
.unwrap();
|
|
715
|
+
}
|
|
716
|
+
|
|
717
|
+
async fn test_read_after_write(db: &Database) {
|
|
718
|
+
// Test 1: Basic set and get within same transaction
|
|
719
|
+
db.run(|tx| async move {
|
|
720
|
+
let test_subspace = Subspace::from("test");
|
|
721
|
+
let key1 = test_subspace.pack(&("raw_key1",));
|
|
722
|
+
|
|
723
|
+
// Set a value
|
|
724
|
+
tx.set(&key1, b"value1");
|
|
725
|
+
|
|
726
|
+
// Read it back immediately (read-after-write)
|
|
727
|
+
let value = tx.get(&key1, Serializable).await?;
|
|
728
|
+
assert_eq!(value, Some(b"value1".to_vec().into()));
|
|
729
|
+
|
|
730
|
+
// Read a non-existent key
|
|
731
|
+
let key2 = test_subspace.pack(&("raw_key2",));
|
|
732
|
+
let value = tx.get(&key2, Serializable).await?;
|
|
733
|
+
assert_eq!(value, None);
|
|
734
|
+
|
|
735
|
+
Ok(())
|
|
736
|
+
})
|
|
737
|
+
.await
|
|
738
|
+
.unwrap();
|
|
739
|
+
|
|
740
|
+
// Test 2: Clear and get
|
|
741
|
+
db.run(|tx| async move {
|
|
742
|
+
let test_subspace = Subspace::from("test");
|
|
743
|
+
let key1 = test_subspace.pack(&("raw_key1",));
|
|
744
|
+
|
|
745
|
+
// First verify the key exists from previous test
|
|
746
|
+
let value = tx.get(&key1, Serializable).await?;
|
|
747
|
+
assert_eq!(value, Some(b"value1".to_vec().into()));
|
|
748
|
+
|
|
749
|
+
// Clear it
|
|
750
|
+
tx.clear(&key1);
|
|
751
|
+
|
|
752
|
+
// Read should return None
|
|
753
|
+
let value = tx.get(&key1, Serializable).await?;
|
|
754
|
+
assert_eq!(value, None);
|
|
755
|
+
|
|
756
|
+
Ok(())
|
|
757
|
+
})
|
|
758
|
+
.await
|
|
759
|
+
.unwrap();
|
|
760
|
+
|
|
761
|
+
// Test 3: Clear range and get
|
|
762
|
+
db.run(|tx| async move {
|
|
763
|
+
let test_subspace = Subspace::from("test");
|
|
764
|
+
let key_a = test_subspace.pack(&("raw_a",));
|
|
765
|
+
let key_b = test_subspace.pack(&("raw_b",));
|
|
766
|
+
let key_c = test_subspace.pack(&("raw_c",));
|
|
767
|
+
let key_d = test_subspace.pack(&("raw_d",));
|
|
768
|
+
|
|
769
|
+
// Set multiple values
|
|
770
|
+
tx.set(&key_a, b"value_a");
|
|
771
|
+
tx.set(&key_b, b"value_b");
|
|
772
|
+
tx.set(&key_c, b"value_c");
|
|
773
|
+
tx.set(&key_d, b"value_d");
|
|
774
|
+
|
|
775
|
+
// Clear range b to d (exclusive)
|
|
776
|
+
tx.clear_range(&key_b, &key_d);
|
|
777
|
+
|
|
778
|
+
// Check values
|
|
779
|
+
assert_eq!(
|
|
780
|
+
tx.get(&key_a, Serializable).await?,
|
|
781
|
+
Some(b"value_a".to_vec().into())
|
|
782
|
+
);
|
|
783
|
+
assert_eq!(tx.get(&key_b, Serializable).await?, None);
|
|
784
|
+
assert_eq!(tx.get(&key_c, Serializable).await?, None);
|
|
785
|
+
assert_eq!(
|
|
786
|
+
tx.get(&key_d, Serializable).await?,
|
|
787
|
+
Some(b"value_d".to_vec().into())
|
|
788
|
+
);
|
|
789
|
+
|
|
790
|
+
Ok(())
|
|
791
|
+
})
|
|
792
|
+
.await
|
|
793
|
+
.unwrap();
|
|
794
|
+
|
|
795
|
+
// Test 4: Get range with local modifications
|
|
796
|
+
db.run(|tx| async move {
|
|
797
|
+
let test_subspace = Subspace::from("test");
|
|
798
|
+
let range_key1 = test_subspace.pack(&("range_key1",));
|
|
799
|
+
let range_key3 = test_subspace.pack(&("range_key3",));
|
|
800
|
+
|
|
801
|
+
// Set some values in transaction
|
|
802
|
+
tx.set(&range_key1, b"new_value1");
|
|
803
|
+
tx.set(&range_key3, b"value3");
|
|
804
|
+
|
|
805
|
+
// Get range
|
|
806
|
+
let begin = test_subspace.pack(&("range_",));
|
|
807
|
+
let end = test_subspace.pack(&("range_z",));
|
|
808
|
+
let range_opt = RangeOption {
|
|
809
|
+
begin: KeySelector::first_greater_or_equal(Cow::Owned(begin)),
|
|
810
|
+
end: KeySelector::first_greater_or_equal(Cow::Owned(end)),
|
|
811
|
+
..RangeOption::default()
|
|
812
|
+
};
|
|
813
|
+
let values = tx.get_range(&range_opt, 1, Serializable).await?;
|
|
814
|
+
|
|
815
|
+
let mut keys = Vec::new();
|
|
816
|
+
for kv in values.into_iter() {
|
|
817
|
+
keys.push(kv.key().to_vec());
|
|
818
|
+
}
|
|
819
|
+
|
|
820
|
+
// Should see all keys in range
|
|
821
|
+
assert!(keys.contains(&range_key1));
|
|
822
|
+
assert!(keys.contains(&range_key3));
|
|
823
|
+
|
|
824
|
+
Ok(())
|
|
825
|
+
})
|
|
826
|
+
.await
|
|
827
|
+
.unwrap();
|
|
828
|
+
|
|
829
|
+
// Test 5: Overwrite value multiple times
|
|
830
|
+
db.run(|tx| async move {
|
|
831
|
+
let test_subspace = Subspace::from("test");
|
|
832
|
+
let key = test_subspace.pack(&("overwrite_key",));
|
|
833
|
+
|
|
834
|
+
tx.set(&key, b"value1");
|
|
835
|
+
assert_eq!(
|
|
836
|
+
tx.get(&key, Serializable).await?,
|
|
837
|
+
Some(b"value1".to_vec().into())
|
|
838
|
+
);
|
|
839
|
+
|
|
840
|
+
tx.set(&key, b"value2");
|
|
841
|
+
assert_eq!(
|
|
842
|
+
tx.get(&key, Serializable).await?,
|
|
843
|
+
Some(b"value2".to_vec().into())
|
|
844
|
+
);
|
|
845
|
+
|
|
846
|
+
tx.set(&key, b"value3");
|
|
847
|
+
assert_eq!(
|
|
848
|
+
tx.get(&key, Serializable).await?,
|
|
849
|
+
Some(b"value3".to_vec().into())
|
|
850
|
+
);
|
|
851
|
+
|
|
852
|
+
Ok(())
|
|
853
|
+
})
|
|
854
|
+
.await
|
|
855
|
+
.unwrap();
|
|
856
|
+
}
|
|
857
|
+
|
|
858
|
+
async fn test_set_clear_set(db: &Database) {
|
|
859
|
+
// Test the bug where set → clear → set sequence doesn't work correctly
|
|
860
|
+
db.run(|tx| async move {
|
|
861
|
+
let test_subspace = Subspace::from("test");
|
|
862
|
+
let key = test_subspace.pack(&("bug_key",));
|
|
863
|
+
|
|
864
|
+
// Set initial value
|
|
865
|
+
tx.set(&key, b"value1");
|
|
866
|
+
|
|
867
|
+
// Clear the key
|
|
868
|
+
tx.clear(&key);
|
|
869
|
+
|
|
870
|
+
// Set a new value
|
|
871
|
+
tx.set(&key, b"value2");
|
|
872
|
+
|
|
873
|
+
// This should return the latest value "value2", not None or Cleared
|
|
874
|
+
let value = tx.get(&key, Serializable).await?;
|
|
875
|
+
assert_eq!(
|
|
876
|
+
value,
|
|
877
|
+
Some(b"value2".to_vec().into()),
|
|
878
|
+
"Expected to get the latest set value after set-clear-set sequence"
|
|
879
|
+
);
|
|
880
|
+
|
|
881
|
+
Ok(())
|
|
882
|
+
})
|
|
883
|
+
.await
|
|
884
|
+
.unwrap();
|
|
885
|
+
}
|
|
886
|
+
|
|
887
|
+
async fn test_get_key_with_local_writes(db: &Database) {
|
|
888
|
+
// Setup: Store keys with values 2 and 10 in the database
|
|
889
|
+
db.run(|tx| async move {
|
|
890
|
+
let test_subspace = Subspace::from("test");
|
|
891
|
+
let key2 = test_subspace.pack(&(2,));
|
|
892
|
+
let key10 = test_subspace.pack(&(10,));
|
|
893
|
+
tx.set(&key2, b"value2");
|
|
894
|
+
tx.set(&key10, b"value10");
|
|
895
|
+
Ok(())
|
|
896
|
+
})
|
|
897
|
+
.await
|
|
898
|
+
.unwrap();
|
|
899
|
+
|
|
900
|
+
// Test: Write a key with value 5 in the transaction, then get_key with >= 3
|
|
901
|
+
let result_key = db
|
|
902
|
+
.run(|tx| async move {
|
|
903
|
+
let test_subspace = Subspace::from("test");
|
|
904
|
+
|
|
905
|
+
// Write key 5 in the transaction
|
|
906
|
+
let key5 = test_subspace.pack(&(5,));
|
|
907
|
+
tx.set(&key5, b"value5");
|
|
908
|
+
|
|
909
|
+
// Use get_key with >= 3 selector
|
|
910
|
+
let search_key = test_subspace.pack(&(3,));
|
|
911
|
+
let selector = KeySelector::first_greater_or_equal(Cow::Owned(search_key));
|
|
912
|
+
let k = tx.get_key(&selector, Serializable).await?;
|
|
913
|
+
Ok(k)
|
|
914
|
+
})
|
|
915
|
+
.await
|
|
916
|
+
.unwrap();
|
|
917
|
+
|
|
918
|
+
// Should return key5, not key10
|
|
919
|
+
let test_subspace = Subspace::from("test");
|
|
920
|
+
let expected_key5 = test_subspace.pack(&(5,));
|
|
921
|
+
assert_eq!(
|
|
922
|
+
result_key,
|
|
923
|
+
expected_key5.clone().into(),
|
|
924
|
+
"get_key should return key 5 from local writes, not key 10 from database"
|
|
925
|
+
);
|
|
926
|
+
|
|
927
|
+
// Test with first_greater_than
|
|
928
|
+
let result_key = db
|
|
929
|
+
.run(|tx| async move {
|
|
930
|
+
let test_subspace = Subspace::from("test");
|
|
931
|
+
|
|
932
|
+
// Write key 5 in the transaction
|
|
933
|
+
let key5 = test_subspace.pack(&(5,));
|
|
934
|
+
tx.set(&key5, b"value5");
|
|
935
|
+
|
|
936
|
+
// Use get_key with > 4 selector
|
|
937
|
+
let search_key = test_subspace.pack(&(4,));
|
|
938
|
+
let selector = KeySelector::first_greater_than(Cow::Owned(search_key));
|
|
939
|
+
let k = tx.get_key(&selector, Serializable).await?;
|
|
940
|
+
Ok(k)
|
|
941
|
+
})
|
|
942
|
+
.await
|
|
943
|
+
.unwrap();
|
|
944
|
+
|
|
945
|
+
// Should return key5, not key10
|
|
946
|
+
assert_eq!(
|
|
947
|
+
result_key,
|
|
948
|
+
expected_key5.into(),
|
|
949
|
+
"get_key with > selector should return key 5 from local writes"
|
|
950
|
+
);
|
|
951
|
+
}
|
|
952
|
+
|
|
953
|
+
async fn test_snapshot_reads(db: &Database) {
|
|
954
|
+
// Setup: Store initial data in the database
|
|
955
|
+
db.run(|tx| async move {
|
|
956
|
+
let test_subspace = Subspace::from("test");
|
|
957
|
+
let key1 = test_subspace.pack(&("snap_key1",));
|
|
958
|
+
let key2 = test_subspace.pack(&("snap_key2",));
|
|
959
|
+
let key3 = test_subspace.pack(&("snap_key3",));
|
|
960
|
+
|
|
961
|
+
tx.set(&key1, b"db_value1");
|
|
962
|
+
tx.set(&key2, b"db_value2");
|
|
963
|
+
tx.set(&key3, b"db_value3");
|
|
964
|
+
Ok(())
|
|
965
|
+
})
|
|
966
|
+
.await
|
|
967
|
+
.unwrap();
|
|
968
|
+
|
|
969
|
+
// Test 1: Just snapshot reads
|
|
970
|
+
db.run(|tx| async move {
|
|
971
|
+
let test_subspace = Subspace::from("test");
|
|
972
|
+
let key1 = test_subspace.pack(&("snap_key1",));
|
|
973
|
+
let key2 = test_subspace.pack(&("snap_key2",));
|
|
974
|
+
let key3 = test_subspace.pack(&("snap_key3",));
|
|
975
|
+
let _key4 = test_subspace.pack(&("snap_key4",));
|
|
976
|
+
|
|
977
|
+
// Snapshot read should see database value
|
|
978
|
+
let snapshot_value = tx.get(&key1, Snapshot).await?;
|
|
979
|
+
assert_eq!(
|
|
980
|
+
snapshot_value,
|
|
981
|
+
Some(b"db_value1".to_vec().into()),
|
|
982
|
+
"Snapshot read should see database value"
|
|
983
|
+
);
|
|
984
|
+
|
|
985
|
+
// Define range
|
|
986
|
+
let begin = test_subspace.pack(&("snap_",));
|
|
987
|
+
let end = test_subspace.pack(&("snap_z",));
|
|
988
|
+
let range_opt = RangeOption {
|
|
989
|
+
begin: KeySelector::first_greater_or_equal(Cow::Owned(begin)),
|
|
990
|
+
end: KeySelector::first_greater_or_equal(Cow::Owned(end)),
|
|
991
|
+
..RangeOption::default()
|
|
992
|
+
};
|
|
993
|
+
|
|
994
|
+
// Snapshot range read
|
|
995
|
+
let snapshot_values = tx.get_range(&range_opt, 1, Snapshot).await?;
|
|
996
|
+
let mut snapshot_keys = Vec::new();
|
|
997
|
+
for kv in snapshot_values.into_iter() {
|
|
998
|
+
snapshot_keys.push((kv.key().to_vec(), kv.value().to_vec()));
|
|
999
|
+
}
|
|
1000
|
+
|
|
1001
|
+
// Should also see lcoal writes
|
|
1002
|
+
assert_eq!(snapshot_keys.len(), 3, "Expected 3 keys from database");
|
|
1003
|
+
assert!(
|
|
1004
|
+
snapshot_keys
|
|
1005
|
+
.iter()
|
|
1006
|
+
.any(|(k, v)| k == &key1 && v == b"db_value1")
|
|
1007
|
+
);
|
|
1008
|
+
assert!(
|
|
1009
|
+
snapshot_keys
|
|
1010
|
+
.iter()
|
|
1011
|
+
.any(|(k, v)| k == &key2 && v == b"db_value2")
|
|
1012
|
+
);
|
|
1013
|
+
assert!(
|
|
1014
|
+
snapshot_keys
|
|
1015
|
+
.iter()
|
|
1016
|
+
.any(|(k, v)| k == &key3 && v == b"db_value3")
|
|
1017
|
+
);
|
|
1018
|
+
|
|
1019
|
+
Ok(())
|
|
1020
|
+
})
|
|
1021
|
+
.await
|
|
1022
|
+
.unwrap();
|
|
1023
|
+
|
|
1024
|
+
// Test 2: Snapshot read should skip local set operations within a transaction
|
|
1025
|
+
db.run(|tx| async move {
|
|
1026
|
+
let test_subspace = Subspace::from("test");
|
|
1027
|
+
let key1 = test_subspace.pack(&("snap_key1",));
|
|
1028
|
+
|
|
1029
|
+
// Set a new value locally
|
|
1030
|
+
tx.set(&key1, b"local_value1");
|
|
1031
|
+
|
|
1032
|
+
// Non-snapshot read should see local value
|
|
1033
|
+
let value = tx.get(&key1, Serializable).await?;
|
|
1034
|
+
assert_eq!(
|
|
1035
|
+
value,
|
|
1036
|
+
Some(b"local_value1".to_vec().into()),
|
|
1037
|
+
"Non-snapshot read should see local write"
|
|
1038
|
+
);
|
|
1039
|
+
|
|
1040
|
+
// Snapshot read should see local write
|
|
1041
|
+
let snapshot_value = tx.get(&key1, Snapshot).await?;
|
|
1042
|
+
assert_eq!(
|
|
1043
|
+
snapshot_value,
|
|
1044
|
+
Some(b"local_value1".to_vec().into()),
|
|
1045
|
+
"Snapshot read should see local write"
|
|
1046
|
+
);
|
|
1047
|
+
|
|
1048
|
+
Ok(())
|
|
1049
|
+
})
|
|
1050
|
+
.await
|
|
1051
|
+
.unwrap();
|
|
1052
|
+
|
|
1053
|
+
// Reset state
|
|
1054
|
+
{
|
|
1055
|
+
clear_test_namespace(&db).await.unwrap();
|
|
1056
|
+
db.run(|tx| async move {
|
|
1057
|
+
let test_subspace = Subspace::from("test");
|
|
1058
|
+
let key1 = test_subspace.pack(&("snap_key1",));
|
|
1059
|
+
let key2 = test_subspace.pack(&("snap_key2",));
|
|
1060
|
+
let key3 = test_subspace.pack(&("snap_key3",));
|
|
1061
|
+
|
|
1062
|
+
tx.set(&key1, b"db_value1");
|
|
1063
|
+
tx.set(&key2, b"db_value2");
|
|
1064
|
+
tx.set(&key3, b"db_value3");
|
|
1065
|
+
Ok(())
|
|
1066
|
+
})
|
|
1067
|
+
.await
|
|
1068
|
+
.unwrap();
|
|
1069
|
+
}
|
|
1070
|
+
|
|
1071
|
+
// Test 3: Snapshot read should skip local clear operations
|
|
1072
|
+
db.run(|tx| async move {
|
|
1073
|
+
let test_subspace = Subspace::from("test");
|
|
1074
|
+
let key2 = test_subspace.pack(&("snap_key2",));
|
|
1075
|
+
|
|
1076
|
+
// Clear the key locally
|
|
1077
|
+
tx.clear(&key2);
|
|
1078
|
+
|
|
1079
|
+
// Non-snapshot read should see None (cleared)
|
|
1080
|
+
let value = tx.get(&key2, Serializable).await?;
|
|
1081
|
+
assert_eq!(value, None, "Non-snapshot read should see cleared value");
|
|
1082
|
+
|
|
1083
|
+
// Snapshot read should still see database value
|
|
1084
|
+
let snapshot_value = tx.get(&key2, Snapshot).await?;
|
|
1085
|
+
assert_eq!(snapshot_value, None, "Snapshot read should see local clear");
|
|
1086
|
+
|
|
1087
|
+
Ok(())
|
|
1088
|
+
})
|
|
1089
|
+
.await
|
|
1090
|
+
.unwrap();
|
|
1091
|
+
|
|
1092
|
+
// Reset state
|
|
1093
|
+
{
|
|
1094
|
+
clear_test_namespace(&db).await.unwrap();
|
|
1095
|
+
db.run(|tx| async move {
|
|
1096
|
+
let test_subspace = Subspace::from("test");
|
|
1097
|
+
let key1 = test_subspace.pack(&("snap_key1",));
|
|
1098
|
+
let key2 = test_subspace.pack(&("snap_key2",));
|
|
1099
|
+
let key3 = test_subspace.pack(&("snap_key3",));
|
|
1100
|
+
|
|
1101
|
+
tx.set(&key1, b"db_value1");
|
|
1102
|
+
tx.set(&key2, b"db_value2");
|
|
1103
|
+
tx.set(&key3, b"db_value3");
|
|
1104
|
+
Ok(())
|
|
1105
|
+
})
|
|
1106
|
+
.await
|
|
1107
|
+
.unwrap();
|
|
1108
|
+
}
|
|
1109
|
+
|
|
1110
|
+
// Test 4: Snapshot get_range should skip local operations
|
|
1111
|
+
db.run(|tx| async move {
|
|
1112
|
+
let test_subspace = Subspace::from("test");
|
|
1113
|
+
let key1 = test_subspace.pack(&("snap_key1",));
|
|
1114
|
+
let key2 = test_subspace.pack(&("snap_key2",));
|
|
1115
|
+
let key3 = test_subspace.pack(&("snap_key3",));
|
|
1116
|
+
let key4 = test_subspace.pack(&("snap_key4",));
|
|
1117
|
+
|
|
1118
|
+
// Local modifications
|
|
1119
|
+
tx.set(&key1, b"modified1");
|
|
1120
|
+
tx.clear(&key2);
|
|
1121
|
+
tx.set(&key4, b"new_local_value");
|
|
1122
|
+
|
|
1123
|
+
// Define range
|
|
1124
|
+
let begin = test_subspace.pack(&("snap_",));
|
|
1125
|
+
let end = test_subspace.pack(&("snap_z",));
|
|
1126
|
+
let range_opt = RangeOption {
|
|
1127
|
+
begin: KeySelector::first_greater_or_equal(Cow::Owned(begin)),
|
|
1128
|
+
end: KeySelector::first_greater_or_equal(Cow::Owned(end)),
|
|
1129
|
+
..RangeOption::default()
|
|
1130
|
+
};
|
|
1131
|
+
|
|
1132
|
+
// Non-snapshot range read
|
|
1133
|
+
let values = tx.get_range(&range_opt, 1, Serializable).await?;
|
|
1134
|
+
let mut non_snapshot_keys = Vec::new();
|
|
1135
|
+
for kv in values.into_iter() {
|
|
1136
|
+
non_snapshot_keys.push((kv.key().to_vec(), kv.value().to_vec()));
|
|
1137
|
+
}
|
|
1138
|
+
|
|
1139
|
+
// Should see: key1 with modified value, key2 missing (cleared), key3 unchanged, key4 new
|
|
1140
|
+
assert_eq!(non_snapshot_keys.len(), 3);
|
|
1141
|
+
assert!(
|
|
1142
|
+
non_snapshot_keys
|
|
1143
|
+
.iter()
|
|
1144
|
+
.any(|(k, v)| k == &key1 && v == b"modified1")
|
|
1145
|
+
);
|
|
1146
|
+
assert!(!non_snapshot_keys.iter().any(|(k, _)| k == &key2)); // cleared
|
|
1147
|
+
assert!(
|
|
1148
|
+
non_snapshot_keys
|
|
1149
|
+
.iter()
|
|
1150
|
+
.any(|(k, v)| k == &key3 && v == b"db_value3")
|
|
1151
|
+
);
|
|
1152
|
+
assert!(
|
|
1153
|
+
non_snapshot_keys
|
|
1154
|
+
.iter()
|
|
1155
|
+
.any(|(k, v)| k == &key4 && v == b"new_local_value")
|
|
1156
|
+
);
|
|
1157
|
+
|
|
1158
|
+
// Snapshot range read
|
|
1159
|
+
let snapshot_values = tx.get_range(&range_opt, 1, Snapshot).await?;
|
|
1160
|
+
let mut snapshot_keys = Vec::new();
|
|
1161
|
+
for kv in snapshot_values.into_iter() {
|
|
1162
|
+
snapshot_keys.push((kv.key().to_vec(), kv.value().to_vec()));
|
|
1163
|
+
}
|
|
1164
|
+
|
|
1165
|
+
// Should also see lcoal writes
|
|
1166
|
+
assert_eq!(snapshot_keys.len(), 3, "Expected 3 keys from database");
|
|
1167
|
+
assert!(
|
|
1168
|
+
snapshot_keys
|
|
1169
|
+
.iter()
|
|
1170
|
+
.any(|(k, v)| k == &key1 && v == b"modified1")
|
|
1171
|
+
);
|
|
1172
|
+
assert!(!snapshot_keys.iter().any(|(k, _)| k == &key2)); // cleared
|
|
1173
|
+
assert!(
|
|
1174
|
+
snapshot_keys
|
|
1175
|
+
.iter()
|
|
1176
|
+
.any(|(k, v)| k == &key3 && v == b"db_value3")
|
|
1177
|
+
);
|
|
1178
|
+
assert!(
|
|
1179
|
+
snapshot_keys
|
|
1180
|
+
.iter()
|
|
1181
|
+
.any(|(k, v)| k == &key4 && v == b"new_local_value")
|
|
1182
|
+
);
|
|
1183
|
+
|
|
1184
|
+
Ok(())
|
|
1185
|
+
})
|
|
1186
|
+
.await
|
|
1187
|
+
.unwrap();
|
|
1188
|
+
|
|
1189
|
+
// Reset state
|
|
1190
|
+
{
|
|
1191
|
+
clear_test_namespace(&db).await.unwrap();
|
|
1192
|
+
db.run(|tx| async move {
|
|
1193
|
+
let test_subspace = Subspace::from("test");
|
|
1194
|
+
let key1 = test_subspace.pack(&("snap_key1",));
|
|
1195
|
+
let key2 = test_subspace.pack(&("snap_key2",));
|
|
1196
|
+
let key3 = test_subspace.pack(&("snap_key3",));
|
|
1197
|
+
|
|
1198
|
+
tx.set(&key1, b"db_value1");
|
|
1199
|
+
tx.set(&key2, b"db_value2");
|
|
1200
|
+
tx.set(&key3, b"db_value3");
|
|
1201
|
+
Ok(())
|
|
1202
|
+
})
|
|
1203
|
+
.await
|
|
1204
|
+
.unwrap();
|
|
1205
|
+
}
|
|
1206
|
+
|
|
1207
|
+
// Test 5: Snapshot get_key should skip local operations
|
|
1208
|
+
db.run(|tx| async move {
|
|
1209
|
+
let test_subspace = Subspace::from("test");
|
|
1210
|
+
|
|
1211
|
+
// Add a local key between existing database keys
|
|
1212
|
+
let key15 = test_subspace.pack(&("snap_key15",)); // between key1 and key2
|
|
1213
|
+
tx.set(&key15, b"local_value15");
|
|
1214
|
+
|
|
1215
|
+
// Non-snapshot get_key >= "snap_key14" should find the local key15
|
|
1216
|
+
let search_key = test_subspace.pack(&("snap_key14",));
|
|
1217
|
+
let selector = KeySelector::first_greater_or_equal(Cow::Owned(search_key));
|
|
1218
|
+
let result = tx.get_key(&selector, Serializable).await?;
|
|
1219
|
+
assert_eq!(
|
|
1220
|
+
result,
|
|
1221
|
+
key15.clone().into(),
|
|
1222
|
+
"Non-snapshot get_key should find local key"
|
|
1223
|
+
);
|
|
1224
|
+
|
|
1225
|
+
// Snapshot get_key >= "snap_key14" should find the local key15
|
|
1226
|
+
let snapshot_result = tx.get_key(&selector, Snapshot).await?;
|
|
1227
|
+
assert_eq!(
|
|
1228
|
+
snapshot_result,
|
|
1229
|
+
key15.into(),
|
|
1230
|
+
"Snapshot get_key should find local key"
|
|
1231
|
+
);
|
|
1232
|
+
|
|
1233
|
+
Ok(())
|
|
1234
|
+
})
|
|
1235
|
+
.await
|
|
1236
|
+
.unwrap();
|
|
1237
|
+
}
|
|
1238
|
+
|
|
1239
|
+
async fn test_atomic_operations(db: &Database) {
|
|
1240
|
+
// Test Add operation
|
|
1241
|
+
test_atomic_add(&db).await;
|
|
1242
|
+
clear_test_namespace(&db).await.unwrap();
|
|
1243
|
+
|
|
1244
|
+
// Test bitwise operations
|
|
1245
|
+
test_atomic_bitwise(&db).await;
|
|
1246
|
+
clear_test_namespace(&db).await.unwrap();
|
|
1247
|
+
|
|
1248
|
+
// Test append if fits operation
|
|
1249
|
+
test_atomic_append_if_fits(&db).await;
|
|
1250
|
+
clear_test_namespace(&db).await.unwrap();
|
|
1251
|
+
|
|
1252
|
+
// Test min/max operations
|
|
1253
|
+
test_atomic_min_max(&db).await;
|
|
1254
|
+
clear_test_namespace(&db).await.unwrap();
|
|
1255
|
+
|
|
1256
|
+
// Test byte min/max operations
|
|
1257
|
+
test_atomic_byte_min_max(&db).await;
|
|
1258
|
+
clear_test_namespace(&db).await.unwrap();
|
|
1259
|
+
|
|
1260
|
+
// Test compare and clear operation
|
|
1261
|
+
test_atomic_compare_and_clear(&db).await;
|
|
1262
|
+
clear_test_namespace(&db).await.unwrap();
|
|
1263
|
+
|
|
1264
|
+
// Test atomic operations with transaction isolation
|
|
1265
|
+
test_atomic_transaction_isolation(&db).await;
|
|
1266
|
+
clear_test_namespace(&db).await.unwrap();
|
|
1267
|
+
|
|
1268
|
+
// Test atomic operations on non-existent keys
|
|
1269
|
+
test_atomic_nonexistent_keys(&db).await;
|
|
1270
|
+
clear_test_namespace(&db).await.unwrap();
|
|
1271
|
+
}
|
|
1272
|
+
|
|
1273
|
+
async fn test_atomic_add(db: &Database) {
|
|
1274
|
+
use universaldb::options::MutationType;
|
|
1275
|
+
|
|
1276
|
+
// Test 1: Add to non-existent key (should treat as 0)
|
|
1277
|
+
db.run(|tx| async move {
|
|
1278
|
+
let test_subspace = Subspace::from("test");
|
|
1279
|
+
let key = test_subspace.pack(&("add_key1",));
|
|
1280
|
+
|
|
1281
|
+
// Add 42 to non-existent key
|
|
1282
|
+
tx.informal()
|
|
1283
|
+
.atomic_op(&key, &42i64.to_le_bytes(), MutationType::Add);
|
|
1284
|
+
Ok(())
|
|
1285
|
+
})
|
|
1286
|
+
.await
|
|
1287
|
+
.unwrap();
|
|
1288
|
+
|
|
1289
|
+
// Verify the result
|
|
1290
|
+
let value = db
|
|
1291
|
+
.run(|tx| async move {
|
|
1292
|
+
let test_subspace = Subspace::from("test");
|
|
1293
|
+
let key = test_subspace.pack(&("add_key1",));
|
|
1294
|
+
let val = tx.get(&key, Serializable).await?;
|
|
1295
|
+
Ok(val)
|
|
1296
|
+
})
|
|
1297
|
+
.await
|
|
1298
|
+
.unwrap();
|
|
1299
|
+
|
|
1300
|
+
let result = i64::from_le_bytes(Vec::from(value.unwrap()).try_into().unwrap());
|
|
1301
|
+
assert_eq!(
|
|
1302
|
+
result, 42,
|
|
1303
|
+
"Add to non-existent key should equal the parameter"
|
|
1304
|
+
);
|
|
1305
|
+
|
|
1306
|
+
// Test 2: Add to existing value
|
|
1307
|
+
db.run(|tx| async move {
|
|
1308
|
+
let test_subspace = Subspace::from("test");
|
|
1309
|
+
let key = test_subspace.pack(&("add_key1",));
|
|
1310
|
+
|
|
1311
|
+
// Add 10 to existing value (42)
|
|
1312
|
+
tx.informal()
|
|
1313
|
+
.atomic_op(&key, &10i64.to_le_bytes(), MutationType::Add);
|
|
1314
|
+
Ok(())
|
|
1315
|
+
})
|
|
1316
|
+
.await
|
|
1317
|
+
.unwrap();
|
|
1318
|
+
|
|
1319
|
+
let value = db
|
|
1320
|
+
.run(|tx| async move {
|
|
1321
|
+
let test_subspace = Subspace::from("test");
|
|
1322
|
+
let key = test_subspace.pack(&("add_key1",));
|
|
1323
|
+
let val = tx.get(&key, Serializable).await?;
|
|
1324
|
+
Ok(val)
|
|
1325
|
+
})
|
|
1326
|
+
.await
|
|
1327
|
+
.unwrap();
|
|
1328
|
+
|
|
1329
|
+
let result = i64::from_le_bytes(Vec::from(value.unwrap()).try_into().unwrap());
|
|
1330
|
+
assert_eq!(result, 52, "42 + 10 should equal 52");
|
|
1331
|
+
|
|
1332
|
+
// Test 3: Add negative number
|
|
1333
|
+
db.run(|tx| async move {
|
|
1334
|
+
let test_subspace = Subspace::from("test");
|
|
1335
|
+
let key = test_subspace.pack(&("add_key1",));
|
|
1336
|
+
|
|
1337
|
+
// Add -20 to existing value (52)
|
|
1338
|
+
tx.informal()
|
|
1339
|
+
.atomic_op(&key, &(-20i64).to_le_bytes(), MutationType::Add);
|
|
1340
|
+
Ok(())
|
|
1341
|
+
})
|
|
1342
|
+
.await
|
|
1343
|
+
.unwrap();
|
|
1344
|
+
|
|
1345
|
+
let value = db
|
|
1346
|
+
.run(|tx| async move {
|
|
1347
|
+
let test_subspace = Subspace::from("test");
|
|
1348
|
+
let key = test_subspace.pack(&("add_key1",));
|
|
1349
|
+
let val = tx.get(&key, Serializable).await?;
|
|
1350
|
+
Ok(val)
|
|
1351
|
+
})
|
|
1352
|
+
.await
|
|
1353
|
+
.unwrap();
|
|
1354
|
+
|
|
1355
|
+
let result = i64::from_le_bytes(Vec::from(value.unwrap()).try_into().unwrap());
|
|
1356
|
+
assert_eq!(result, 32, "52 + (-20) should equal 32");
|
|
1357
|
+
|
|
1358
|
+
// Test 4: Test wrapping behavior with overflow
|
|
1359
|
+
db.run(|tx| async move {
|
|
1360
|
+
let test_subspace = Subspace::from("test");
|
|
1361
|
+
let key = test_subspace.pack(&("add_overflow",));
|
|
1362
|
+
|
|
1363
|
+
// Set initial value to max i64
|
|
1364
|
+
tx.set(&key, &i64::MAX.to_le_bytes());
|
|
1365
|
+
Ok(())
|
|
1366
|
+
})
|
|
1367
|
+
.await
|
|
1368
|
+
.unwrap();
|
|
1369
|
+
|
|
1370
|
+
db.run(|tx| async move {
|
|
1371
|
+
let test_subspace = Subspace::from("test");
|
|
1372
|
+
let key = test_subspace.pack(&("add_overflow",));
|
|
1373
|
+
|
|
1374
|
+
// Add 1 to max i64 (should wrap)
|
|
1375
|
+
tx.informal()
|
|
1376
|
+
.atomic_op(&key, &1i64.to_le_bytes(), MutationType::Add);
|
|
1377
|
+
Ok(())
|
|
1378
|
+
})
|
|
1379
|
+
.await
|
|
1380
|
+
.unwrap();
|
|
1381
|
+
|
|
1382
|
+
let value = db
|
|
1383
|
+
.run(|tx| async move {
|
|
1384
|
+
let test_subspace = Subspace::from("test");
|
|
1385
|
+
let key = test_subspace.pack(&("add_overflow",));
|
|
1386
|
+
let val = tx.get(&key, Serializable).await?;
|
|
1387
|
+
Ok(val)
|
|
1388
|
+
})
|
|
1389
|
+
.await
|
|
1390
|
+
.unwrap();
|
|
1391
|
+
|
|
1392
|
+
let result = i64::from_le_bytes(Vec::from(value.unwrap()).try_into().unwrap());
|
|
1393
|
+
assert_eq!(result, i64::MIN, "Max i64 + 1 should wrap to min i64");
|
|
1394
|
+
}
|
|
1395
|
+
|
|
1396
|
+
async fn test_atomic_bitwise(db: &Database) {
|
|
1397
|
+
use universaldb::options::MutationType;
|
|
1398
|
+
|
|
1399
|
+
// Test BitAnd operation
|
|
1400
|
+
db.run(|tx| async move {
|
|
1401
|
+
let test_subspace = Subspace::from("test");
|
|
1402
|
+
let key = test_subspace.pack(&("bit_and",));
|
|
1403
|
+
|
|
1404
|
+
// Set initial value: 0b11110000 (240)
|
|
1405
|
+
tx.set(&key, &[0b11110000]);
|
|
1406
|
+
Ok(())
|
|
1407
|
+
})
|
|
1408
|
+
.await
|
|
1409
|
+
.unwrap();
|
|
1410
|
+
|
|
1411
|
+
db.run(|tx| async move {
|
|
1412
|
+
let test_subspace = Subspace::from("test");
|
|
1413
|
+
let key = test_subspace.pack(&("bit_and",));
|
|
1414
|
+
|
|
1415
|
+
// AND with 0b10101010 (170)
|
|
1416
|
+
tx.informal()
|
|
1417
|
+
.atomic_op(&key, &[0b10101010], MutationType::BitAnd);
|
|
1418
|
+
Ok(())
|
|
1419
|
+
})
|
|
1420
|
+
.await
|
|
1421
|
+
.unwrap();
|
|
1422
|
+
|
|
1423
|
+
let value = db
|
|
1424
|
+
.run(|tx| async move {
|
|
1425
|
+
let test_subspace = Subspace::from("test");
|
|
1426
|
+
let key = test_subspace.pack(&("bit_and",));
|
|
1427
|
+
let val = tx.get(&key, Serializable).await?;
|
|
1428
|
+
Ok(val)
|
|
1429
|
+
})
|
|
1430
|
+
.await
|
|
1431
|
+
.unwrap();
|
|
1432
|
+
|
|
1433
|
+
assert_eq!(
|
|
1434
|
+
value.unwrap()[0],
|
|
1435
|
+
0b10100000,
|
|
1436
|
+
"BitAnd result should be 0b10100000 (160)"
|
|
1437
|
+
);
|
|
1438
|
+
|
|
1439
|
+
// Test BitOr operation
|
|
1440
|
+
db.run(|tx| async move {
|
|
1441
|
+
let test_subspace = Subspace::from("test");
|
|
1442
|
+
let key = test_subspace.pack(&("bit_or",));
|
|
1443
|
+
|
|
1444
|
+
// Set initial value: 0b11110000 (240)
|
|
1445
|
+
tx.set(&key, &[0b11110000]);
|
|
1446
|
+
Ok(())
|
|
1447
|
+
})
|
|
1448
|
+
.await
|
|
1449
|
+
.unwrap();
|
|
1450
|
+
|
|
1451
|
+
db.run(|tx| async move {
|
|
1452
|
+
let test_subspace = Subspace::from("test");
|
|
1453
|
+
let key = test_subspace.pack(&("bit_or",));
|
|
1454
|
+
|
|
1455
|
+
// OR with 0b00001111 (15)
|
|
1456
|
+
tx.informal()
|
|
1457
|
+
.atomic_op(&key, &[0b00001111], MutationType::BitOr);
|
|
1458
|
+
Ok(())
|
|
1459
|
+
})
|
|
1460
|
+
.await
|
|
1461
|
+
.unwrap();
|
|
1462
|
+
|
|
1463
|
+
let value = db
|
|
1464
|
+
.run(|tx| async move {
|
|
1465
|
+
let test_subspace = Subspace::from("test");
|
|
1466
|
+
let key = test_subspace.pack(&("bit_or",));
|
|
1467
|
+
let val = tx.get(&key, Serializable).await?;
|
|
1468
|
+
Ok(val)
|
|
1469
|
+
})
|
|
1470
|
+
.await
|
|
1471
|
+
.unwrap();
|
|
1472
|
+
|
|
1473
|
+
assert_eq!(
|
|
1474
|
+
value.unwrap()[0],
|
|
1475
|
+
0b11111111,
|
|
1476
|
+
"BitOr result should be 0b11111111 (255)"
|
|
1477
|
+
);
|
|
1478
|
+
|
|
1479
|
+
// Test BitXor operation
|
|
1480
|
+
db.run(|tx| async move {
|
|
1481
|
+
let test_subspace = Subspace::from("test");
|
|
1482
|
+
let key = test_subspace.pack(&("bit_xor",));
|
|
1483
|
+
|
|
1484
|
+
// Set initial value: 0b11110000 (240)
|
|
1485
|
+
tx.set(&key, &[0b11110000]);
|
|
1486
|
+
Ok(())
|
|
1487
|
+
})
|
|
1488
|
+
.await
|
|
1489
|
+
.unwrap();
|
|
1490
|
+
|
|
1491
|
+
db.run(|tx| async move {
|
|
1492
|
+
let test_subspace = Subspace::from("test");
|
|
1493
|
+
let key = test_subspace.pack(&("bit_xor",));
|
|
1494
|
+
|
|
1495
|
+
// XOR with 0b10101010 (170)
|
|
1496
|
+
tx.informal()
|
|
1497
|
+
.atomic_op(&key, &[0b10101010], MutationType::BitXor);
|
|
1498
|
+
Ok(())
|
|
1499
|
+
})
|
|
1500
|
+
.await
|
|
1501
|
+
.unwrap();
|
|
1502
|
+
|
|
1503
|
+
let value = db
|
|
1504
|
+
.run(|tx| async move {
|
|
1505
|
+
let test_subspace = Subspace::from("test");
|
|
1506
|
+
let key = test_subspace.pack(&("bit_xor",));
|
|
1507
|
+
let val = tx.get(&key, Serializable).await?;
|
|
1508
|
+
Ok(val)
|
|
1509
|
+
})
|
|
1510
|
+
.await
|
|
1511
|
+
.unwrap();
|
|
1512
|
+
|
|
1513
|
+
assert_eq!(
|
|
1514
|
+
value.unwrap()[0],
|
|
1515
|
+
0b01011010,
|
|
1516
|
+
"BitXor result should be 0b01011010 (90)"
|
|
1517
|
+
);
|
|
1518
|
+
|
|
1519
|
+
// Test bitwise operations with different lengths
|
|
1520
|
+
db.run(|tx| async move {
|
|
1521
|
+
let test_subspace = Subspace::from("test");
|
|
1522
|
+
let key = test_subspace.pack(&("bit_len",));
|
|
1523
|
+
|
|
1524
|
+
// Set 2-byte value
|
|
1525
|
+
tx.set(&key, &[0b11110000, 0b00001111]);
|
|
1526
|
+
Ok(())
|
|
1527
|
+
})
|
|
1528
|
+
.await
|
|
1529
|
+
.unwrap();
|
|
1530
|
+
|
|
1531
|
+
db.run(|tx| async move {
|
|
1532
|
+
let test_subspace = Subspace::from("test");
|
|
1533
|
+
let key = test_subspace.pack(&("bit_len",));
|
|
1534
|
+
|
|
1535
|
+
// AND with 1-byte value (should extend current to match param length)
|
|
1536
|
+
tx.informal()
|
|
1537
|
+
.atomic_op(&key, &[0b10101010], MutationType::BitAnd);
|
|
1538
|
+
Ok(())
|
|
1539
|
+
})
|
|
1540
|
+
.await
|
|
1541
|
+
.unwrap();
|
|
1542
|
+
|
|
1543
|
+
let value = db
|
|
1544
|
+
.run(|tx| async move {
|
|
1545
|
+
let test_subspace = Subspace::from("test");
|
|
1546
|
+
let key = test_subspace.pack(&("bit_len",));
|
|
1547
|
+
let val = tx.get(&key, Serializable).await?;
|
|
1548
|
+
Ok(val)
|
|
1549
|
+
})
|
|
1550
|
+
.await
|
|
1551
|
+
.unwrap();
|
|
1552
|
+
|
|
1553
|
+
let result = value.unwrap();
|
|
1554
|
+
assert_eq!(
|
|
1555
|
+
result.len(),
|
|
1556
|
+
1,
|
|
1557
|
+
"Result should be truncated to param length"
|
|
1558
|
+
);
|
|
1559
|
+
assert_eq!(
|
|
1560
|
+
result[0], 0b10100000,
|
|
1561
|
+
"Result should be correct after length adjustment"
|
|
1562
|
+
);
|
|
1563
|
+
}
|
|
1564
|
+
|
|
1565
|
+
async fn test_atomic_append_if_fits(db: &Database) {
|
|
1566
|
+
use universaldb::options::MutationType;
|
|
1567
|
+
|
|
1568
|
+
// Test 1: Append to non-existent key
|
|
1569
|
+
db.run(|tx| async move {
|
|
1570
|
+
let test_subspace = Subspace::from("test");
|
|
1571
|
+
let key = test_subspace.pack(&("append_key1",));
|
|
1572
|
+
|
|
1573
|
+
tx.informal()
|
|
1574
|
+
.atomic_op(&key, b"hello", MutationType::AppendIfFits);
|
|
1575
|
+
Ok(())
|
|
1576
|
+
})
|
|
1577
|
+
.await
|
|
1578
|
+
.unwrap();
|
|
1579
|
+
|
|
1580
|
+
let value = db
|
|
1581
|
+
.run(|tx| async move {
|
|
1582
|
+
let test_subspace = Subspace::from("test");
|
|
1583
|
+
let key = test_subspace.pack(&("append_key1",));
|
|
1584
|
+
let val = tx.get(&key, Serializable).await?;
|
|
1585
|
+
Ok(val)
|
|
1586
|
+
})
|
|
1587
|
+
.await
|
|
1588
|
+
.unwrap();
|
|
1589
|
+
|
|
1590
|
+
assert_eq!(
|
|
1591
|
+
value.unwrap().as_slice(),
|
|
1592
|
+
b"hello",
|
|
1593
|
+
"Append to non-existent key should create the key"
|
|
1594
|
+
);
|
|
1595
|
+
|
|
1596
|
+
// Test 2: Append to existing key
|
|
1597
|
+
db.run(|tx| async move {
|
|
1598
|
+
let test_subspace = Subspace::from("test");
|
|
1599
|
+
let key = test_subspace.pack(&("append_key1",));
|
|
1600
|
+
|
|
1601
|
+
tx.informal()
|
|
1602
|
+
.atomic_op(&key, b" world", MutationType::AppendIfFits);
|
|
1603
|
+
Ok(())
|
|
1604
|
+
})
|
|
1605
|
+
.await
|
|
1606
|
+
.unwrap();
|
|
1607
|
+
|
|
1608
|
+
let value = db
|
|
1609
|
+
.run(|tx| async move {
|
|
1610
|
+
let test_subspace = Subspace::from("test");
|
|
1611
|
+
let key = test_subspace.pack(&("append_key1",));
|
|
1612
|
+
let val = tx.get(&key, Serializable).await?;
|
|
1613
|
+
Ok(val)
|
|
1614
|
+
})
|
|
1615
|
+
.await
|
|
1616
|
+
.unwrap();
|
|
1617
|
+
|
|
1618
|
+
assert_eq!(
|
|
1619
|
+
value.unwrap().as_slice(),
|
|
1620
|
+
b"hello world",
|
|
1621
|
+
"Append should concatenate values"
|
|
1622
|
+
);
|
|
1623
|
+
|
|
1624
|
+
// Test 3: Append that would exceed size limit (should not append)
|
|
1625
|
+
db.run(|tx| async move {
|
|
1626
|
+
let test_subspace = Subspace::from("test");
|
|
1627
|
+
let key = test_subspace.pack(&("append_large",));
|
|
1628
|
+
|
|
1629
|
+
// Create a value close to the 100KB limit
|
|
1630
|
+
let large_value = vec![b'x'; 99_000];
|
|
1631
|
+
tx.set(&key, &large_value);
|
|
1632
|
+
Ok(())
|
|
1633
|
+
})
|
|
1634
|
+
.await
|
|
1635
|
+
.unwrap();
|
|
1636
|
+
|
|
1637
|
+
db.run(|tx| async move {
|
|
1638
|
+
let test_subspace = Subspace::from("test");
|
|
1639
|
+
let key = test_subspace.pack(&("append_large",));
|
|
1640
|
+
|
|
1641
|
+
// Try to append 2KB more (should not fit)
|
|
1642
|
+
let append_value = vec![b'y'; 2000];
|
|
1643
|
+
tx.informal()
|
|
1644
|
+
.atomic_op(&key, &append_value, MutationType::AppendIfFits);
|
|
1645
|
+
Ok(())
|
|
1646
|
+
})
|
|
1647
|
+
.await
|
|
1648
|
+
.unwrap();
|
|
1649
|
+
|
|
1650
|
+
let value = db
|
|
1651
|
+
.run(|tx| async move {
|
|
1652
|
+
let test_subspace = Subspace::from("test");
|
|
1653
|
+
let key = test_subspace.pack(&("append_large",));
|
|
1654
|
+
let val = tx.get(&key, Serializable).await?;
|
|
1655
|
+
Ok(val)
|
|
1656
|
+
})
|
|
1657
|
+
.await
|
|
1658
|
+
.unwrap();
|
|
1659
|
+
|
|
1660
|
+
let result = value.unwrap();
|
|
1661
|
+
assert_eq!(
|
|
1662
|
+
result.len(),
|
|
1663
|
+
99_000,
|
|
1664
|
+
"Value should not have been appended due to size limit"
|
|
1665
|
+
);
|
|
1666
|
+
assert!(
|
|
1667
|
+
result.iter().all(|&b| b == b'x'),
|
|
1668
|
+
"Original value should be unchanged"
|
|
1669
|
+
);
|
|
1670
|
+
}
|
|
1671
|
+
|
|
1672
|
+
async fn test_atomic_min_max(db: &Database) {
|
|
1673
|
+
use universaldb::options::MutationType;
|
|
1674
|
+
|
|
1675
|
+
// Test Max operation
|
|
1676
|
+
db.run(|tx| async move {
|
|
1677
|
+
let test_subspace = Subspace::from("test");
|
|
1678
|
+
let key = test_subspace.pack(&("max_key",));
|
|
1679
|
+
|
|
1680
|
+
// Set initial value: 10
|
|
1681
|
+
tx.set(&key, &10i64.to_le_bytes());
|
|
1682
|
+
Ok(())
|
|
1683
|
+
})
|
|
1684
|
+
.await
|
|
1685
|
+
.unwrap();
|
|
1686
|
+
|
|
1687
|
+
// Max with larger value (should replace)
|
|
1688
|
+
db.run(|tx| async move {
|
|
1689
|
+
let test_subspace = Subspace::from("test");
|
|
1690
|
+
let key = test_subspace.pack(&("max_key",));
|
|
1691
|
+
|
|
1692
|
+
tx.informal()
|
|
1693
|
+
.atomic_op(&key, &20i64.to_le_bytes(), MutationType::Max);
|
|
1694
|
+
Ok(())
|
|
1695
|
+
})
|
|
1696
|
+
.await
|
|
1697
|
+
.unwrap();
|
|
1698
|
+
|
|
1699
|
+
let value = db
|
|
1700
|
+
.run(|tx| async move {
|
|
1701
|
+
let test_subspace = Subspace::from("test");
|
|
1702
|
+
let key = test_subspace.pack(&("max_key",));
|
|
1703
|
+
let val = tx.get(&key, Serializable).await?;
|
|
1704
|
+
Ok(val)
|
|
1705
|
+
})
|
|
1706
|
+
.await
|
|
1707
|
+
.unwrap();
|
|
1708
|
+
|
|
1709
|
+
let result = i64::from_le_bytes(Vec::from(value.unwrap()).try_into().unwrap());
|
|
1710
|
+
assert_eq!(result, 20, "Max should select the larger value");
|
|
1711
|
+
|
|
1712
|
+
// Max with smaller value (should not replace)
|
|
1713
|
+
db.run(|tx| async move {
|
|
1714
|
+
let test_subspace = Subspace::from("test");
|
|
1715
|
+
let key = test_subspace.pack(&("max_key",));
|
|
1716
|
+
|
|
1717
|
+
tx.informal()
|
|
1718
|
+
.atomic_op(&key, &15i64.to_le_bytes(), MutationType::Max);
|
|
1719
|
+
Ok(())
|
|
1720
|
+
})
|
|
1721
|
+
.await
|
|
1722
|
+
.unwrap();
|
|
1723
|
+
|
|
1724
|
+
let value = db
|
|
1725
|
+
.run(|tx| async move {
|
|
1726
|
+
let test_subspace = Subspace::from("test");
|
|
1727
|
+
let key = test_subspace.pack(&("max_key",));
|
|
1728
|
+
let val = tx.get(&key, Serializable).await?;
|
|
1729
|
+
Ok(val)
|
|
1730
|
+
})
|
|
1731
|
+
.await
|
|
1732
|
+
.unwrap();
|
|
1733
|
+
|
|
1734
|
+
let result = i64::from_le_bytes(Vec::from(value.unwrap()).try_into().unwrap());
|
|
1735
|
+
assert_eq!(result, 20, "Max should keep the larger value");
|
|
1736
|
+
|
|
1737
|
+
// Test Min operation
|
|
1738
|
+
db.run(|tx| async move {
|
|
1739
|
+
let test_subspace = Subspace::from("test");
|
|
1740
|
+
let key = test_subspace.pack(&("min_key",));
|
|
1741
|
+
|
|
1742
|
+
// Set initial value: 10
|
|
1743
|
+
tx.set(&key, &10i64.to_le_bytes());
|
|
1744
|
+
Ok(())
|
|
1745
|
+
})
|
|
1746
|
+
.await
|
|
1747
|
+
.unwrap();
|
|
1748
|
+
|
|
1749
|
+
// Min with smaller value (should replace)
|
|
1750
|
+
db.run(|tx| async move {
|
|
1751
|
+
let test_subspace = Subspace::from("test");
|
|
1752
|
+
let key = test_subspace.pack(&("min_key",));
|
|
1753
|
+
|
|
1754
|
+
tx.informal()
|
|
1755
|
+
.atomic_op(&key, &5i64.to_le_bytes(), MutationType::Min);
|
|
1756
|
+
Ok(())
|
|
1757
|
+
})
|
|
1758
|
+
.await
|
|
1759
|
+
.unwrap();
|
|
1760
|
+
|
|
1761
|
+
let value = db
|
|
1762
|
+
.run(|tx| async move {
|
|
1763
|
+
let test_subspace = Subspace::from("test");
|
|
1764
|
+
let key = test_subspace.pack(&("min_key",));
|
|
1765
|
+
let val = tx.get(&key, Serializable).await?;
|
|
1766
|
+
Ok(val)
|
|
1767
|
+
})
|
|
1768
|
+
.await
|
|
1769
|
+
.unwrap();
|
|
1770
|
+
|
|
1771
|
+
let result = i64::from_le_bytes(Vec::from(value.unwrap()).try_into().unwrap());
|
|
1772
|
+
assert_eq!(result, 5, "Min should select the smaller value");
|
|
1773
|
+
|
|
1774
|
+
// Min with larger value (should not replace)
|
|
1775
|
+
db.run(|tx| async move {
|
|
1776
|
+
let test_subspace = Subspace::from("test");
|
|
1777
|
+
let key = test_subspace.pack(&("min_key",));
|
|
1778
|
+
|
|
1779
|
+
tx.informal()
|
|
1780
|
+
.atomic_op(&key, &15i64.to_le_bytes(), MutationType::Min);
|
|
1781
|
+
Ok(())
|
|
1782
|
+
})
|
|
1783
|
+
.await
|
|
1784
|
+
.unwrap();
|
|
1785
|
+
|
|
1786
|
+
let value = db
|
|
1787
|
+
.run(|tx| async move {
|
|
1788
|
+
let test_subspace = Subspace::from("test");
|
|
1789
|
+
let key = test_subspace.pack(&("min_key",));
|
|
1790
|
+
let val = tx.get(&key, Serializable).await?;
|
|
1791
|
+
Ok(val)
|
|
1792
|
+
})
|
|
1793
|
+
.await
|
|
1794
|
+
.unwrap();
|
|
1795
|
+
|
|
1796
|
+
let result = i64::from_le_bytes(Vec::from(value.unwrap()).try_into().unwrap());
|
|
1797
|
+
assert_eq!(result, 5, "Min should keep the smaller value");
|
|
1798
|
+
|
|
1799
|
+
// Test Max/Min with non-existent key
|
|
1800
|
+
db.run(|tx| async move {
|
|
1801
|
+
let test_subspace = Subspace::from("test");
|
|
1802
|
+
let key = test_subspace.pack(&("max_nonexistent",));
|
|
1803
|
+
|
|
1804
|
+
tx.informal()
|
|
1805
|
+
.atomic_op(&key, &42i64.to_le_bytes(), MutationType::Max);
|
|
1806
|
+
Ok(())
|
|
1807
|
+
})
|
|
1808
|
+
.await
|
|
1809
|
+
.unwrap();
|
|
1810
|
+
|
|
1811
|
+
let value = db
|
|
1812
|
+
.run(|tx| async move {
|
|
1813
|
+
let test_subspace = Subspace::from("test");
|
|
1814
|
+
let key = test_subspace.pack(&("max_nonexistent",));
|
|
1815
|
+
let val = tx.get(&key, Serializable).await?;
|
|
1816
|
+
Ok(val)
|
|
1817
|
+
})
|
|
1818
|
+
.await
|
|
1819
|
+
.unwrap();
|
|
1820
|
+
|
|
1821
|
+
let result = i64::from_le_bytes(Vec::from(value.unwrap()).try_into().unwrap());
|
|
1822
|
+
assert_eq!(result, 42, "Max on non-existent key should set the value");
|
|
1823
|
+
}
|
|
1824
|
+
|
|
1825
|
+
async fn test_atomic_byte_min_max(db: &Database) {
|
|
1826
|
+
use universaldb::options::MutationType;
|
|
1827
|
+
|
|
1828
|
+
// Test ByteMax operation (lexicographic comparison)
|
|
1829
|
+
db.run(|tx| async move {
|
|
1830
|
+
let test_subspace = Subspace::from("test");
|
|
1831
|
+
let key = test_subspace.pack(&("byte_max",));
|
|
1832
|
+
|
|
1833
|
+
// Set initial value: "banana"
|
|
1834
|
+
tx.set(&key, b"banana");
|
|
1835
|
+
Ok(())
|
|
1836
|
+
})
|
|
1837
|
+
.await
|
|
1838
|
+
.unwrap();
|
|
1839
|
+
|
|
1840
|
+
// ByteMax with lexicographically larger string (should replace)
|
|
1841
|
+
db.run(|tx| async move {
|
|
1842
|
+
let test_subspace = Subspace::from("test");
|
|
1843
|
+
let key = test_subspace.pack(&("byte_max",));
|
|
1844
|
+
|
|
1845
|
+
tx.informal()
|
|
1846
|
+
.atomic_op(&key, b"cherry", MutationType::ByteMax);
|
|
1847
|
+
Ok(())
|
|
1848
|
+
})
|
|
1849
|
+
.await
|
|
1850
|
+
.unwrap();
|
|
1851
|
+
|
|
1852
|
+
let value = db
|
|
1853
|
+
.run(|tx| async move {
|
|
1854
|
+
let test_subspace = Subspace::from("test");
|
|
1855
|
+
let key = test_subspace.pack(&("byte_max",));
|
|
1856
|
+
let val = tx.get(&key, Serializable).await?;
|
|
1857
|
+
Ok(val)
|
|
1858
|
+
})
|
|
1859
|
+
.await
|
|
1860
|
+
.unwrap();
|
|
1861
|
+
|
|
1862
|
+
assert_eq!(
|
|
1863
|
+
value.unwrap().as_slice(),
|
|
1864
|
+
b"cherry",
|
|
1865
|
+
"ByteMax should select lexicographically larger value"
|
|
1866
|
+
);
|
|
1867
|
+
|
|
1868
|
+
// ByteMax with lexicographically smaller string (should not replace)
|
|
1869
|
+
db.run(|tx| async move {
|
|
1870
|
+
let test_subspace = Subspace::from("test");
|
|
1871
|
+
let key = test_subspace.pack(&("byte_max",));
|
|
1872
|
+
|
|
1873
|
+
tx.informal()
|
|
1874
|
+
.atomic_op(&key, b"apple", MutationType::ByteMax);
|
|
1875
|
+
Ok(())
|
|
1876
|
+
})
|
|
1877
|
+
.await
|
|
1878
|
+
.unwrap();
|
|
1879
|
+
|
|
1880
|
+
let value = db
|
|
1881
|
+
.run(|tx| async move {
|
|
1882
|
+
let test_subspace = Subspace::from("test");
|
|
1883
|
+
let key = test_subspace.pack(&("byte_max",));
|
|
1884
|
+
let val = tx.get(&key, Serializable).await?;
|
|
1885
|
+
Ok(val)
|
|
1886
|
+
})
|
|
1887
|
+
.await
|
|
1888
|
+
.unwrap();
|
|
1889
|
+
|
|
1890
|
+
assert_eq!(
|
|
1891
|
+
value.unwrap().as_slice(),
|
|
1892
|
+
b"cherry",
|
|
1893
|
+
"ByteMax should keep lexicographically larger value"
|
|
1894
|
+
);
|
|
1895
|
+
|
|
1896
|
+
// Test ByteMin operation
|
|
1897
|
+
db.run(|tx| async move {
|
|
1898
|
+
let test_subspace = Subspace::from("test");
|
|
1899
|
+
let key = test_subspace.pack(&("byte_min",));
|
|
1900
|
+
|
|
1901
|
+
// Set initial value: "banana"
|
|
1902
|
+
tx.set(&key, b"banana");
|
|
1903
|
+
Ok(())
|
|
1904
|
+
})
|
|
1905
|
+
.await
|
|
1906
|
+
.unwrap();
|
|
1907
|
+
|
|
1908
|
+
// ByteMin with lexicographically smaller string (should replace)
|
|
1909
|
+
db.run(|tx| async move {
|
|
1910
|
+
let test_subspace = Subspace::from("test");
|
|
1911
|
+
let key = test_subspace.pack(&("byte_min",));
|
|
1912
|
+
|
|
1913
|
+
tx.informal()
|
|
1914
|
+
.atomic_op(&key, b"apple", MutationType::ByteMin);
|
|
1915
|
+
Ok(())
|
|
1916
|
+
})
|
|
1917
|
+
.await
|
|
1918
|
+
.unwrap();
|
|
1919
|
+
|
|
1920
|
+
let value = db
|
|
1921
|
+
.run(|tx| async move {
|
|
1922
|
+
let test_subspace = Subspace::from("test");
|
|
1923
|
+
let key = test_subspace.pack(&("byte_min",));
|
|
1924
|
+
let val = tx.get(&key, Serializable).await?;
|
|
1925
|
+
Ok(val)
|
|
1926
|
+
})
|
|
1927
|
+
.await
|
|
1928
|
+
.unwrap();
|
|
1929
|
+
|
|
1930
|
+
assert_eq!(
|
|
1931
|
+
value.unwrap().as_slice(),
|
|
1932
|
+
b"apple",
|
|
1933
|
+
"ByteMin should select lexicographically smaller value"
|
|
1934
|
+
);
|
|
1935
|
+
|
|
1936
|
+
// ByteMin with lexicographically larger string (should not replace)
|
|
1937
|
+
db.run(|tx| async move {
|
|
1938
|
+
let test_subspace = Subspace::from("test");
|
|
1939
|
+
let key = test_subspace.pack(&("byte_min",));
|
|
1940
|
+
|
|
1941
|
+
tx.informal()
|
|
1942
|
+
.atomic_op(&key, b"cherry", MutationType::ByteMin);
|
|
1943
|
+
Ok(())
|
|
1944
|
+
})
|
|
1945
|
+
.await
|
|
1946
|
+
.unwrap();
|
|
1947
|
+
|
|
1948
|
+
let value = db
|
|
1949
|
+
.run(|tx| async move {
|
|
1950
|
+
let test_subspace = Subspace::from("test");
|
|
1951
|
+
let key = test_subspace.pack(&("byte_min",));
|
|
1952
|
+
let val = tx.get(&key, Serializable).await?;
|
|
1953
|
+
Ok(val)
|
|
1954
|
+
})
|
|
1955
|
+
.await
|
|
1956
|
+
.unwrap();
|
|
1957
|
+
|
|
1958
|
+
assert_eq!(
|
|
1959
|
+
value.unwrap().as_slice(),
|
|
1960
|
+
b"apple",
|
|
1961
|
+
"ByteMin should keep lexicographically smaller value"
|
|
1962
|
+
);
|
|
1963
|
+
|
|
1964
|
+
// Test ByteMin/ByteMax with non-existent key
|
|
1965
|
+
db.run(|tx| async move {
|
|
1966
|
+
let test_subspace = Subspace::from("test");
|
|
1967
|
+
let key = test_subspace.pack(&("byte_nonexistent",));
|
|
1968
|
+
|
|
1969
|
+
tx.informal()
|
|
1970
|
+
.atomic_op(&key, b"first", MutationType::ByteMin);
|
|
1971
|
+
Ok(())
|
|
1972
|
+
})
|
|
1973
|
+
.await
|
|
1974
|
+
.unwrap();
|
|
1975
|
+
|
|
1976
|
+
let value = db
|
|
1977
|
+
.run(|tx| async move {
|
|
1978
|
+
let test_subspace = Subspace::from("test");
|
|
1979
|
+
let key = test_subspace.pack(&("byte_nonexistent",));
|
|
1980
|
+
let val = tx.get(&key, Serializable).await?;
|
|
1981
|
+
Ok(val)
|
|
1982
|
+
})
|
|
1983
|
+
.await
|
|
1984
|
+
.unwrap();
|
|
1985
|
+
|
|
1986
|
+
assert_eq!(
|
|
1987
|
+
value.unwrap().as_slice(),
|
|
1988
|
+
b"first",
|
|
1989
|
+
"ByteMin on non-existent key should set the value"
|
|
1990
|
+
);
|
|
1991
|
+
}
|
|
1992
|
+
|
|
1993
|
+
async fn test_atomic_compare_and_clear(db: &Database) {
|
|
1994
|
+
use universaldb::options::MutationType;
|
|
1995
|
+
|
|
1996
|
+
// Test 1: Compare and clear with matching value
|
|
1997
|
+
db.run(|tx| async move {
|
|
1998
|
+
let test_subspace = Subspace::from("test");
|
|
1999
|
+
let key = test_subspace.pack(&("cac_key1",));
|
|
2000
|
+
|
|
2001
|
+
// Set initial value
|
|
2002
|
+
tx.set(&key, b"target_value");
|
|
2003
|
+
Ok(())
|
|
2004
|
+
})
|
|
2005
|
+
.await
|
|
2006
|
+
.unwrap();
|
|
2007
|
+
|
|
2008
|
+
db.run(|tx| async move {
|
|
2009
|
+
let test_subspace = Subspace::from("test");
|
|
2010
|
+
let key = test_subspace.pack(&("cac_key1",));
|
|
2011
|
+
|
|
2012
|
+
// Compare and clear with matching value
|
|
2013
|
+
tx.informal()
|
|
2014
|
+
.atomic_op(&key, b"target_value", MutationType::CompareAndClear);
|
|
2015
|
+
Ok(())
|
|
2016
|
+
})
|
|
2017
|
+
.await
|
|
2018
|
+
.unwrap();
|
|
2019
|
+
|
|
2020
|
+
let value = db
|
|
2021
|
+
.run(|tx| async move {
|
|
2022
|
+
let test_subspace = Subspace::from("test");
|
|
2023
|
+
let key = test_subspace.pack(&("cac_key1",));
|
|
2024
|
+
let val = tx.get(&key, Serializable).await?;
|
|
2025
|
+
Ok(val)
|
|
2026
|
+
})
|
|
2027
|
+
.await
|
|
2028
|
+
.unwrap();
|
|
2029
|
+
|
|
2030
|
+
assert_eq!(value, None, "Key should be cleared when values match");
|
|
2031
|
+
|
|
2032
|
+
// Test 2: Compare and clear with non-matching value
|
|
2033
|
+
db.run(|tx| async move {
|
|
2034
|
+
let test_subspace = Subspace::from("test");
|
|
2035
|
+
let key = test_subspace.pack(&("cac_key2",));
|
|
2036
|
+
|
|
2037
|
+
// Set initial value
|
|
2038
|
+
tx.set(&key, b"keep_this");
|
|
2039
|
+
Ok(())
|
|
2040
|
+
})
|
|
2041
|
+
.await
|
|
2042
|
+
.unwrap();
|
|
2043
|
+
|
|
2044
|
+
db.run(|tx| async move {
|
|
2045
|
+
let test_subspace = Subspace::from("test");
|
|
2046
|
+
let key = test_subspace.pack(&("cac_key2",));
|
|
2047
|
+
|
|
2048
|
+
// Compare and clear with non-matching value
|
|
2049
|
+
tx.informal()
|
|
2050
|
+
.atomic_op(&key, b"different_value", MutationType::CompareAndClear);
|
|
2051
|
+
Ok(())
|
|
2052
|
+
})
|
|
2053
|
+
.await
|
|
2054
|
+
.unwrap();
|
|
2055
|
+
|
|
2056
|
+
let value = db
|
|
2057
|
+
.run(|tx| async move {
|
|
2058
|
+
let test_subspace = Subspace::from("test");
|
|
2059
|
+
let key = test_subspace.pack(&("cac_key2",));
|
|
2060
|
+
let val = tx.get(&key, Serializable).await?;
|
|
2061
|
+
Ok(val)
|
|
2062
|
+
})
|
|
2063
|
+
.await
|
|
2064
|
+
.unwrap();
|
|
2065
|
+
|
|
2066
|
+
assert_eq!(
|
|
2067
|
+
value.unwrap().as_slice(),
|
|
2068
|
+
b"keep_this",
|
|
2069
|
+
"Key should remain unchanged when values don't match"
|
|
2070
|
+
);
|
|
2071
|
+
|
|
2072
|
+
// Test 3: Compare and clear on non-existent key
|
|
2073
|
+
db.run(|tx| async move {
|
|
2074
|
+
let test_subspace = Subspace::from("test");
|
|
2075
|
+
let key = test_subspace.pack(&("cac_nonexistent",));
|
|
2076
|
+
|
|
2077
|
+
// Compare and clear on non-existent key (treated as empty value)
|
|
2078
|
+
tx.informal()
|
|
2079
|
+
.atomic_op(&key, b"", MutationType::CompareAndClear);
|
|
2080
|
+
Ok(())
|
|
2081
|
+
})
|
|
2082
|
+
.await
|
|
2083
|
+
.unwrap();
|
|
2084
|
+
|
|
2085
|
+
let value = db
|
|
2086
|
+
.run(|tx| async move {
|
|
2087
|
+
let test_subspace = Subspace::from("test");
|
|
2088
|
+
let key = test_subspace.pack(&("cac_nonexistent",));
|
|
2089
|
+
let val = tx.get(&key, Serializable).await?;
|
|
2090
|
+
Ok(val)
|
|
2091
|
+
})
|
|
2092
|
+
.await
|
|
2093
|
+
.unwrap();
|
|
2094
|
+
|
|
2095
|
+
assert_eq!(
|
|
2096
|
+
value, None,
|
|
2097
|
+
"Non-existent key should be cleared when comparing with empty value"
|
|
2098
|
+
);
|
|
2099
|
+
|
|
2100
|
+
// Test 4: Compare and clear with empty value on existing key
|
|
2101
|
+
db.run(|tx| async move {
|
|
2102
|
+
let test_subspace = Subspace::from("test");
|
|
2103
|
+
let key = test_subspace.pack(&("cac_empty",));
|
|
2104
|
+
|
|
2105
|
+
// Set empty value
|
|
2106
|
+
tx.set(&key, b"");
|
|
2107
|
+
Ok(())
|
|
2108
|
+
})
|
|
2109
|
+
.await
|
|
2110
|
+
.unwrap();
|
|
2111
|
+
|
|
2112
|
+
db.run(|tx| async move {
|
|
2113
|
+
let test_subspace = Subspace::from("test");
|
|
2114
|
+
let key = test_subspace.pack(&("cac_empty",));
|
|
2115
|
+
|
|
2116
|
+
// Compare and clear with empty value
|
|
2117
|
+
tx.informal()
|
|
2118
|
+
.atomic_op(&key, b"", MutationType::CompareAndClear);
|
|
2119
|
+
Ok(())
|
|
2120
|
+
})
|
|
2121
|
+
.await
|
|
2122
|
+
.unwrap();
|
|
2123
|
+
|
|
2124
|
+
let value = db
|
|
2125
|
+
.run(|tx| async move {
|
|
2126
|
+
let test_subspace = Subspace::from("test");
|
|
2127
|
+
let key = test_subspace.pack(&("cac_empty",));
|
|
2128
|
+
let val = tx.get(&key, Serializable).await?;
|
|
2129
|
+
Ok(val)
|
|
2130
|
+
})
|
|
2131
|
+
.await
|
|
2132
|
+
.unwrap();
|
|
2133
|
+
|
|
2134
|
+
assert_eq!(
|
|
2135
|
+
value, None,
|
|
2136
|
+
"Key with empty value should be cleared when comparing with empty value"
|
|
2137
|
+
);
|
|
2138
|
+
}
|
|
2139
|
+
|
|
2140
|
+
async fn test_atomic_transaction_isolation(db: &Database) {
|
|
2141
|
+
use universaldb::options::MutationType;
|
|
2142
|
+
|
|
2143
|
+
// Test that atomic operations within a transaction are visible to subsequent reads
|
|
2144
|
+
db.run(|tx| async move {
|
|
2145
|
+
let test_subspace = Subspace::from("test");
|
|
2146
|
+
let key = test_subspace.pack(&("isolation_key",));
|
|
2147
|
+
|
|
2148
|
+
// Set initial value
|
|
2149
|
+
tx.set(&key, &10i64.to_le_bytes());
|
|
2150
|
+
|
|
2151
|
+
// Perform atomic add
|
|
2152
|
+
tx.informal()
|
|
2153
|
+
.atomic_op(&key, &5i64.to_le_bytes(), MutationType::Add);
|
|
2154
|
+
|
|
2155
|
+
// Read the value within the same transaction
|
|
2156
|
+
let value = tx.get(&key, Serializable).await?;
|
|
2157
|
+
let result = i64::from_le_bytes(Vec::from(value.unwrap()).try_into().unwrap());
|
|
2158
|
+
|
|
2159
|
+
assert_eq!(
|
|
2160
|
+
result, 15,
|
|
2161
|
+
"Atomic operation should be visible within the same transaction"
|
|
2162
|
+
);
|
|
2163
|
+
|
|
2164
|
+
// Perform another atomic operation
|
|
2165
|
+
tx.informal()
|
|
2166
|
+
.atomic_op(&key, &3i64.to_le_bytes(), MutationType::Add);
|
|
2167
|
+
|
|
2168
|
+
// Read again
|
|
2169
|
+
let value = tx.get(&key, Serializable).await?;
|
|
2170
|
+
let result = i64::from_le_bytes(Vec::from(value.unwrap()).try_into().unwrap());
|
|
2171
|
+
|
|
2172
|
+
assert_eq!(
|
|
2173
|
+
result, 18,
|
|
2174
|
+
"Multiple atomic operations should be cumulative within transaction"
|
|
2175
|
+
);
|
|
2176
|
+
|
|
2177
|
+
Ok(())
|
|
2178
|
+
})
|
|
2179
|
+
.await
|
|
2180
|
+
.unwrap();
|
|
2181
|
+
|
|
2182
|
+
// Test that atomic operations are isolated between transactions
|
|
2183
|
+
// Set initial value in one transaction
|
|
2184
|
+
db.run(|tx| async move {
|
|
2185
|
+
let test_subspace = Subspace::from("test");
|
|
2186
|
+
let key = test_subspace.pack(&("isolation_key2",));
|
|
2187
|
+
|
|
2188
|
+
tx.set(&key, &100i64.to_le_bytes());
|
|
2189
|
+
Ok(())
|
|
2190
|
+
})
|
|
2191
|
+
.await
|
|
2192
|
+
.unwrap();
|
|
2193
|
+
|
|
2194
|
+
// Perform atomic operation in another transaction
|
|
2195
|
+
db.run(|tx| async move {
|
|
2196
|
+
let test_subspace = Subspace::from("test");
|
|
2197
|
+
let key = test_subspace.pack(&("isolation_key2",));
|
|
2198
|
+
|
|
2199
|
+
tx.informal()
|
|
2200
|
+
.atomic_op(&key, &50i64.to_le_bytes(), MutationType::Add);
|
|
2201
|
+
Ok(())
|
|
2202
|
+
})
|
|
2203
|
+
.await
|
|
2204
|
+
.unwrap();
|
|
2205
|
+
|
|
2206
|
+
// Verify the result in a third transaction
|
|
2207
|
+
let value = db
|
|
2208
|
+
.run(|tx| async move {
|
|
2209
|
+
let test_subspace = Subspace::from("test");
|
|
2210
|
+
let key = test_subspace.pack(&("isolation_key2",));
|
|
2211
|
+
let val = tx.get(&key, Serializable).await?;
|
|
2212
|
+
Ok(val)
|
|
2213
|
+
})
|
|
2214
|
+
.await
|
|
2215
|
+
.unwrap();
|
|
2216
|
+
|
|
2217
|
+
let result = i64::from_le_bytes(Vec::from(value.unwrap()).try_into().unwrap());
|
|
2218
|
+
assert_eq!(
|
|
2219
|
+
result, 150,
|
|
2220
|
+
"Atomic operation should be committed and visible in new transaction"
|
|
2221
|
+
);
|
|
2222
|
+
}
|
|
2223
|
+
|
|
2224
|
+
async fn test_atomic_nonexistent_keys(db: &Database) {
|
|
2225
|
+
use universaldb::options::MutationType;
|
|
2226
|
+
|
|
2227
|
+
// Test atomic operations on non-existent keys behave correctly
|
|
2228
|
+
|
|
2229
|
+
// Test Add (should treat as 0)
|
|
2230
|
+
db.run(|tx| async move {
|
|
2231
|
+
let test_subspace = Subspace::from("test");
|
|
2232
|
+
let key = test_subspace.pack(&("nonexistent_add",));
|
|
2233
|
+
|
|
2234
|
+
tx.informal()
|
|
2235
|
+
.atomic_op(&key, &42i64.to_le_bytes(), MutationType::Add);
|
|
2236
|
+
Ok(())
|
|
2237
|
+
})
|
|
2238
|
+
.await
|
|
2239
|
+
.unwrap();
|
|
2240
|
+
|
|
2241
|
+
let value = db
|
|
2242
|
+
.run(|tx| async move {
|
|
2243
|
+
let test_subspace = Subspace::from("test");
|
|
2244
|
+
let key = test_subspace.pack(&("nonexistent_add",));
|
|
2245
|
+
let val = tx.get(&key, Serializable).await?;
|
|
2246
|
+
Ok(val)
|
|
2247
|
+
})
|
|
2248
|
+
.await
|
|
2249
|
+
.unwrap();
|
|
2250
|
+
|
|
2251
|
+
let result = i64::from_le_bytes(Vec::from(value.unwrap()).try_into().unwrap());
|
|
2252
|
+
assert_eq!(result, 42, "Add on non-existent key should treat as 0");
|
|
2253
|
+
|
|
2254
|
+
// Test BitOr (should treat as 0)
|
|
2255
|
+
db.run(|tx| async move {
|
|
2256
|
+
let test_subspace = Subspace::from("test");
|
|
2257
|
+
let key = test_subspace.pack(&("nonexistent_or",));
|
|
2258
|
+
|
|
2259
|
+
tx.informal()
|
|
2260
|
+
.atomic_op(&key, &[0b11110000], MutationType::BitOr);
|
|
2261
|
+
Ok(())
|
|
2262
|
+
})
|
|
2263
|
+
.await
|
|
2264
|
+
.unwrap();
|
|
2265
|
+
|
|
2266
|
+
let value = db
|
|
2267
|
+
.run(|tx| async move {
|
|
2268
|
+
let test_subspace = Subspace::from("test");
|
|
2269
|
+
let key = test_subspace.pack(&("nonexistent_or",));
|
|
2270
|
+
let val = tx.get(&key, Serializable).await?;
|
|
2271
|
+
Ok(val)
|
|
2272
|
+
})
|
|
2273
|
+
.await
|
|
2274
|
+
.unwrap();
|
|
2275
|
+
|
|
2276
|
+
assert_eq!(
|
|
2277
|
+
value.unwrap()[0],
|
|
2278
|
+
0b11110000,
|
|
2279
|
+
"BitOr on non-existent key should treat as 0"
|
|
2280
|
+
);
|
|
2281
|
+
|
|
2282
|
+
// Test Max (should set the parameter value)
|
|
2283
|
+
db.run(|tx| async move {
|
|
2284
|
+
let test_subspace = Subspace::from("test");
|
|
2285
|
+
let key = test_subspace.pack(&("nonexistent_max",));
|
|
2286
|
+
|
|
2287
|
+
tx.informal()
|
|
2288
|
+
.atomic_op(&key, &123i64.to_le_bytes(), MutationType::Max);
|
|
2289
|
+
Ok(())
|
|
2290
|
+
})
|
|
2291
|
+
.await
|
|
2292
|
+
.unwrap();
|
|
2293
|
+
|
|
2294
|
+
let value = db
|
|
2295
|
+
.run(|tx| async move {
|
|
2296
|
+
let test_subspace = Subspace::from("test");
|
|
2297
|
+
let key = test_subspace.pack(&("nonexistent_max",));
|
|
2298
|
+
let val = tx.get(&key, Serializable).await?;
|
|
2299
|
+
Ok(val)
|
|
2300
|
+
})
|
|
2301
|
+
.await
|
|
2302
|
+
.unwrap();
|
|
2303
|
+
|
|
2304
|
+
let result = i64::from_le_bytes(Vec::from(value.unwrap()).try_into().unwrap());
|
|
2305
|
+
assert_eq!(
|
|
2306
|
+
result, 123,
|
|
2307
|
+
"Max on non-existent key should set the parameter value"
|
|
2308
|
+
);
|
|
2309
|
+
|
|
2310
|
+
// Test ByteMin (should set the parameter value)
|
|
2311
|
+
db.run(|tx| async move {
|
|
2312
|
+
let test_subspace = Subspace::from("test");
|
|
2313
|
+
let key = test_subspace.pack(&("nonexistent_bytemin",));
|
|
2314
|
+
|
|
2315
|
+
tx.informal()
|
|
2316
|
+
.atomic_op(&key, b"hello", MutationType::ByteMin);
|
|
2317
|
+
Ok(())
|
|
2318
|
+
})
|
|
2319
|
+
.await
|
|
2320
|
+
.unwrap();
|
|
2321
|
+
|
|
2322
|
+
let value = db
|
|
2323
|
+
.run(|tx| async move {
|
|
2324
|
+
let test_subspace = Subspace::from("test");
|
|
2325
|
+
let key = test_subspace.pack(&("nonexistent_bytemin",));
|
|
2326
|
+
let val = tx.get(&key, Serializable).await?;
|
|
2327
|
+
Ok(val)
|
|
2328
|
+
})
|
|
2329
|
+
.await
|
|
2330
|
+
.unwrap();
|
|
2331
|
+
|
|
2332
|
+
assert_eq!(
|
|
2333
|
+
value.unwrap().as_slice(),
|
|
2334
|
+
b"hello",
|
|
2335
|
+
"ByteMin on non-existent key should set the parameter value"
|
|
2336
|
+
);
|
|
2337
|
+
|
|
2338
|
+
// Test CompareAndClear with empty comparison (should clear since non-existent = empty)
|
|
2339
|
+
db.run(|tx| async move {
|
|
2340
|
+
let test_subspace = Subspace::from("test");
|
|
2341
|
+
let key = test_subspace.pack(&("nonexistent_cac",));
|
|
2342
|
+
|
|
2343
|
+
tx.informal()
|
|
2344
|
+
.atomic_op(&key, b"", MutationType::CompareAndClear);
|
|
2345
|
+
Ok(())
|
|
2346
|
+
})
|
|
2347
|
+
.await
|
|
2348
|
+
.unwrap();
|
|
2349
|
+
|
|
2350
|
+
let value = db
|
|
2351
|
+
.run(|tx| async move {
|
|
2352
|
+
let test_subspace = Subspace::from("test");
|
|
2353
|
+
let key = test_subspace.pack(&("nonexistent_cac",));
|
|
2354
|
+
let val = tx.get(&key, Serializable).await?;
|
|
2355
|
+
Ok(val)
|
|
2356
|
+
})
|
|
2357
|
+
.await
|
|
2358
|
+
.unwrap();
|
|
2359
|
+
|
|
2360
|
+
assert_eq!(
|
|
2361
|
+
value, None,
|
|
2362
|
+
"CompareAndClear on non-existent key with empty param should result in None"
|
|
2363
|
+
);
|
|
2364
|
+
}
|
|
2365
|
+
|
|
2366
|
+
#[allow(dead_code)]
|
|
2367
|
+
async fn test_versionstamps(db: &Database) {
|
|
2368
|
+
// Test 1: Basic versionstamp insertion and ordering within a single transaction
|
|
2369
|
+
db.run(|tx| async move {
|
|
2370
|
+
let test_subspace = Subspace::from("test_vs");
|
|
2371
|
+
|
|
2372
|
+
// Create multiple values with incomplete versionstamps in the same transaction
|
|
2373
|
+
// Insert multiple entries with versionstamps
|
|
2374
|
+
for i in 0..3 {
|
|
2375
|
+
let incomplete = Versionstamp::from([0xff; 12]);
|
|
2376
|
+
let tuple = vec![
|
|
2377
|
+
Element::String("vs_test".into()),
|
|
2378
|
+
Element::Versionstamp(incomplete),
|
|
2379
|
+
Element::Int(i),
|
|
2380
|
+
];
|
|
2381
|
+
let key = test_subspace.pack(&(format!("entry_{}", i),));
|
|
2382
|
+
let value = pack_with_versionstamp(&tuple);
|
|
2383
|
+
tx.set(&key, &value);
|
|
2384
|
+
}
|
|
2385
|
+
|
|
2386
|
+
Ok(())
|
|
2387
|
+
})
|
|
2388
|
+
.await
|
|
2389
|
+
.unwrap();
|
|
2390
|
+
|
|
2391
|
+
// Verify that versionstamps were substituted and have the same transaction version
|
|
2392
|
+
// but different user versions (counter values)
|
|
2393
|
+
let results = db
|
|
2394
|
+
.run(|tx| async move {
|
|
2395
|
+
let test_subspace = Subspace::from("test_vs");
|
|
2396
|
+
let (begin, end) = test_subspace.range();
|
|
2397
|
+
|
|
2398
|
+
let range_opt = RangeOption {
|
|
2399
|
+
begin: KeySelector::first_greater_or_equal(Cow::Owned(begin)),
|
|
2400
|
+
end: KeySelector::first_greater_or_equal(Cow::Owned(end)),
|
|
2401
|
+
..RangeOption::default()
|
|
2402
|
+
};
|
|
2403
|
+
|
|
2404
|
+
let values = tx.get_range(&range_opt, 1, Serializable).await?;
|
|
2405
|
+
let mut results = Vec::new();
|
|
2406
|
+
|
|
2407
|
+
for kv in values.into_iter() {
|
|
2408
|
+
let key = kv.key().to_vec();
|
|
2409
|
+
let value = kv.value().to_vec();
|
|
2410
|
+
let unpacked: Vec<Element> = universaldb::tuple::unpack(&value).unwrap();
|
|
2411
|
+
if unpacked.len() >= 3 {
|
|
2412
|
+
if let Element::Versionstamp(vs) = &unpacked[1] {
|
|
2413
|
+
if let Element::Int(i) = &unpacked[2] {
|
|
2414
|
+
results.push((key, vs.clone(), *i));
|
|
2415
|
+
}
|
|
2416
|
+
}
|
|
2417
|
+
}
|
|
2418
|
+
}
|
|
2419
|
+
|
|
2420
|
+
Ok(results)
|
|
2421
|
+
})
|
|
2422
|
+
.await
|
|
2423
|
+
.unwrap();
|
|
2424
|
+
|
|
2425
|
+
// All entries should have versionstamps
|
|
2426
|
+
assert_eq!(results.len(), 3, "Expected 3 entries with versionstamps");
|
|
2427
|
+
|
|
2428
|
+
// Check if versionstamp substitution is supported by checking if any are complete
|
|
2429
|
+
let has_substitution = results.iter().any(|(_, vs, _)| vs.is_complete());
|
|
2430
|
+
|
|
2431
|
+
if !has_substitution {
|
|
2432
|
+
// Memory driver doesn't support versionstamp substitution
|
|
2433
|
+
// Skip the remaining versionstamp tests
|
|
2434
|
+
println!("Skipping versionstamp tests - driver doesn't support substitution");
|
|
2435
|
+
return;
|
|
2436
|
+
}
|
|
2437
|
+
|
|
2438
|
+
// Extract versionstamps and verify they're complete
|
|
2439
|
+
for (_, vs, _) in &results {
|
|
2440
|
+
assert!(
|
|
2441
|
+
vs.is_complete(),
|
|
2442
|
+
"Versionstamp should be complete after substitution"
|
|
2443
|
+
);
|
|
2444
|
+
}
|
|
2445
|
+
|
|
2446
|
+
// Test 2: Versionstamp ordering across multiple transactions
|
|
2447
|
+
// Insert entries in separate transactions to get different transaction versions
|
|
2448
|
+
let mut tx_versionstamps = Vec::new();
|
|
2449
|
+
|
|
2450
|
+
for i in 0..3 {
|
|
2451
|
+
let vs = db
|
|
2452
|
+
.run(|tx| async move {
|
|
2453
|
+
let test_subspace = Subspace::from("test_vs");
|
|
2454
|
+
let incomplete = Versionstamp::from([0xff; 12]);
|
|
2455
|
+
|
|
2456
|
+
let tuple = vec![
|
|
2457
|
+
Element::String("multi_tx".into()),
|
|
2458
|
+
Element::Versionstamp(incomplete),
|
|
2459
|
+
Element::Int(i),
|
|
2460
|
+
];
|
|
2461
|
+
let key = test_subspace.pack(&(format!("tx_{}", i),));
|
|
2462
|
+
let value = pack_with_versionstamp(&tuple);
|
|
2463
|
+
tx.set(&key, &value);
|
|
2464
|
+
|
|
2465
|
+
Ok(i)
|
|
2466
|
+
})
|
|
2467
|
+
.await
|
|
2468
|
+
.unwrap();
|
|
2469
|
+
|
|
2470
|
+
tx_versionstamps.push(vs);
|
|
2471
|
+
|
|
2472
|
+
// Small delay to ensure different timestamps
|
|
2473
|
+
tokio::time::sleep(tokio::time::Duration::from_millis(10)).await;
|
|
2474
|
+
}
|
|
2475
|
+
|
|
2476
|
+
// Read back and verify ordering
|
|
2477
|
+
let multi_tx_results = db
|
|
2478
|
+
.run(|tx| async move {
|
|
2479
|
+
let test_subspace = Subspace::from("test_vs");
|
|
2480
|
+
let begin = test_subspace.pack(&("tx_",));
|
|
2481
|
+
let end = test_subspace.pack(&("tx_z",));
|
|
2482
|
+
|
|
2483
|
+
let range_opt = RangeOption {
|
|
2484
|
+
begin: KeySelector::first_greater_or_equal(Cow::Owned(begin)),
|
|
2485
|
+
end: KeySelector::first_greater_or_equal(Cow::Owned(end)),
|
|
2486
|
+
..RangeOption::default()
|
|
2487
|
+
};
|
|
2488
|
+
|
|
2489
|
+
let values = tx.get_range(&range_opt, 1, Serializable).await?;
|
|
2490
|
+
let mut results = Vec::new();
|
|
2491
|
+
|
|
2492
|
+
for kv in values.into_iter() {
|
|
2493
|
+
let unpacked: Vec<Element> = universaldb::tuple::unpack(kv.value()).unwrap();
|
|
2494
|
+
if let Element::Versionstamp(vs) = &unpacked[1] {
|
|
2495
|
+
results.push((kv.key().to_vec(), vs.as_bytes().to_vec()));
|
|
2496
|
+
}
|
|
2497
|
+
}
|
|
2498
|
+
|
|
2499
|
+
Ok(results)
|
|
2500
|
+
})
|
|
2501
|
+
.await
|
|
2502
|
+
.unwrap();
|
|
2503
|
+
|
|
2504
|
+
assert_eq!(
|
|
2505
|
+
multi_tx_results.len(),
|
|
2506
|
+
3,
|
|
2507
|
+
"Expected 3 entries from multiple transactions"
|
|
2508
|
+
);
|
|
2509
|
+
|
|
2510
|
+
// Versionstamps from later transactions should be greater
|
|
2511
|
+
for i in 1..multi_tx_results.len() {
|
|
2512
|
+
let prev_vs = &multi_tx_results[i - 1].1;
|
|
2513
|
+
let curr_vs = &multi_tx_results[i].1;
|
|
2514
|
+
assert!(
|
|
2515
|
+
curr_vs > prev_vs,
|
|
2516
|
+
"Versionstamps should increase across transactions"
|
|
2517
|
+
);
|
|
2518
|
+
}
|
|
2519
|
+
|
|
2520
|
+
// Test 3: Already complete versionstamps should not be modified
|
|
2521
|
+
db.run(|tx| async move {
|
|
2522
|
+
let test_subspace = Subspace::from("test_vs");
|
|
2523
|
+
|
|
2524
|
+
// Create a complete versionstamp manually
|
|
2525
|
+
let complete_vs = generate_versionstamp(999);
|
|
2526
|
+
|
|
2527
|
+
let tuple = vec![
|
|
2528
|
+
Element::String("complete_vs".into()),
|
|
2529
|
+
Element::Versionstamp(complete_vs),
|
|
2530
|
+
Element::Int(42),
|
|
2531
|
+
];
|
|
2532
|
+
|
|
2533
|
+
// Pack with versionstamp (this adds the offset)
|
|
2534
|
+
let value = pack_with_versionstamp(&tuple);
|
|
2535
|
+
let key = test_subspace.pack(&("complete_entry",));
|
|
2536
|
+
tx.set(&key, &value);
|
|
2537
|
+
|
|
2538
|
+
Ok(())
|
|
2539
|
+
})
|
|
2540
|
+
.await
|
|
2541
|
+
.unwrap();
|
|
2542
|
+
|
|
2543
|
+
// Read back and verify the versionstamp remains unchanged
|
|
2544
|
+
let complete_result = db
|
|
2545
|
+
.run(|tx| async move {
|
|
2546
|
+
let test_subspace = Subspace::from("test_vs");
|
|
2547
|
+
let key = test_subspace.pack(&("complete_entry",));
|
|
2548
|
+
let value = tx.get(&key, Serializable).await?.unwrap();
|
|
2549
|
+
|
|
2550
|
+
let unpacked: Vec<Element> = universaldb::tuple::unpack(&value).unwrap();
|
|
2551
|
+
if let Element::Versionstamp(vs) = &unpacked[1] {
|
|
2552
|
+
Ok((vs.user_version(), vs.is_complete()))
|
|
2553
|
+
} else {
|
|
2554
|
+
panic!("Expected versionstamp element");
|
|
2555
|
+
}
|
|
2556
|
+
})
|
|
2557
|
+
.await
|
|
2558
|
+
.unwrap();
|
|
2559
|
+
|
|
2560
|
+
assert_eq!(complete_result.0, 999, "User version should remain 999");
|
|
2561
|
+
assert!(complete_result.1, "Versionstamp should still be complete");
|
|
2562
|
+
|
|
2563
|
+
// Test 4: Verify correct count and order within a transaction
|
|
2564
|
+
// Insert 10 entries in one transaction and verify they have sequential counters
|
|
2565
|
+
db.run(|tx| async move {
|
|
2566
|
+
let test_subspace = Subspace::from("test_vs");
|
|
2567
|
+
|
|
2568
|
+
for i in 0..10 {
|
|
2569
|
+
let incomplete = Versionstamp::from([0xff; 12]);
|
|
2570
|
+
let tuple = vec![
|
|
2571
|
+
Element::String("count_test".into()),
|
|
2572
|
+
Element::Versionstamp(incomplete),
|
|
2573
|
+
Element::Int(i),
|
|
2574
|
+
];
|
|
2575
|
+
let key = test_subspace.pack(&(format!("count_{:02}", i),));
|
|
2576
|
+
let value = pack_with_versionstamp(&tuple);
|
|
2577
|
+
tx.set(&key, &value);
|
|
2578
|
+
}
|
|
2579
|
+
|
|
2580
|
+
Ok(())
|
|
2581
|
+
})
|
|
2582
|
+
.await
|
|
2583
|
+
.unwrap();
|
|
2584
|
+
|
|
2585
|
+
// Read back and verify count and ordering
|
|
2586
|
+
let count_results = db
|
|
2587
|
+
.run(|tx| async move {
|
|
2588
|
+
let test_subspace = Subspace::from("test_vs");
|
|
2589
|
+
let begin = test_subspace.pack(&("count_",));
|
|
2590
|
+
let end = test_subspace.pack(&("count_z",));
|
|
2591
|
+
|
|
2592
|
+
let range_opt = RangeOption {
|
|
2593
|
+
begin: KeySelector::first_greater_or_equal(Cow::Owned(begin)),
|
|
2594
|
+
end: KeySelector::first_greater_or_equal(Cow::Owned(end)),
|
|
2595
|
+
..RangeOption::default()
|
|
2596
|
+
};
|
|
2597
|
+
|
|
2598
|
+
let values = tx.get_range(&range_opt, 1, Serializable).await?;
|
|
2599
|
+
let mut results = Vec::new();
|
|
2600
|
+
|
|
2601
|
+
for kv in values.into_iter() {
|
|
2602
|
+
let unpacked: Vec<Element> = universaldb::tuple::unpack(kv.value()).unwrap();
|
|
2603
|
+
if let (Element::Versionstamp(vs), Element::Int(idx)) = (&unpacked[1], &unpacked[2])
|
|
2604
|
+
{
|
|
2605
|
+
results.push((vs.as_bytes().to_vec(), *idx));
|
|
2606
|
+
}
|
|
2607
|
+
}
|
|
2608
|
+
|
|
2609
|
+
Ok(results)
|
|
2610
|
+
})
|
|
2611
|
+
.await
|
|
2612
|
+
.unwrap();
|
|
2613
|
+
|
|
2614
|
+
assert_eq!(count_results.len(), 10, "Expected exactly 10 entries");
|
|
2615
|
+
|
|
2616
|
+
// All should have the same transaction version (first 8 bytes)
|
|
2617
|
+
let first_tx_version = &count_results[0].0[0..8];
|
|
2618
|
+
for (vs_bytes, _) in &count_results {
|
|
2619
|
+
assert_eq!(
|
|
2620
|
+
&vs_bytes[0..8],
|
|
2621
|
+
first_tx_version,
|
|
2622
|
+
"All entries should have same transaction version"
|
|
2623
|
+
);
|
|
2624
|
+
}
|
|
2625
|
+
|
|
2626
|
+
// The counter portion (bytes 8-10) should be sequential
|
|
2627
|
+
let mut counters: Vec<u16> = count_results
|
|
2628
|
+
.iter()
|
|
2629
|
+
.map(|(vs_bytes, _)| u16::from_be_bytes([vs_bytes[8], vs_bytes[9]]))
|
|
2630
|
+
.collect();
|
|
2631
|
+
counters.sort();
|
|
2632
|
+
|
|
2633
|
+
// Verify they are sequential (might not start at 0 due to other operations)
|
|
2634
|
+
for i in 1..counters.len() {
|
|
2635
|
+
assert_eq!(
|
|
2636
|
+
counters[i],
|
|
2637
|
+
counters[i - 1] + 1,
|
|
2638
|
+
"Counters should be sequential"
|
|
2639
|
+
);
|
|
2640
|
+
}
|
|
2641
|
+
|
|
2642
|
+
// Test 5: Mixed incomplete and complete versionstamps in same transaction
|
|
2643
|
+
db.run(|tx| async move {
|
|
2644
|
+
let test_subspace = Subspace::from("test_vs");
|
|
2645
|
+
|
|
2646
|
+
// Insert an incomplete versionstamp
|
|
2647
|
+
let incomplete = Versionstamp::from([0xff; 12]);
|
|
2648
|
+
let tuple1 = vec![
|
|
2649
|
+
Element::String("mixed".into()),
|
|
2650
|
+
Element::Versionstamp(incomplete),
|
|
2651
|
+
Element::Int(1),
|
|
2652
|
+
];
|
|
2653
|
+
let key1 = test_subspace.pack(&("mixed_incomplete",));
|
|
2654
|
+
let value1 = pack_with_versionstamp(&tuple1);
|
|
2655
|
+
tx.set(&key1, &value1);
|
|
2656
|
+
|
|
2657
|
+
// Insert a complete versionstamp
|
|
2658
|
+
let complete = generate_versionstamp(555);
|
|
2659
|
+
let tuple2 = vec![
|
|
2660
|
+
Element::String("mixed".into()),
|
|
2661
|
+
Element::Versionstamp(complete),
|
|
2662
|
+
Element::Int(2),
|
|
2663
|
+
];
|
|
2664
|
+
let key2 = test_subspace.pack(&("mixed_complete",));
|
|
2665
|
+
let value2 = pack_with_versionstamp(&tuple2);
|
|
2666
|
+
tx.set(&key2, &value2);
|
|
2667
|
+
|
|
2668
|
+
Ok(())
|
|
2669
|
+
})
|
|
2670
|
+
.await
|
|
2671
|
+
.unwrap();
|
|
2672
|
+
|
|
2673
|
+
// Verify both were stored correctly
|
|
2674
|
+
let mixed_results = db
|
|
2675
|
+
.run(|tx| async move {
|
|
2676
|
+
let test_subspace = Subspace::from("test_vs");
|
|
2677
|
+
let begin = test_subspace.pack(&("mixed_",));
|
|
2678
|
+
let end = test_subspace.pack(&("mixed_z",));
|
|
2679
|
+
|
|
2680
|
+
let range_opt = RangeOption {
|
|
2681
|
+
begin: KeySelector::first_greater_or_equal(Cow::Owned(begin)),
|
|
2682
|
+
end: KeySelector::first_greater_or_equal(Cow::Owned(end)),
|
|
2683
|
+
..RangeOption::default()
|
|
2684
|
+
};
|
|
2685
|
+
|
|
2686
|
+
let values = tx.get_range(&range_opt, 1, Serializable).await?;
|
|
2687
|
+
let mut results = Vec::new();
|
|
2688
|
+
|
|
2689
|
+
for kv in values.into_iter() {
|
|
2690
|
+
let unpacked: Vec<Element> = universaldb::tuple::unpack(kv.value()).unwrap();
|
|
2691
|
+
if let Element::Versionstamp(vs) = &unpacked[1] {
|
|
2692
|
+
results.push((
|
|
2693
|
+
String::from_utf8_lossy(kv.key()).to_string(),
|
|
2694
|
+
vs.user_version(),
|
|
2695
|
+
vs.is_complete(),
|
|
2696
|
+
));
|
|
2697
|
+
}
|
|
2698
|
+
}
|
|
2699
|
+
|
|
2700
|
+
Ok(results)
|
|
2701
|
+
})
|
|
2702
|
+
.await
|
|
2703
|
+
.unwrap();
|
|
2704
|
+
|
|
2705
|
+
assert_eq!(mixed_results.len(), 2, "Expected 2 mixed entries");
|
|
2706
|
+
|
|
2707
|
+
// Find and verify each entry
|
|
2708
|
+
let incomplete_entry = mixed_results
|
|
2709
|
+
.iter()
|
|
2710
|
+
.find(|(k, _, _)| k.contains("mixed_incomplete"))
|
|
2711
|
+
.expect("Should find incomplete entry");
|
|
2712
|
+
assert!(
|
|
2713
|
+
incomplete_entry.2,
|
|
2714
|
+
"Incomplete versionstamp should be substituted and complete"
|
|
2715
|
+
);
|
|
2716
|
+
assert_eq!(
|
|
2717
|
+
incomplete_entry.1, 0,
|
|
2718
|
+
"Substituted versionstamp should have user_version 0"
|
|
2719
|
+
);
|
|
2720
|
+
|
|
2721
|
+
let complete_entry = mixed_results
|
|
2722
|
+
.iter()
|
|
2723
|
+
.find(|(k, _, _)| k.contains("mixed_complete"))
|
|
2724
|
+
.expect("Should find complete entry");
|
|
2725
|
+
assert!(
|
|
2726
|
+
complete_entry.2,
|
|
2727
|
+
"Complete versionstamp should remain complete"
|
|
2728
|
+
);
|
|
2729
|
+
assert_eq!(
|
|
2730
|
+
complete_entry.1, 555,
|
|
2731
|
+
"Complete versionstamp should keep user_version 555"
|
|
2732
|
+
);
|
|
2733
|
+
}
|