Skip to content

AdvisoryLockGuard without lifetime #3429

Open
@bonsairobo

Description

@bonsairobo

Is your feature request related to a problem? Please describe.

I have an issue trying to use AdvisoryLockGuard. The lifetime prevents me from writing code that acquires the lock and then passes the guard into a 'static closure. This is relevant because I want to be able to write an axum request handler that upgrades to a websocket, but I want any errors that occur while acquiring the lock to be sent in a Response instead of a websocket close message.

A rought sketch of how I want the code to look:

async fn my_handler(
    ws: WebSocketUpgrade,
    State(state): State<MyState>,
) -> Result<Response, ApiError> {
    let db = state.get_db();
    let lock = PgAdvisoryLock::new(...);
    let Either::Left(mut guard) = model_lock.try_acquire(&mut db).await? else {
        return Err(ApiError::Foo(...));
    };

    let response = ws.on_upgrade(move |socket| async move {
        // Have the guard in here while doing stuff with the socket...
    });

    Ok(response)
}

Describe the solution you'd like

I think having an API similar to this would work, though I'm not sure how feasible it would be to implement that for sqlx.

Describe alternatives you've considered

AFAICT my only (safe) option is to move the PgAdvisoryLock into the task scope that handles the socket. This means I must return any errors within that scope along the socket instead of in an HTTP response.

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions