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
use crate::{api::Response, service::cookie::CookieService, SESSION_COOKIE};
use log::{info, warn};
use serde::{Deserialize, Serialize};
use std::time::Duration;
use webapp::{
protocol::{model::Session, request::LoginSession, response::Login},
API_URL_LOGIN_SESSION,
};
use yew::{
format::Json,
prelude::{worker::*, *},
services::{fetch::FetchTask, IntervalService, Task},
};
pub enum Message {
Fetch(Response<Login>),
Update,
}
#[derive(Deserialize, Serialize)]
pub enum Request {
Start,
Stop,
}
#[derive(Deserialize, Serialize)]
pub struct TimerResponse;
pub struct SessionTimerAgent {
agent_link: AgentLink<SessionTimerAgent>,
callback: Callback<()>,
cookie_service: CookieService,
fetch_task: Option<FetchTask>,
timer_task: Option<Box<dyn Task>>,
}
impl Agent for SessionTimerAgent {
type Input = Request;
type Message = Message;
type Output = TimerResponse;
type Reach = Context<Self>;
fn create(link: AgentLink<Self>) -> Self {
Self {
callback: link.callback(|_| Message::Update),
agent_link: link,
cookie_service: CookieService::new(),
fetch_task: None,
timer_task: None,
}
}
fn update(&mut self, msg: Self::Message) {
match msg {
Message::Update => {
info!("Updating current session");
if let Ok(token) = self.cookie_service.get(SESSION_COOKIE) {
self.fetch_task = fetch! {
LoginSession(Session::new(token)) => API_URL_LOGIN_SESSION,
self.agent_link, Message::Fetch,
|| {},
|| {
warn!("Unable to create scheduled session login request");
}
};
}
}
Message::Fetch(response) => {
let (meta, Json(body)) = response.into_parts();
if meta.status.is_success() {
match body {
Ok(Login(Session { token })) => {
info!("Scheduled session based login succeed");
self.cookie_service.set(SESSION_COOKIE, &token);
}
_ => warn!("Got wrong scheduled session login response"),
}
} else {
info!(
"Scheduled session login failed with status: {}",
meta.status
);
}
self.fetch_task = None;
}
}
}
fn handle_input(&mut self, msg: Self::Input, _: HandlerId) {
match msg {
Request::Start => {
let handle = IntervalService::spawn(Duration::from_secs(10), self.callback.clone());
self.timer_task = Some(Box::new(handle));
}
Request::Stop => {
if self.timer_task.take().is_some() {
self.timer_task = None;
}
}
}
}
}