ntex-rs/ntex

Option to configure underlying runtime

Closed this issue · 6 comments

I am trying to use ScyllaDB with ntex and tokio, but the application panics due to a stack overflow. I figured out that it has something to do with the configuration of the tokio runtime and how ntex's System builds and configures tokio.

A solution (and something that bothered me from the start) is an option for setting the tokio runtime or at least somehow configure it.

Thanks for any help :D

you can create your own tokio runtime and start it.

code would look like this:

async fn my_ntex_main() {
   ...
}

/// tokio async code

...start-tokio-runtime...

/// start ntex workers
ntex::rt::System::new("ntex-app")
   .run_local(my_ntex_main())

@fafhrd91 this is also the solution I thought about, however it's far from ideal since my database is inside my application state, so I would need to create a new tokio runtime runtime just to create the app state (+ database) and then move it into the ntex main.

The issue I want to address is not my database stack overflow error (this is just an example/introduction), but the customization options of the ntex tokio runtime

.run_local() allows you to run ntex from inside tokio runtime, would it work?

.run_local() allows you to run ntex from inside tokio runtime, would it work?

Oh, I thought that just runs the ntex main in the default executor.
I managed to run ntex in a custom runtime:

Builder::new_current_thread()
        .thread_stack_size(10 * 1028 * 1028)
        .enable_all()
        .build()
        .expect("failed to create tokio runtime")
        .block_on(async {
            ntex::rt::System::build()
                .name("server-system")
                .stop_on_panic(true)
                .finish()
                .run_local(async { server::run().await })
                .await
                .expect("failed to run server")
        })

However, I still get a stack overflow when calling this inside the ntex system:

// create scylla database
let database = SessionBuilder::new()
            .known_node(DATABASE_URI.clone())
            .build()
            .await
            .unwrap();

I tried configuring the runtime using no options, a few megabytes of stack size and even more, however it still gives me the same error.

At the end I got this solution:

  1. Create tokio runtime
  2. Create database inside tokio runtime (not inside ntex system!)
  3. Create and run ntex System

This solves the main issue of creating a tokio runtime just for the database, but I still can't create it inside the ntex System.
Though that's likely another issue.

added stack size and block on config #411

I was looking for a similar solution and tried the above. It seems to work, but I wondered if things are working as expected...

Asking specifically because when using #[ntex::main] I see 2 ntex-rt:worker:xxx threads and 3 ntex-server threads and no tokio worker threads.

When using the above, I notice I now see two tokio worker threads, but I still see the 2 ntex-rt:worker:xxx threads and the 3 ntext-server threads.

I would somehow expect that those ntex worker threads would now be replaced by the tokio worker threads, but instead it seems to add them.

So in that case, does ntex really use the tokio worker threads, or does it still spawn all its own tokio threads as well?