Repository navigation
Proposal: Unify Resource Management On Texera #9394
Closed
bobbairobot
started this conversation in
Ideas
Replies: 0 comments
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Uh oh!
There was an error while loading. Please reload this page.
How Texera manages resources today
Texera manages six kinds of resources: workflows, datasets, models, computing units, environments, and warehouses. By managing a resource I mean three things: creating, reading, updating, and deleting it (CRUD), keeping its versions, and controlling who can access it. Today each kind is managed by its own code: workflows and warehouses in the Dashboard Service, datasets and models in the File Service, computing units in the Computing Unit Managing Service, and environments in the computing unit itself.
Major Limitation: Resources Are Managed Ad-hoc
I think Texera's resource management has one major limitation: resources are managed ad-hoc. Each kind was built on its own, with its own tables, endpoints, and rules, and the codebase has no single definition of a resource that every kind follows. As a result, the same three things are done differently for each kind:
POST /workflow/create, but an environment withPOST /pve/db. A dataset is deleted withDELETE /dataset/{did}, but a workflow withPOST /workflow/delete.workflow_of_usertable for workflows, in anowner_uidcolumn for datasets and models, and in auidcolumn for the other kinds. The rules differ too: a user with read access can remove themselves from a shared workflow, but not from a shared dataset, and environments and warehouses cannot be shared at all.The codebase itself shows how far the kinds have drifted apart.
ResourceTables.scalawas added so that the access rules could be written once, but its own comment says that it fits only datasets and models, because workflows record ownership in a separate table and computing units have no public flag.Consequences: Backend Code Is Duplicated, Hard to Maintain, and Hard to Extend
The current backend codebase suffers from three problems:
ModelResource.scalarepeats 31 of the 32 endpoints ofDatasetResource.scala, and the access rules are implemented three times: for workflows, for datasets and models, and for computing units. The database repeats itself in the same way: 17 of its 42 tables are per-kind copies.Proposal: Unify the Resource Management
I propose to unify resource management. By unify I mean: designing and implementing common primitives that are shared across all kinds of resources.
Based on current Texera's position, I see three major primitives:
P1: Resource CRUD: every kind has an id, a name, and an owner, and every kind needs the same operations: create, list, read, update, and delete.
P2: Resource version CRUD: a workflow version, a dataset version, and a model version are the same concept, which is an immutable snapshot of a resource. The
dataset_versionandmodel_versiontables already have the same columns.P3: Resource access control: every kind needs the same decision, which is whether a user may read or write a resource. The four
*_user_accesstables already have the same three columns: the user, the resource, and the privilege.[image: Screenshot 2026-11-09 at 4.51.03 PM.png]
What stays specific to a kind is its own fields and actions, such as executing a workflow or uploading a file to a dataset. Once the common parts exist in one copy, a new kind defines only what is specific to it, and a feature built on the common parts works for every kind.
Implementation Proposal
I see at least two layers whose implementation needs to be refactored: the database schema layer and the API definition layer. Each layer needs its own detailed discussion, so below I only give my proposal for each.
Layer 1: Database Schema Layer
At this layer, my proposal is to store the common parts once, under two supertypes:
ResourceandResource Version.Before: each kind has its own tables for the common parts. Each kind keeps its own relationships to
User, tenownandaccessrelationships in total, and each versioned kind keeps its own version table.[image: Animation of today's database schema: the plain diagram first, then redundant access tables, redundant version tables, and what adding one kind costs, highlighted one at a time]
After: every kind is a subtype of
Resource, which has a singleaccessrelationship toUserwith the levels own, read, and write. Every version is a subtype ofResource Version, keyed by(rid, vno), so onelineagetable can link a version to the versions it was derived from. A new kind adds only its own fields underResource.[image: Animation of the proposed database schema: the plain diagram first, then one access relationship, one version model, easy to record resource lineage, and easy to add new resource kinds, highlighted one at a time]
Layer 2: API Definition Layer
My proposal at this layer is to give every kind the same endpoints for the three common parts. For each part, the table below lists the endpoints before and after. In the After column,
{kind}is the plural name of a kind, such asworkflowsordatasets,{rid}is the id of a resource,{vno}is the number of a version, and{uid}is the id of a user.Resource CRUD
Before, each kind spells the same operation in its own way, and some kinds lack an operation. After, every kind has the same five operations.
POST /workflow/create,POST /dataset/create,POST /model/create,POST /computing-unit/create,POST /pve/db,POST /warehousePOST /{kind}GET /workflow/list,GET /dataset/list,GET /model/list,GET /computing-unit,GET /pve/db,GET /warehouse/statusGET /{kind}GET /workflow/{wid},GET /dataset/{did},GET /model/{mid},GET /computing-unit/{cuid}; none for environments and warehousesGET /{kind}/{rid}POST /workflow/update/name,POST /dataset/update/name,POST /model/update/name,PUT /computing-unit/{cuid}/rename/{name},PUT /pve/db/{veid}; none for warehousesPATCH /{kind}/{rid}POST /workflow/delete,DELETE /dataset/{did},DELETE /model/{mid},DELETE /computing-unit/{cuid}/terminate,DELETE /pve/db/{veid},DELETE /warehouse/{whid}DELETE /{kind}/{rid}Resource Version CRUD
Before, workflow versions have their own root path and no endpoint to create one, because a version is made whenever a workflow is saved, while dataset and model versions put the operation in the path. After, every versioned kind has the same three operations. A version is numbered within its resource and immutable, so it has no update or delete.
POST /dataset/{did}/version/create,POST /model/{mid}/version/create; none for workflows, wherePOST /workflow/persistmakes a version as a side effectPOST /{kind}/{rid}/versionsGET /version/{wid},GET /dataset/{did}/version/list,GET /model/{mid}/version/listGET /{kind}/{rid}/versionsGET /version/{wid}/{vid},GET /dataset/{did}/version/{dvid}/rootFileNodes,GET /model/{mid}/version/{mvid}/rootFileNodesGET /{kind}/{rid}/versions/{vno}Resource Access Control
Before, the same sharing endpoints are defined four times, in three services. Environments and warehouses have none, and no endpoint checks access, so each service checks it in its own code. After, every kind is shared and checked in the same way.
GET /access/workflow/list/{wid}, plus a copy each for datasets, models, and computing unitsGET /{kind}/{rid}/accessPUT /access/workflow/grant/{wid}/{email}/{privilege}, plus the same three copiesPUT /{kind}/{rid}/access/{uid}DELETE /access/workflow/revoke/{wid}/{email}, plus the same three copiesDELETE /{kind}/{rid}/access/{uid}POST /access/evaluationAll reactions