Split orchestration by durable use case

This commit is contained in:
ms2k 2026-07-19 01:33:14 +09:00
commit fa81cb7f21
4 changed files with 609 additions and 513 deletions

View file

@ -40,6 +40,7 @@ use sqlx::{PgPool, types::Json};
use time::{OffsetDateTime, format_description::well_known::Rfc3339};
mod events;
mod routes;
const DEFAULT_LIMIT: u32 = 50;
const MAX_LIMIT: u32 = 200;
@ -170,56 +171,11 @@ pub fn configure_public_api(config: &mut web::ServiceConfig) {
.limit(1024 * 1024)
.error_handler(|_, _| PublicApiError::invalid_request().into()),
)
.route("/jobs", web::post().to(submit_job))
.route("/jobs", web::get().to(list_jobs))
.route("/jobs/{job_id}", web::get().to(get_job))
.route("/jobs/{job_id}/result", web::get().to(get_job_result))
.route(
"/jobs/{job_id}/result/members",
web::get().to(list_result_members),
)
.route(
"/jobs/{job_id}/result/members/{member_id}/content",
web::get().to(access_result_member),
)
.route("/jobs/{job_id}/cancel", web::post().to(cancel_job))
.route(
"/jobs/{job_id}/soft-delete",
web::post().to(soft_delete_job),
)
.route("/jobs/{job_id}/restore", web::post().to(restore_job))
.route(
"/jobs/{job_id}/hard-delete",
web::post().to(hard_delete_job),
)
.route("/jobs/{job_id}/revoke", web::post().to(revoke_job))
.route("/jobs/{job_id}/attempts", web::get().to(list_job_attempts))
.route(
"/source-credentials",
web::post().to(create_source_credential),
)
.route(
"/source-credentials",
web::get().to(list_source_credentials),
)
.route(
"/source-credentials/{credential_id}",
web::get().to(get_source_credential),
)
.route(
"/source-credentials/{credential_id}/versions",
web::post().to(rotate_source_credential),
)
.route(
"/source-credentials/{credential_id}/revoke",
web::post().to(revoke_source_credential),
)
.route(
"/deletions/{operation_id}",
web::get().to(get_deletion_operation),
)
.route("/event-tickets", web::post().to(events::issue_ticket))
.route("/events", web::get().to(events::connect)),
.configure(routes::jobs)
.configure(routes::results)
.configure(routes::credentials)
.configure(routes::deletions)
.configure(routes::events),
);
}

View file

@ -0,0 +1,80 @@
use actix_web::web;
use super::{
access_result_member, cancel_job, create_source_credential, events as event_handlers,
get_deletion_operation, get_job, get_job_result, get_source_credential, hard_delete_job,
list_job_attempts, list_jobs, list_result_members, list_source_credentials, restore_job,
revoke_job, revoke_source_credential, rotate_source_credential, soft_delete_job, submit_job,
};
pub(super) fn jobs(config: &mut web::ServiceConfig) {
config
.route("/jobs", web::post().to(submit_job))
.route("/jobs", web::get().to(list_jobs))
.route("/jobs/{job_id}", web::get().to(get_job))
.route("/jobs/{job_id}/cancel", web::post().to(cancel_job))
.route(
"/jobs/{job_id}/soft-delete",
web::post().to(soft_delete_job),
)
.route("/jobs/{job_id}/restore", web::post().to(restore_job))
.route(
"/jobs/{job_id}/hard-delete",
web::post().to(hard_delete_job),
)
.route("/jobs/{job_id}/revoke", web::post().to(revoke_job))
.route("/jobs/{job_id}/attempts", web::get().to(list_job_attempts));
}
pub(super) fn results(config: &mut web::ServiceConfig) {
config
.route("/jobs/{job_id}/result", web::get().to(get_job_result))
.route(
"/jobs/{job_id}/result/members",
web::get().to(list_result_members),
)
.route(
"/jobs/{job_id}/result/members/{member_id}/content",
web::get().to(access_result_member),
);
}
pub(super) fn credentials(config: &mut web::ServiceConfig) {
config
.route(
"/source-credentials",
web::post().to(create_source_credential),
)
.route(
"/source-credentials",
web::get().to(list_source_credentials),
)
.route(
"/source-credentials/{credential_id}",
web::get().to(get_source_credential),
)
.route(
"/source-credentials/{credential_id}/versions",
web::post().to(rotate_source_credential),
)
.route(
"/source-credentials/{credential_id}/revoke",
web::post().to(revoke_source_credential),
);
}
pub(super) fn deletions(config: &mut web::ServiceConfig) {
config.route(
"/deletions/{operation_id}",
web::get().to(get_deletion_operation),
);
}
pub(super) fn events(config: &mut web::ServiceConfig) {
config
.route(
"/event-tickets",
web::post().to(event_handlers::issue_ticket),
)
.route("/events", web::get().to(event_handlers::connect));
}

