|
@@ -5,7 +5,8 @@ use actix::prelude::*;
|
|
use bytes::{Bytes, BytesMut};
|
|
use bytes::{Bytes, BytesMut};
|
|
use futures::stream::futures_unordered::FuturesUnordered;
|
|
use futures::stream::futures_unordered::FuturesUnordered;
|
|
use futures::{FutureExt, StreamExt, TryStreamExt};
|
|
use futures::{FutureExt, StreamExt, TryStreamExt};
|
|
-use rand::{thread_rng, Rng, ThreadRng};
|
|
|
|
|
|
+use rand::rngs::SmallRng;
|
|
|
|
+use rand::{Rng, SeedableRng};
|
|
use tokio_postgres::{connect, Client, NoTls, Statement};
|
|
use tokio_postgres::{connect, Client, NoTls, Statement};
|
|
|
|
|
|
use crate::models::World;
|
|
use crate::models::World;
|
|
@@ -16,7 +17,7 @@ pub struct PgConnection {
|
|
cl: Client,
|
|
cl: Client,
|
|
fortune: Statement,
|
|
fortune: Statement,
|
|
world: Statement,
|
|
world: Statement,
|
|
- rng: ThreadRng,
|
|
|
|
|
|
+ rng: SmallRng,
|
|
}
|
|
}
|
|
|
|
|
|
impl Actor for PgConnection {
|
|
impl Actor for PgConnection {
|
|
@@ -28,19 +29,16 @@ impl PgConnection {
|
|
let (cl, conn) = connect(db_url, NoTls)
|
|
let (cl, conn) = connect(db_url, NoTls)
|
|
.await
|
|
.await
|
|
.expect("can not connect to postgresql");
|
|
.expect("can not connect to postgresql");
|
|
- actix_rt::spawn(conn.map(|res| panic!("{:?}", res)));
|
|
|
|
|
|
+ actix_rt::spawn(conn.map(|_| ()));
|
|
|
|
|
|
- let fortune = cl.prepare("SELECT id, message FROM fortune").await.unwrap();
|
|
|
|
- let world = cl
|
|
|
|
- .prepare("SELECT id, randomnumber FROM world WHERE id=$1")
|
|
|
|
- .await
|
|
|
|
- .unwrap();
|
|
|
|
|
|
+ let fortune = cl.prepare("SELECT * FROM fortune").await.unwrap();
|
|
|
|
+ let world = cl.prepare("SELECT * FROM world WHERE id=$1").await.unwrap();
|
|
|
|
|
|
Ok(PgConnection::create(move |_| PgConnection {
|
|
Ok(PgConnection::create(move |_| PgConnection {
|
|
cl,
|
|
cl,
|
|
fortune,
|
|
fortune,
|
|
world,
|
|
world,
|
|
- rng: thread_rng(),
|
|
|
|
|
|
+ rng: SmallRng::from_entropy(),
|
|
}))
|
|
}))
|
|
}
|
|
}
|
|
}
|
|
}
|
|
@@ -55,7 +53,7 @@ impl Handler<RandomWorld> for PgConnection {
|
|
type Result = ResponseFuture<Result<Bytes, io::Error>>;
|
|
type Result = ResponseFuture<Result<Bytes, io::Error>>;
|
|
|
|
|
|
fn handle(&mut self, _: RandomWorld, _: &mut Self::Context) -> Self::Result {
|
|
fn handle(&mut self, _: RandomWorld, _: &mut Self::Context) -> Self::Result {
|
|
- let random_id = self.rng.gen_range::<i32>(1, 10_001);
|
|
|
|
|
|
+ let random_id = (self.rng.gen::<u32>() % 10_000 + 1) as i32;
|
|
let fut = self.cl.query_one(&self.world, &[&random_id]);
|
|
let fut = self.cl.query_one(&self.world, &[&random_id]);
|
|
|
|
|
|
Box::pin(async move {
|
|
Box::pin(async move {
|
|
@@ -90,7 +88,7 @@ impl Handler<RandomWorlds> for PgConnection {
|
|
fn handle(&mut self, msg: RandomWorlds, _: &mut Self::Context) -> Self::Result {
|
|
fn handle(&mut self, msg: RandomWorlds, _: &mut Self::Context) -> Self::Result {
|
|
let worlds = FuturesUnordered::new();
|
|
let worlds = FuturesUnordered::new();
|
|
for _ in 0..msg.0 {
|
|
for _ in 0..msg.0 {
|
|
- let w_id: i32 = self.rng.gen_range(1, 10_001);
|
|
|
|
|
|
+ let w_id = (self.rng.gen::<u32>() % 10_000 + 1) as i32;
|
|
worlds.push(
|
|
worlds.push(
|
|
self.cl
|
|
self.cl
|
|
.query_one(&self.world, &[&w_id])
|
|
.query_one(&self.world, &[&w_id])
|
|
@@ -122,21 +120,17 @@ impl Handler<UpdateWorld> for PgConnection {
|
|
fn handle(&mut self, msg: UpdateWorld, _: &mut Self::Context) -> Self::Result {
|
|
fn handle(&mut self, msg: UpdateWorld, _: &mut Self::Context) -> Self::Result {
|
|
let worlds = FuturesUnordered::new();
|
|
let worlds = FuturesUnordered::new();
|
|
for _ in 0..msg.0 {
|
|
for _ in 0..msg.0 {
|
|
- let id: i32 = self.rng.gen_range(1, 10_001);
|
|
|
|
- let w_id: i32 = self.rng.gen_range(1, 10_001);
|
|
|
|
|
|
+ let id = (self.rng.gen::<u32>() % 10_000 + 1) as i32;
|
|
|
|
+ let w_id = (self.rng.gen::<u32>() % 10_000 + 1) as i32;
|
|
worlds.push(self.cl.query_one(&self.world, &[&w_id]).map(
|
|
worlds.push(self.cl.query_one(&self.world, &[&w_id]).map(
|
|
move |res| match res {
|
|
move |res| match res {
|
|
Err(e) => {
|
|
Err(e) => {
|
|
Err(io::Error::new(io::ErrorKind::Other, format!("{:?}", e)))
|
|
Err(io::Error::new(io::ErrorKind::Other, format!("{:?}", e)))
|
|
}
|
|
}
|
|
- Ok(row) => {
|
|
|
|
- let mut world = World {
|
|
|
|
- id: row.get(0),
|
|
|
|
- randomnumber: row.get(1),
|
|
|
|
- };
|
|
|
|
- world.randomnumber = id;
|
|
|
|
- Ok(world)
|
|
|
|
- }
|
|
|
|
|
|
+ Ok(row) => Ok(World {
|
|
|
|
+ id: row.get(0),
|
|
|
|
+ randomnumber: id,
|
|
|
|
+ }),
|
|
},
|
|
},
|
|
));
|
|
));
|
|
}
|
|
}
|
|
@@ -145,20 +139,19 @@ impl Handler<UpdateWorld> for PgConnection {
|
|
Box::pin(async move {
|
|
Box::pin(async move {
|
|
let worlds: Vec<World> = worlds.try_collect().await?;
|
|
let worlds: Vec<World> = worlds.try_collect().await?;
|
|
|
|
|
|
- let mut update = String::with_capacity(120 + 6 * msg.0 as usize);
|
|
|
|
- update.push_str(
|
|
|
|
- "UPDATE world SET randomnumber = temp.randomnumber FROM (VALUES ",
|
|
|
|
- );
|
|
|
|
-
|
|
|
|
|
|
+ let mut q = String::with_capacity(100 + 24 * msg.0 as usize);
|
|
|
|
+ q.push_str("UPDATE world SET randomnumber = CASE id ");
|
|
for w in &worlds {
|
|
for w in &worlds {
|
|
- let _ = write!(&mut update, "({}, {}),", w.id, w.randomnumber);
|
|
|
|
|
|
+ let _ = write!(&mut q, "when {} then {} ", w.id, w.randomnumber);
|
|
}
|
|
}
|
|
- update.pop();
|
|
|
|
- update.push_str(
|
|
|
|
- " ORDER BY 1) AS temp(id, randomnumber) WHERE temp.id = world.id",
|
|
|
|
- );
|
|
|
|
|
|
+ q.push_str("ELSE randomnumber END WHERE id IN (");
|
|
|
|
+ for w in &worlds {
|
|
|
|
+ let _ = write!(&mut q, "{},", w.id);
|
|
|
|
+ }
|
|
|
|
+ q.pop();
|
|
|
|
+ q.push(')');
|
|
|
|
|
|
- cl.simple_query(&update)
|
|
|
|
|
|
+ cl.simple_query(&q)
|
|
.await
|
|
.await
|
|
.map_err(|e| io::Error::new(io::ErrorKind::Other, format!("{:?}", e)))?;
|
|
.map_err(|e| io::Error::new(io::ErrorKind::Other, format!("{:?}", e)))?;
|
|
|
|
|