-
Notifications
You must be signed in to change notification settings - Fork 3
/
create_tasks.rs
129 lines (112 loc) · 4.12 KB
/
create_tasks.rs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
use std::io;
use futures::TryFutureExt;
use actix::{Handler, Message, ResponseFuture};
use serde::{Deserialize};
use super::{PgConnection};
use rand::{RngCore, FromEntropy};
use rand::rngs::SmallRng;
use tokio_postgres::{binary_copy::BinaryCopyInWriter, types::Type};
use futures::{pin_mut};
use lipsum::MarkovChain;
static FNAMES: [&str; 300] = include!("texts/fnames.json");
static LNAMES: [&str; 300] = include!("texts/lnames.json");
static DIALOGUES: &str = include!("texts/ring.txt");
/// Create N tasks assigned to M workers
/// Can be run only on empty DB
#[derive(Deserialize)]
pub struct CreateTasks {
tasks: i32,
workers: i32,
}
impl Message for CreateTasks {
type Result = io::Result<usize>;
}
impl Handler<CreateTasks> for PgConnection {
type Result = ResponseFuture<io::Result<usize>>;
fn handle(
&mut self, CreateTasks { tasks, workers }: CreateTasks, _: &mut Self::Context,
) -> Self::Result {
let cl = self.client();
let mut rng = SmallRng::from_entropy();
let mut gen_text = MarkovChain::new_with_rng(SmallRng::from_entropy());
gen_text.learn(DIALOGUES);
let workers_data: Vec<Worker> = (1..=workers).map(|id| Worker::gen(id, &mut rng)).collect();
let tasks_data: Vec<Task> = (1..=tasks).map(|id| Task::gen(id, &workers_data, &mut rng, &mut gen_text)).collect();
let fut = async move {
// Copy in workers
let workers_sink = cl.conn.copy_in("COPY worker (id, name, email) FROM STDIN BINARY").await?;
let writer = BinaryCopyInWriter::new(workers_sink, &[Type::INT4, Type::VARCHAR, Type::VARCHAR]);
pin_mut!(writer);
for worker in workers_data {
writer.as_mut().write(&[&worker.id, &worker.name, &worker.email]).await?
}
writer.finish().await?;
// Copy in tasks
let tasks_sink = cl.conn.copy_in("COPY task (id, summary, description, assignee_id) FROM STDIN BINARY").await?;
let writer = BinaryCopyInWriter::new(tasks_sink, &[Type::INT4, Type::VARCHAR, Type::VARCHAR, Type::INT4]);
pin_mut!(writer);
for task in tasks_data {
writer.as_mut().write(&[&task.id, &task.summary, &task.description, &task.assignee_id]).await?
}
writer.finish().await?;
Ok(tasks as usize)
};
Box::pin(fut.map_err(|err: tokio_postgres::error::Error| { dbg!(&err); io::Error::new(io::ErrorKind::Other, format!("{:?}", err)) } ))
}
}
// CREATE TABLE workers (
// id SERIAL PRIMARY KEY,
// name varchar(255) NOT NULL,
// email varchar(255) NULL,
// score integer DEFAULT 0
// );
struct Worker {
id: i32,
name: String,
email: String
}
impl Worker {
pub fn gen(id: i32, rng: &mut impl RngCore) -> Self {
let mut name: String = FNAMES[rng.next_u32() as usize % 300].to_string();
name.push(' ');
name.push_str(LNAMES[rng.next_u32() as usize % 300]);
let mut email = name.replace(" ", ".");
email.push_str("@gmail.com");
Worker {
id,
name,
email
}
}
}
// CREATE TABLE tasks (
// id SERIAL PRIMARY KEY,
// summary varchar(255) NOT NULL,
// description text NOT NULL,
// assignee_id integer NULL REFERENCES workers,
// created TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP
// );
struct Task {
id: i32,
summary: String,
description: String,
assignee_id: i32
}
impl Task {
pub fn gen<R: RngCore>(id: i32, workers: &Vec<Worker>, rng: &mut impl RngCore, gen_text: &mut MarkovChain<R>) -> Self {
let assignee = &workers[rng.next_u32() as usize % workers.len()];
let assignee_id = assignee.id;
let mut summary: String = assignee.name.clone();
summary.push(' ');
summary.push_str(gen_text.generate(rng.next_u32() as usize % 10).as_str());
let mut description = summary.clone();
description.push(' ');
description.push_str(gen_text.generate(rng.next_u32() as usize % 1000).as_str());
Task {
id,
summary,
description,
assignee_id
}
}
}