View file

@ -30,6 +30,8 @@ use remora_target::{ContentSha256, ObjectIdentity, StoredObject, attempt_staging
use sha2::{Digest, Sha256};
use time::{OffsetDateTime, format_description::well_known::Rfc3339};
mod routes;
#[derive(Clone, Debug, Eq, PartialEq)]
pub struct AuthenticatedWorker {
pub identity: OpaqueId,
@ -96,39 +98,9 @@ pub fn configure_worker_api(config: &mut web::ServiceConfig) {
.limit(1024 * 1024)
.error_handler(|_, _| WorkerApiError::invalid_request().into()),
)
.route("/health/ready", web::get().to(worker_ready))
.route("/jobs/{job_id}/claim", web::post().to(claim))
.route("/attempts/{attempt_id}/renew", web::post().to(renew))
.route("/attempts/{attempt_id}/activate", web::post().to(activate))
.route("/attempts/{attempt_id}/stop", web::post().to(stop))
.route(
"/attempts/{attempt_id}/staging/write-intent",
web::post().to(register_staging_write_intent),
)
.route(
"/attempts/{attempt_id}/staging/object",
web::post().to(register_staging_object),
)
.route(
"/attempts/{attempt_id}/staging/multipart",
web::post().to(register_staging_multipart),
)
.route(
"/attempts/{attempt_id}/resolved-source",
web::post().to(pin_resolved_source),
)
.route(
"/attempts/{attempt_id}/checkpoint",
web::post().to(persist_checkpoint),
)
.route(
"/attempts/{attempt_id}/progress",
web::post().to(report_progress),
)
.route(
"/attempts/{attempt_id}/outcome",
web::post().to(report_outcome),
),
.configure(routes::authority)
.configure(routes::staging)
.configure(routes::execution),
);
}

View file

@ -0,0 +1,52 @@
use actix_web::web;
use super::{
activate, claim, persist_checkpoint, pin_resolved_source, register_staging_multipart,
register_staging_object, register_staging_write_intent, renew, report_outcome, report_progress,
stop, worker_ready,
};
pub(super) fn authority(config: &mut web::ServiceConfig) {
config
.route("/health/ready", web::get().to(worker_ready))
.route("/jobs/{job_id}/claim", web::post().to(claim))
.route("/attempts/{attempt_id}/renew", web::post().to(renew))
.route("/attempts/{attempt_id}/activate", web::post().to(activate))
.route("/attempts/{attempt_id}/stop", web::post().to(stop));
}
pub(super) fn staging(config: &mut web::ServiceConfig) {
config
.route(
"/attempts/{attempt_id}/staging/write-intent",
web::post().to(register_staging_write_intent),
)
.route(
"/attempts/{attempt_id}/staging/object",
web::post().to(register_staging_object),
)
.route(
"/attempts/{attempt_id}/staging/multipart",
web::post().to(register_staging_multipart),
);
}
pub(super) fn execution(config: &mut web::ServiceConfig) {
config
.route(
"/attempts/{attempt_id}/resolved-source",
web::post().to(pin_resolved_source),
)
.route(
"/attempts/{attempt_id}/checkpoint",
web::post().to(persist_checkpoint),
)
.route(
"/attempts/{attempt_id}/progress",
web::post().to(report_progress),
)
.route(
"/attempts/{attempt_id}/outcome",
web::post().to(report_outcome),
);
}