FazBrowse GitHub Viewer | Trending |
URL:
| Home
Tools: [Download Repo ZIP]   [Original HTTPS Page]

rupoc: Appwrite 3.x.x Rust Users-first migration by eldadfux · Pull Request #13240 · appwrite/appwrite · GitHub

rupoc: Appwrite 3.x.x Rust Users-first migration - #13240

Draft
eldadfux wants to merge 38 commits into
mainfrom
cursor/rupoc-bdfb
Draft

rupoc: Appwrite 3.x.x Rust Users-first migration#13240
eldadfux wants to merge 38 commits into
mainfrom
cursor/rupoc-bdfb

Conversation

eldadfux commented Aug 16, 2026
edited by cursor Bot
Loading

Copy link
Copy Markdown
Member

Summary

Implements the Users-first Rust migration under 3.x.x/ (long-lived secret branch rupoc). Tip: 833d0e2301.

  • Peer crates: utopia-* + appwrite-*, binary apps/server
  • Traefik PathPrefix(/v1/users) → appwrite-rust
  • Shared API hooks + full Users HTTP surface (PHP one-file-per-action layout)
  • Real utopia_pools checkout per project/platform; Postgres I/O isolated from Tokio
  • DB adapters (same as PHP _APP_DB_ADAPTER): postgresql, mysql, mariadb, mongodb, plus Memory fallback

Folded stack PRs

PR Status
#13242 docker-e2e Traefik E2E Squash-merged earlier
#13243 Users hot paths / benches / cache / auth Fast-forwarded into this branch
#13244 Users HTTP restructure Fast-forwarded into this branch
#13245 DB pool + Postgres isolation Fast-forwarded into this branch (tip)

Database adapters

_APP_DB_ADAPTER Backend
postgresql / postgres Postgres
mysql MySQL
mariadb MariaDB
mongodb / mongo MongoDB
memory / unset / connect failure in-process Memory

Uses the same _APP_DB_HOST / _PORT / _USER / _PASS / _SCHEMA / _APP_OPENSSL_KEY_V1 env as PHP.

Verification

cd 3.x.x
cargo test -p appwrite-platform

Users CustomServerTest via Traefik → Rust: 50 tests green. Concurrent benches: 3.x.x/benchmarks/users/bench-concurrent.php.

  

cursoragent and others added 9 commits August 16, 2026 07:18
Scaffold appwrite-* library crates and apps/server health binary under
3.x.x, wire them into the Cargo workspace, and document the layout.

Co-authored-by: Eldad A. Fux <eldadfux@users.noreply.github.com>
Lock dependencies resolved while verifying appwrite crate stubs compile.

Co-authored-by: Eldad A. Fux <eldadfux@users.noreply.github.com>
Copy the utopia-* building-block crates from rust-poc under 3.x.x/crates/
alongside appwrite-* peers, plus Rust toolchain/clippy/deny/rustfmt config.

Co-authored-by: Eldad A. Fux <eldadfux@users.noreply.github.com>
Replace stub src/lib.rs with real, compiling ports of the
Appwrite\* PHP domains the Users API migration needs, across
seven crates plus the platform composition layer that wires them
together.

appwrite-exception: Exception { type_, message, code, version }
constructed from a type string looked up in a static ERRORS map
(src/Appwrite/Extend/Exception.php + app/config/errors.php). Ports
every GENERAL_*/USER_*/PROJECT_* constant PHP defines (plus a
documented PROJECT_UNKNOWN Rust-only addition), is_publishable(),
default_code()/default_message(), and to_json() matching the PHP
Error response model (message, code, type, version).

appwrite-response: data-driven Rule/ModelSpec/ListSpec model
catalog covering User, Session, Token, JWT, Preferences, Target,
Membership, Identity, and the MFA response models (+ list
variants), and dynamic(doc, model) porting Response::dynamic() --
filters a document to its model's rules, fills PHP-equivalent
defaults for missing optional fields, recurses into nested models,
and wraps lists as { total, <plural>: [...] }.

appwrite-hooks: Hooks registry (add/remove/has/trigger) mirroring
Appwrite\Hooks\Hooks, with the PASSWORD_VALIDATOR hook slot.
Deliberately instance-owned rather than PHP's static registry
(documented deviation).

appwrite-locale: GeoRecord { country_code, country, continent,
continent_code, eu, currency } with new()/unknown() constructors,
porting Appwrite\Locale\GeoRecord.

