pgcentralfoundation / pgrx

Build Postgres Extensions with Rust!
Other
3.57k stars 242 forks source link

A question about bgworker #1727

Open xingtanzjr opened 4 months ago

xingtanzjr commented 4 months ago

I am investigating to launch several background process to do a parallel table scan in my index extension. But now, I encounter some problems.

When I use pg_sys::LaunchParallelWorkers() to launch all the parallel workers. I got an error which said

ERROR:  could not access file "": No such file or directory
CONTEXT:  parallel worker

I guess it is because the module name for pctx is not configured correctly. The way I do that is

let module_name = CString::new("extension_name").expect("CString::new failed");
let function_name = CString::new("parallel_worker_build_index").expect("CString::new failed");
let pcxt = pg_sys::CreateParallelContext(module_name.as_ptr(), function_name.as_ptr(), 1 as i32);

I am not sure could pgrx can load the .so file properly if I do so.

Then I switch to another way to do that, that is, leverage the bgworker wrapped by pgrx. I noticed that there is a method named load_dynamic() for bgworker to launch a backgroundworker any time when needed. But when I read the example in pgrx's source code, it says the bgworker could only used in _PGinit(). See here

https://github.com/pgcentralfoundation/pgrx/blob/ed5aa06775f9f1547685bc853ef9cdab1eb22662/pgrx-examples/bgworker/src/lib.rs#L14C1-L27C3

Could someone have some experience about that ? My question are:

  1. Can I use pg_sys::LaunchParallelWorker(pctx) in pgrx ?
  2. Can bgworker be created any time using load_dynamic ?

I am struggling in this issue for several days so much appreciate for any input. Thanks !

ccleve commented 3 months ago

I don't have an answer to your first question, but to your second, this works for me:

    let db_oid = unsafe { MyDatabaseId };
    let index_oid = pg_indexrel.oid();
    let extra = format!("{}/{}", db_oid.as_u32(), index_oid.as_u32());

    let worker = BackgroundWorkerBuilder::new(name.as_str())
        .set_function("background_worker_merge")
        .set_library("my_extension")
        .set_argument(None)
        .set_extra(&extra)
        .enable_spi_access() // odd bugs without this
        .load_dynamic();