Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

how to let the Pingora server just run its tasks inside the provided current runtime #292

Closed
futurist opened this issue Jun 18, 2024 · 10 comments
Labels
question Further information is requested stale

Comments

@futurist
Copy link

Describe the bug

Thread panic when run_forever within tokio::spawn, like below:

pub async fn proxy_start() {
    // read command line arguments
    let opt: Opt = Opt::from_args();
    let mut my_server = Server::new(Some(opt)).unwrap();
    my_server.bootstrap();

    let mut my_proxy = pingora_proxy::http_proxy_service(
        &my_server.configuration,
        MyProxy {
            beta_counter: Mutex::new(0),
        },
    );
    my_proxy.add_tcp("0.0.0.0:6190");

    my_server.add_service(my_proxy);
    my_server.run_forever();
}

#[tokio::main]
async fn main() -> anyhow::Result<()> {
  tokio::spawn(async {
      proxy_start().await;
      println!("proxy server exited.");
  });
  // other server logic, like spawn a localhost for proxy.
}

Above will panic,

Cannot start a runtime from within a runtime.
This happens because a function (like `block_on`) attempted to block the current thread while the thread is being used to drive asynchronous tasks.

Pingora info

Please include the following information about your environment:

Pingora version: 0.2.0 from crates.io
Rust version: cargo 1.78.0 (54d8815d0 2024-03-26)
Operating system version: MacOS 13.4

@eaufavor eaufavor added the question Further information is requested label Jun 18, 2024
@eaufavor
Copy link
Member

Pingora Server inside an async runtime is not supported. The reason is the Server itself needs to spawn and manage the async runtimes but Tokio doesn't support doing so inside a runtime.

@futurist
Copy link
Author

So how to run tokio::spawn?

  • I've tried add a Background Service to start up my_server, and run a http server in tokio::spwan there, but the server is unresponsive, is it due to the #[async_trait] macro?
  • In normal #[tokio::main] async function, the http server work normally.

Even I've changed the conf.work_stealing = false when start the proxy server, the problem still exits.

@eaufavor
Copy link
Member

What is the goal you want to achieve here?
run_forever() shouldn't be and doesn't need to be inside a tokio runtime.

@futurist
Copy link
Author

The goal is to run pingora and many backend service at the same time, since it's mono app, only one executable deployed.

  • the proxy just a module in the app, many other service using tokio::spawn
  • and we don't need hot reload/reload without lose connection feature, just the proxy feature needed

@eaufavor
Copy link
Member

I see now.

Maybe you can try thread::spawn(|| { my_server.run_forever(); }); so that the pingora server is free from the current tokio runtime so that it can manage its own.

Or, if the question is "how to let the Pingora server just run its tasks inside the provided current runtime", that is a feature request that we might implement.

@futurist futurist changed the title Thread panic when run_forever within tokio::spawn how to let the Pingora server just run its tasks inside the provided current runtime Jun 21, 2024
@futurist
Copy link
Author

@eaufavor yes exactly. I've changed the title.

@futurist
Copy link
Author

also the process::exit behavior prevent other runtime service to shutdown gracefully, which is also related issue: #154

Copy link

This question has been stale for a week. It will be closed in an additional day if not updated.

@github-actions github-actions bot added the stale label Jun 30, 2024
Copy link

github-actions bot commented Jul 1, 2024

This issue has been closed because it has been stalled with no activity.

@github-actions github-actions bot closed this as not planned Won't fix, can't repro, duplicate, stale Jul 1, 2024
@fredr
Copy link

fredr commented Jul 3, 2024

Depending on what you need you can also start the pingora Service in the current runtime rather than starting up a whole pingora Server.

You would then have to implement your own signal handling, and you wouldn't get other features that the pignora Server would give you, like daemonization etc.

let mut my_proxy = pingora_proxy::http_proxy_service(
    &conf,
    MyProxy {
        beta_counter: Mutex::new(0),
    },
);
my_proxy.add_tcp("0.0.0.0:6190");

let (tx, rx) = watch::channel(false);
my_proxy.start_service(None, rx).await;

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
question Further information is requested stale
Projects
None yet
Development

No branches or pull requests

3 participants