The main function

Before we create the main function, we have to embed migrations using the embed_migrations! macro call:

embed_migrations!();

This call creates an embedded_migrations module, which contains the run function, which applies all migrations to a database. But before we use it, let's add the Config struct to read the database connection link from a configuration file or an environment variable using the config crate:

#[derive(Deserialize)]
struct Config {
database: Option<String>,
}

This struct contains only a single parameter—the optional String with a connection link to the database. We will set this parameter later with Docker Compose using the DBSYNC_DATABASE environment variable. We have added the DBSYNC prefix in the main function. Look at the full code of the main function:

fn main() -> Result<(), Error> {
env_logger::init();
let mut config = config::Config::default();
config.merge(config::Environment::with_prefix("DBSYNC"))?;
let config: Config = config.try_into()?;
let db_address = config.database.unwrap_or("postgres://localhost/".into());
debug!("Waiting for database...");
loop {
let conn: Result<PgConnection, _> = Connection::establish(&db_address);
if let Ok(conn) = conn {
debug!("Database connected");
embedded_migrations::run(&conn)?;
break;
}
}
debug!("Database migrated");
Ok(())
}

In the preceding code, we initialized env_logger to print information to strerr. After, we created a generic Config instance from the config module and merged environment variables with the DBSYNC prefix. If the config merged successfully, we try to convert it to a value of our own Config type that we declared before. We'll use a config to extract a link of a connection to the database. If the value is not provided, we will use the postgres://localhost/ link.

When a connection link is ready, we use a loop to try to connect to the database. We will try to connect to it until it succeeds, because we will use this worker with Docker Compose, and despite the fact we will start a container with the database, it can be unavailable when a database instance is starting. We use a loop to wait for the connection to be ready.

When the connection is ready, we use it to apply embedded migrations with the run method of the embedded_migrations module. After the migrations have been applied, we break the loop and stop the worker.

We have all the microservices ready to launch, but their disadvantage is that their source code also remains in the image. This is not good if we want to hide the implementation details of our microservices. Let's explore a technique that hides the sources of microservices using the image building cache.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
18.118.205.235