main.rs 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181
  1. use std::net::{IpAddr, Ipv4Addr};
  2. use rand::{rngs::SmallRng, Rng, SeedableRng};
  3. use rocket::http::Status;
  4. use rocket::response::Redirect;
  5. use rocket::{figment::Figment, log::LogLevel, serde::json::Json, Config};
  6. use rocket_dyn_templates::{context, Template};
  7. use diesel::prelude::*;
  8. use crate::database::Db;
  9. use crate::models::Fortune;
  10. use crate::models::Message;
  11. use crate::models::World;
  12. use crate::schema::fortune;
  13. use crate::schema::world;
  14. #[macro_use]
  15. extern crate diesel;
  16. #[macro_use]
  17. extern crate rocket;
  18. extern crate rocket_sync_db_pools;
  19. mod database;
  20. mod models;
  21. mod schema;
  22. fn random() -> i32 {
  23. SmallRng::from_entropy().gen_range(1..10_000)
  24. }
  25. #[get("/plaintext")]
  26. fn plaintext() -> &'static str {
  27. "Hello, World!"
  28. }
  29. #[get("/json")]
  30. fn json() -> Json<Message> {
  31. let message = Message {
  32. message: "Hello, World!",
  33. };
  34. Json(message)
  35. }
  36. #[get("/db")]
  37. async fn db(db: Db) -> Result<Json<World>, Status> {
  38. let world = db
  39. .run(move |conn| world::table.find(random()).first::<World>(conn))
  40. .await;
  41. match world {
  42. Ok(world) => Ok(Json(world)),
  43. Err(_) => Err(Status::NotFound),
  44. }
  45. }
  46. #[get("/queries")]
  47. fn queries_empty() -> Redirect {
  48. Redirect::to(uri!(queries(1)))
  49. }
  50. #[get("/queries?<q>")]
  51. async fn queries(db: Db, q: u16) -> Result<Json<Vec<World>>, Status> {
  52. let q = q.clamp(1, 500);
  53. let mut results = Vec::with_capacity(q.into());
  54. for _ in 0..q {
  55. let world = db
  56. .run(move |conn| world::table.find(random()).first::<World>(conn))
  57. .await;
  58. match world {
  59. Ok(world) => results.push(world),
  60. Err(_) => return Err(Status::NotFound),
  61. }
  62. }
  63. Ok(Json(results))
  64. }
  65. #[get("/updates")]
  66. fn updates_empty() -> Redirect {
  67. Redirect::to(uri!(updates(1)))
  68. }
  69. #[get("/updates?<q>")]
  70. async fn updates(db: Db, q: u16) -> Result<Json<Vec<World>>, Status> {
  71. let q = q.clamp(1, 500);
  72. let mut results = Vec::with_capacity(q.into());
  73. for _ in 0..q {
  74. let world = db
  75. .run(move |conn| world::table.find(random()).first::<World>(conn))
  76. .await;
  77. match world {
  78. Ok(world) => results.push(world),
  79. Err(_) => return Err(Status::NotFound),
  80. }
  81. }
  82. for mut world in results.clone() {
  83. world.randomnumber = random();
  84. let result = db
  85. .run(move |conn| {
  86. diesel::update(world::table.find(world.id))
  87. .set(world::randomnumber.eq(world.randomnumber))
  88. .execute(conn)
  89. })
  90. .await;
  91. if let Err(_) = result {
  92. return Err(Status::InternalServerError);
  93. }
  94. }
  95. Ok(Json(results))
  96. }
  97. #[get("/fortunes")]
  98. async fn fortunes(db: Db) -> Template {
  99. let mut fortunes = db
  100. .run(|conn| fortune::table.load::<Fortune>(conn))
  101. .await
  102. .expect("Error loading fortunes from database.");
  103. fortunes.push(Fortune {
  104. id: 0,
  105. message: "Additional fortune added at request time.".to_string(),
  106. });
  107. fortunes.sort_by(|a, b| a.message.cmp(&b.message));
  108. Template::render("fortunes", context! { fortunes: fortunes })
  109. }
  110. #[launch]
  111. fn rocket() -> _ {
  112. let config = Config {
  113. address: IpAddr::V4(Ipv4Addr::new(0, 0, 0, 0)),
  114. port: 8000,
  115. keep_alive: 0,
  116. log_level: LogLevel::Off,
  117. ..Default::default()
  118. };
  119. let figment = Figment::from(config).merge((
  120. "databases.hello_world",
  121. rocket_sync_db_pools::Config {
  122. pool_size: 100,
  123. timeout: 3,
  124. url: rocket::Config::figment()
  125. .extract_inner("benchmark_database_url")
  126. .expect("Expected env: ROCKET_BENCHMARK_DATABASE_URL"),
  127. },
  128. ));
  129. rocket::custom(figment)
  130. .attach(Db::fairing())
  131. .attach(Template::fairing())
  132. .mount(
  133. "/",
  134. routes![
  135. plaintext,
  136. json,
  137. fortunes,
  138. db,
  139. queries_empty,
  140. queries,
  141. updates_empty,
  142. updates,
  143. ],
  144. )
  145. }