appwrite-auth: Key::decode_standard() porting Appwrite\Auth\Key's
API_KEY_STANDARD case (secret lookup + expiry check against a
project document's keys array); Password (length 8-256) and Phone
validators porting Appwrite\Auth\Validator\*; mfa module porting
Appwrite\Auth\MFA\Type factor constants; Hash/Argon2/Bcrypt
re-exported from utopia-auth behind feature flags plus
hash_password/verify_password wrappers.

appwrite-event: Event builder (set_project/set_user/set_event/
set_param/set_payload/set_context) with to_message() producing the
PHP queue payload shape; generate_events() porting
Event::generateEvents()'s placeholder/wildcard expansion for
patterns with up to one sub-resource level (every Users API event
fits this shape); DeleteMessage/AuditMessage porting
Appwrite\Event\Message\{Delete,Audit}::toArray(); DeletePublisher/
AuditPublisher traits with in-memory + callback implementations
ahead of a Redis-backed publisher in apps/server.

appwrite-database: CustomId validator (accepts "unique()" or any
Utopia\Database\Validator\Key-valid ID) porting
Appwrite\Utopia\Database\Validator\CustomId; resolve_id() porting
the "$id == 'unique()' ? ID::unique() : ID::custom($id)" pattern
used across Users/Targets/Sessions creation; queries module with
Query::equal/search helpers for the lookups those endpoints share.

appwrite-platform: composes the above into AppwritePlatform --
DI container, hook registry (with the default passwordValidator
hook registered), and in-memory delete/audit queue publishers --
replacing the previous stub()-touching placeholder. apps/server
updated to construct AppwritePlatform::new() directly.

Every crate: expanded/added unit + integration tests (PHP test
suites as the oracle where they exist), benches printing
ops_per_s=, updated Cargo.toml deps, and README API tables with
PHP-equivalent references and documented deviations.

cargo test -p appwrite-exception -p appwrite-response -p
appwrite-hooks -p appwrite-locale -p appwrite-auth -p
appwrite-event -p appwrite-database -p appwrite-platform: all
green. cargo clippy --all-targets and cargo fmt --check: clean.

Co-authored-by: Eldad A. Fux <eldadfux@users.noreply.github.com>
Implements the shared api-group Init/Error/Shutdown hooks and the full
Users HTTP module on top of utopia-platform, so apps/server can serve
/v1/users* while PHP remains the behavior oracle.

- modules/core: Init hook resolves X-Appwrite-Project/X-Appwrite-Key
  (appwrite_auth::Key), checks the matched route's scope label, and
  binds project/apiKey/dbForProject on the request container; Error
  hook maps HttpError/Exception to the Response::MODEL_ERROR shape;
  Shutdown hook enqueues audits.event messages via publisherForAudits.
- modules/users: all 41 Http/Users/**/*.php actions ported (CRUD,
  pre-hashed-password creates, property updates, prefs, targets,
  sessions/tokens/JWTs, memberships, identities, MFA), registered in
  services/http.rs under their PHP getName() ids.
- state.rs: AppwriteState/ProjectStore/DatabasePool -- an in-memory
  stand-in for dbForPlatform's projects/keys plus a per-project
  dbForProject pool (utopia_database Memory adapter), including
  seed_dev_project for local/test bootstrapping.
- apps/server: wires appwrite_platform::build() into main(), keeps
  /v1/health and /_health, adds _APP_RUST_SEED dev bootstrap.
- utopia-http: share one request-scoped DI container across Init
  hooks, the route action, and Shutdown hooks so resources an Init
  hook binds stay visible downstream (mirrors Utopia\App's per-request
  Container).
- tests/users_http.rs: end-to-end MemoryAdapter coverage of the auth
  flow (missing project, missing scope) and create/get/list/delete
  user round trip.

Co-authored-by: Eldad A. Fux <eldadfux@users.noreply.github.com>
- appwrite-platform: connect_from_env() wires dbForPlatform/dbForProject
  to Postgres when _APP_DB_ADAPTER=postgresql/postgres, matching PHP's
  Appwrite\\Database\\Factory namespace math (_console / _<sequence>).
  Falls back to the existing in-memory ProjectStore/DatabasePool on
  memory adapter or connect failure, so _APP_RUST_SEED unit tests stay
  green. New ProjectDb enum abstracts Database<Memory>/Database<Postgres>
  since utopia_database::Adapter is not dyn-compatible.
- resolve_project()/project_sequence() load a project + its keys from
  dbForPlatform (projects + keys collections), replicating PHP's
  subQueryKeys filter by hand and shaping the JSON for
  appwrite_auth::Key::decode_standard.
- appwrite-database: new encrypt filter (AES-128-GCM) matching PHP's
  openssl_encrypt envelope for users.password / keys.secret, keyed by
  _APP_OPENSSL_KEY_V1 with PHP's zero-pad/truncate key-length quirk.
- utopia-database: fix Postgres row decoding to also try
  serde_json::Value (with-serde_json-1) for JSON/JSONB columns -- array
  attributes (keys.scopes, users.labels, ...) were silently decoding as
  Null over Postgres.
- apps/server: call connect_from_env() at boot and log the active
  adapter; only auto-seed the dev project in memory mode.
- Add an ignored end-to-end Postgres wiring test (state.rs) that
  provisions projects/keys/users against a real local Postgres and
  drives connect_from_env -> resolve_project -> dbForProject, plus an
  ignored postgres_smoke.rs template for validating against PHP-created
  fixtures once the compose stack is up.

Co-authored-by: Eldad A. Fux <eldadfux@users.noreply.github.com>
Cover property updates, prehashed creates, sessions/tokens/JWTs,
targets CRUD, identities/memberships lists, and MFA recovery codes
against the in-memory seeded project/key path.

Co-authored-by: Eldad A. Fux <eldadfux@users.noreply.github.com>
Add appwrite-rust compose service with PathPrefix(/v1/users) priority 100,
in-process Users create+get microbench, and HTTP benchmark harness docs.

Co-authored-by: Eldad A. Fux <eldadfux@users.noreply.github.com>
Co-authored-by: Eldad A. Fux <eldadfux@users.noreply.github.com>

github-actions Bot commented Aug 16, 2026
edited
Loading

Copy link
Copy Markdown

✨ Benchmark results

Comparing main (before) → cursor/rupoc-bdfb (after).

⚠️ Current branch benchmark did not complete — showing available metrics only.

Metric Before After Change
🚀 Requests/sec 176.4 n/a n/a
⏱️ Latency P50 81.67 ms n/a n/a
⏱️ Latency P95 279.19 ms n/a n/a
Per-scenario breakdown & investigation details

Metrics below reflect the current branch (after). Δ P95 compares against the base.

Scenario P50 (ms) P95 (ms) Requests RPS Δ P95 (ms)
API total n/a n/a n/a n/a n/a
Account n/a n/a n/a n/a n/a
TablesDB n/a n/a n/a n/a n/a
Storage n/a n/a n/a n/a n/a
Functions n/a n/a n/a n/a n/a

Top API waits (after)

API request Max wait (ms)
n/a n/a

cursoragent and others added 20 commits August 16, 2026 10:49
Wire `_APP_DB_ADAPTER` the same way PHP does (postgresql/mysql/mariadb/mongodb)
so the Rust Users server can share whichever platform DB Appwrite is configured
for, with Memory fallback for local tests.

Co-authored-by: Eldad A. Fux <eldadfux@users.noreply.github.com>
Wrap sync postgres PDO connect/query in block_in_place so Hyper
workers do not panic on nested runtimes, connect before building the
Tokio runtime in apps/server, wait for healthy Postgres/Redis before
starting appwrite-rust, and ignore target/ in the Rust image context.

Co-authored-by: Eldad A. Fux <eldadfux@users.noreply.github.com>
Co-authored-by: Eldad A. Fux <eldadfux@users.noreply.github.com>
Populate Request payload from application/json (and urlencoded)
bodies so /v1/users create works with Content-Type JSON, matching
PHP Utopia behavior. Also fix appwrite-rust depends_on to use a
literal postgresql service name (compose rejects env-var map keys).

Co-authored-by: Eldad A. Fux <eldadfux@users.noreply.github.com>
Token::generate sliced a hex string built from a floor-divided byte count,
so any odd length (Users' createToken accepts 4..128) panicked and took the
whole server process down. Round the byte count up like PHP's ceil() and
truncate instead of slicing.

The urlencoded parser also dropped http_build_query's queries[0]=..&queries[1]=..
form into a single stringly key, so array params never reached handlers, and
percent-decoding widened raw bytes into Latin-1 code points.

Co-authored-by: Eldad A. Fux <eldadfux@users.noreply.github.com>
i64/f64/bool ToSql impls accept exactly one OID each, so binding an integer
to any column narrower than bigint failed with "error serializing parameter
N" -- tokens.type is INT4, which broke createUser tokens entirely. Route the
scalars through the same type-directed conversion PgFlexible already does for
strings.

Co-authored-by: Eldad A. Fux <eldadfux@users.noreply.github.com>
Co-authored-by: Eldad A. Fux <eldadfux@users.noreply.github.com>
PHP's Database::updateDocument loads the stored document and merges the
caller's partial update over it. The Rust port skipped that, so every
sparse update returned a stub document and rewrote the permissions rows
from an empty $permissions, which made PHP's authorized reads of a
Rust-updated user come back empty.

Co-authored-by: Eldad A. Fux <eldadfux@users.noreply.github.com>
Ports the session half of request.php's user resource and api.php's
admin branch: decode the session store, verify the secret against the
user's sessions, and derive scopes from the confirmed team membership
(admin mode) or the member role (project session).

Co-authored-by: Eldad A. Fux <eldadfux@users.noreply.github.com>
The hyper adapter never populated Request::cookies, so the Console's
a_session_console cookie was invisible to the api init hook and every
SideConsole request fell back to a guest key.

Co-authored-by: Eldad A. Fux <eldadfux@users.noreply.github.com>
Rust kept its own in-process cache, so a session deleted through the
Rust API left the PHP server serving a user document whose cached
sessions relationship still listed it, and a JWT for that session went
on passing sessionActive.

Point the project and platform databases at the Redis PHP already uses.
The cache key carries the adapter hostname, so the adapter now also
carries the DSN host PHP's pooled PDO reports; without it the two
servers would key the same document differently. Writing a child
document leaves the parent user cached with a stale relationship, so
the session, target, token and password handlers purge the user
document where the PHP handlers do.

Co-authored-by: Eldad A. Fux <eldadfux@users.noreply.github.com>
Co-authored-by: Eldad A. Fux <eldadfux@users.noreply.github.com>
Rename utopia-database's connection layer from pdo to SqlClient, connect
through Postgres/Mysql/MariaDb/Sqlite adapters in platform wiring, and
document that Appwrite 3.x keeps Utopia architecture while avoiding PHP
runtime surfaces like PDO.

Co-authored-by: Eldad A. Fux <eldadfux@users.noreply.github.com>
* Fix Rust Postgres boot under Tokio and harden compose startup

Wrap sync postgres PDO connect/query in block_in_place so Hyper
workers do not panic on nested runtimes, connect before building the
Tokio runtime in apps/server, wait for healthy Postgres/Redis before
starting appwrite-rust, and ignore target/ in the Rust image context.

Co-authored-by: Eldad A. Fux <eldadfux@users.noreply.github.com>

* Update Cargo.lock for utopia-database tokio (postgres) feature

Co-authored-by: Eldad A. Fux <eldadfux@users.noreply.github.com>

* Parse JSON request bodies in utopia-http Hyper adapter

Populate Request payload from application/json (and urlencoded)
bodies so /v1/users create works with Content-Type JSON, matching
PHP Utopia behavior. Also fix appwrite-rust depends_on to use a
literal postgresql service name (compose rejects env-var map keys).

Co-authored-by: Eldad A. Fux <eldadfux@users.noreply.github.com>

* Fix odd-length token generation panic and PHP-style query array parsing

Token::generate sliced a hex string built from a floor-divided byte count,
so any odd length (Users' createToken accepts 4..128) panicked and took the
whole server process down. Round the byte count up like PHP's ceil() and
truncate instead of slicing.

The urlencoded parser also dropped http_build_query's queries[0]=..&queries[1]=..
form into a single stringly key, so array params never reached handlers, and
percent-decoding widened raw bytes into Latin-1 code points.

Co-authored-by: Eldad A. Fux <eldadfux@users.noreply.github.com>

* Bind Postgres scalars against the target column type

i64/f64/bool ToSql impls accept exactly one OID each, so binding an integer
to any column narrower than bigint failed with "error serializing parameter
N" -- tokens.type is INT4, which broke createUser tokens entirely. Route the
scalars through the same type-directed conversion PgFlexible already does for
strings.

Co-authored-by: Eldad A. Fux <eldadfux@users.noreply.github.com>

* Add query validation, search refresh, label validation for Users API

Co-authored-by: Eldad A. Fux <eldadfux@users.noreply.github.com>

* Merge stored document into partial updates in utopia-database

PHP's Database::updateDocument loads the stored document and merges the
caller's partial update over it. The Rust port skipped that, so every
sparse update returned a stub document and rewrote the permissions rows
from an empty $permissions, which made PHP's authorized reads of a
Rust-updated user come back empty.

Co-authored-by: Eldad A. Fux <eldadfux@users.noreply.github.com>

* Resolve session-authenticated users in the api init hook

Ports the session half of request.php's user resource and api.php's
admin branch: decode the session store, verify the secret against the
user's sessions, and derive scopes from the confirmed team membership
(admin mode) or the member role (project session).

Co-authored-by: Eldad A. Fux <eldadfux@users.noreply.github.com>

* Parse request cookies so console sessions authenticate

The hyper adapter never populated Request::cookies, so the Console's
a_session_console cookie was invisible to the api init hook and every
SideConsole request fell back to a guest key.

Co-authored-by: Eldad A. Fux <eldadfux@users.noreply.github.com>

* Share the PHP cache so Rust writes invalidate PHP reads

Rust kept its own in-process cache, so a session deleted through the
Rust API left the PHP server serving a user document whose cached
sessions relationship still listed it, and a JWT for that session went
on passing sessionActive.

Point the project and platform databases at the Redis PHP already uses.
The cache key carries the adapter hostname, so the adapter now also
carries the DSN host PHP's pooled PDO reports; without it the two
servers would key the same document differently. Writing a child
document leaves the parent user cached with a stale relationship, so
the session, target, token and password handlers purge the user
document where the PHP handlers do.

Co-authored-by: Eldad A. Fux <eldadfux@users.noreply.github.com>

* Fix formatting and clippy failures in the Rust workspace

Co-authored-by: Eldad A. Fux <eldadfux@users.noreply.github.com>

* Prefer Rust SQL engines over a PDO-shaped API

Rename utopia-database's connection layer from pdo to SqlClient, connect
through Postgres/Mysql/MariaDb/Sqlite adapters in platform wiring, and
document that Appwrite 3.x keeps Utopia architecture while avoiding PHP
runtime surfaces like PDO.

Co-authored-by: Eldad A. Fux <eldadfux@users.noreply.github.com>

---------

Co-authored-by: Cursor Agent <cursoragent@cursor.com>
Co-authored-by: Eldad A. Fux <eldadfux@users.noreply.github.com>
Sync feature branch with latest base.

Co-authored-by: Eldad A. Fux <eldadfux@users.noreply.github.com>
Harness covers create/get/list, property updates, sessions, tokens,
JWTs, targets, memberships, and delete against PHP direct, Rust
direct, and Traefik→Rust.

Co-authored-by: Eldad A. Fux <eldadfux@users.noreply.github.com>
Replace find-all count with SQL COUNT(*), batch targets on list
like PHP XList, fetch only the needed session for JWT, align delete
with PHP (identities/targets only; sessions via worker), and use
find_one for the email-identity uniqueness check.

Co-authored-by: Eldad A. Fux <eldadfux@users.noreply.github.com>
Split the combined http/{crud,hashes,properties,sessions,targets,mfa,
identities,memberships}.rs files into http/users/** matching PHP's
Http/Users/**/*.php tree. Each action file exposes create/get/update/delete/
xlist matching PHP Get/Create/Update/Delete/XList. Shared non-action helpers
live in hash_create.rs, helpers.rs, sessions/shared.rs, and mfa/shared.rs.

Co-authored-by: Eldad A. Fux <eldadfux@users.noreply.github.com>
Require one PHP action class per Rust action file under http/, matching
Modules/{Name}/Http nesting, and forbid collapsing actions into mega-files.

Co-authored-by: Eldad A. Fux <eldadfux@users.noreply.github.com>
Rust has no class inheritance, so shared create/MFA/session API lives on
base.rs the way PHP subclasses call methods on Base. Remove the ad-hoc
hash_create/helpers/shared modules beside HTTP actions.

Co-authored-by: Eldad A. Fux <eldadfux@users.noreply.github.com>
cursoragent and others added 8 commits August 16, 2026 16:44
Connection::resource() previously returned a MutexGuard tied to the
Connection's borrow, which can't be stored across a struct boundary.
Add resource_owned() backed by parking_lot's arc_lock feature so
callers can hold an owned, 'static guard to the pooled resource
independent of the Connection it came from.

Co-authored-by: Eldad A. Fux <eldadfux@users.noreply.github.com>
MySQL's client performs blocking I/O directly on whatever thread calls
it. Wrap connect/exec/exec_drop in mysql_blocking (mirrors the
existing postgres_blocking) so a slow query yields the async worker
thread back to the Tokio runtime instead of stalling it, matching how
Postgres already behaves under load.

Co-authored-by: Eldad A. Fux <eldadfux@users.noreply.github.com>
Replace the single Arc<Mutex<ProjectDb>> per project (and the single
Mutex<ProjectDb> for the platform DB) with a pooled ProjectDatabase
backed by utopia_pools::Pool<ProjectDb> for live adapters. Every
request previously serialized on one shared connection; now each
project (and the platform DB) gets a pool of N connections sized from
_APP_CONNECTIONS_MAX / _APP_POOL_CLIENTS / available parallelism,
floored by _APP_WORKER_MAX_COROUTINES and clamped to [2, 32], mirroring
PHP's app/init/registers.php pool sizing.

- ProjectDb implements utopia_pools::Recover: reset/reconnect both
  ping the live connection so unhealthy connections are dropped and
  replaced instead of being handed back out.
- ProjectDatabase::lock() checks a connection out of the pool
  synchronously (block_in_place, with a multi-thread fallback runtime
  for init-time callers outside Tokio) and returns a ProjectDbGuard
  that Derefs/DerefMuts to ProjectDb and reclaims on Drop, so existing
  handler call sites () don't change.
- Memory adapter keeps a single Mutex<ProjectDb> (in-process, nothing
  to pool) via a Memory variant on ProjectDatabase/ProjectDbGuard.
- warm_up_pool eagerly pops+reclaims a connection at pool creation so
  bad DB config fails fast at boot instead of on the first request.
- state.rs / console.rs / tests updated for the new guard, which is
  infallible for Memory and panics with context on pool exhaustion for
  Pooled rather than returning a poison-recoverable Result.

Co-authored-by: Eldad A. Fux <eldadfux@users.noreply.github.com>
Argon2 hashing is CPU-bound and previously ran while a DB connection
was checked out (create_user hashed inline while holding the lock),
which, with a pool sized well below the request concurrency, would
starve other requests waiting on a free connection.

Introduce ResolvedPassword / base::resolve_password and call it
before base::get_db()/lock() in the plaintext create-user path
(http/users/create.rs) and the password update handler
(http/users/password/update.rs). create_user now takes an already
resolved password instead of a hasher, so it never hashes under the
pool lock. create_hashed_user is unaffected: pre-hashed passwords have
no hashing to move.

Co-authored-by: Eldad A. Fux <eldadfux@users.noreply.github.com>
ProjectDbGuard::lock() is infallible for Memory and panics with
context on pool exhaustion for Pooled, so the old
lock().unwrap_or_else(|e| e.into_inner()) mutex-poison recovery
pattern no longer applies. Mechanical cleanup across every Users
handler that touches dbForProject.

Co-authored-by: Eldad A. Fux <eldadfux@users.noreply.github.com>
Print the computed pool_size_from_env() next to the adapter name so
operators can see how many concurrent connections dbForProject/
dbForPlatform actually have per project, instead of just the adapter
name. Pin max_blocking_threads to 512 explicitly: block_in_place calls
in utopia-database each borrow a blocking-pool thread for the query's
duration, and with N concurrent pool checkouts across projects this
headroom should not silently shrink if the Tokio default changes.

Co-authored-by: Eldad A. Fux <eldadfux@users.noreply.github.com>
Co-authored-by: Eldad A. Fux <eldadfux@users.noreply.github.com>
Sync postgres Client::block_on/close panicked under Hyper's runtime, which
serialized or crashed concurrent /v1/users traffic. Run connect/query/drop on
OS threads without an ambient Tokio handle, size per-project pools for compose
Postgres limits, raise Tokio worker_threads with the pool, and run Users
handlers via finish_blocking. Adds a concurrent PHP vs Rust bench harness.

Co-authored-by: Eldad A. Fux <eldadfux@users.noreply.github.com>
…ase, and event helpers

This commit adds three new crates: `appwrite-auth`, `appwrite-database`, and `appwrite-event`. The `appwrite-auth` crate provides authentication helpers, including API key decoding, password and phone validators, and MFA factor identifiers. The `appwrite-database` crate offers database helpers, including a custom ID validator and query helpers for common Users API lookups. The `appwrite-event` crate includes event payloads and helpers for building queue messages and generating event patterns.

Each crate includes comprehensive documentation and tests to ensure functionality and compatibility with existing Appwrite features.

Co-authored-by: Eldad A. Fux <eldadfux@users.noreply.github.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode characters
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants


Back | FazBrowse Home | New Git URL