Spawn_blocking in tokio::main

I have a rust app using tokio::main where I use the tonic crate to service a gRPC server for incoming gRPC data, which is all in a tokio::spawn() thread. That thread receives the gRPC data, sends it through a tokio::mpsc::channel and then another tokio::spawn() thread with the tokio::mpsc::channel receiver awaits that data and stores it into an embedded rocksdb database. I need another thread that one by on in a FIFO style operation takes the most recent data stored in the database and reads it out and performs blocking operations on it.

Right now, I have it so the gRPC server code is in a tokio::spawn() and I can see it is successfully storing the data into the database. My question is, how do properly I add the synchronous operations of monitoring the most recent data stored in the database and perform synchronous blocking operations on it in the same app?

I have it working where the logic is like this below, but I am not sure if this is the best approach. It has a tokio spawn_blocking thread with a loop in it forever, but I am stuck on if this is bad practice or not.

tokio::task::spawn_blocking(move || {
loop {
// Read out of database when there is new data
// Perform other synchronous things..

Any input or tips on how to handle infinite loop synchronous operations in a tokio app like this would be extremely helpful. Thank you!

See this article:

Since you're looping forever, you should use std::thread::spawn.

Thanks for linking the article, very insightful. So it seems like there is no problem having an infinite std:: thread ::spawn inside an application that has a tokio::main? i.e. the tokio runtime will not be blocked even if the std::thead::spawn contains blocking code.

Indeed. As long as you don't block the runtime's threads, there's no problem. You can do anything you want in std::thread::spawn threads.