Browse Source

learning task continue

pull/25/head
Alexey Velikiy 3 years ago
parent
commit
1e69ec465c
  1. 31
      server/src/api/analytics.rs
  2. 7
      server/src/api/mod.rs
  3. 27
      server/src/services/analytic_service/analytic_client.rs
  4. 50
      server/src/services/analytic_service/analytic_service.rs
  5. 7
      server/src/services/analytic_service/mod.rs
  6. 8
      server/src/services/analytic_service/types.rs
  7. 0
      server/src/services/mod.rs

31
server/src/api/analytics.rs

@ -1,13 +1,13 @@
pub mod filters { pub mod filters {
use super::handlers; use super::handlers;
use super::models::{ListOptions, Srv}; use super::models::{Client, ListOptions};
use warp::Filter; use warp::Filter;
/// The 4 REST API filters combined. /// The 4 REST API filters combined.
pub fn filters( pub fn filters(
srv: Srv, client: Client,
) -> impl Filter<Extract = impl warp::Reply, Error = warp::Rejection> + Clone { ) -> impl Filter<Extract = impl warp::Reply, Error = warp::Rejection> + Clone {
list(srv.clone()) list(client.clone())
// TODO: /status endpoint // TODO: /status endpoint
// .or(create(db.clone())) // .or(create(db.clone()))
// // .or(update(db.clone())) // // .or(update(db.clone()))
@ -16,30 +16,30 @@ pub mod filters {
/// GET /analytics?from=3&to=5 /// GET /analytics?from=3&to=5
pub fn list( pub fn list(
db: Srv, client: Client,
) -> impl Filter<Extract = impl warp::Reply, Error = warp::Rejection> + Clone { ) -> impl Filter<Extract = impl warp::Reply, Error = warp::Rejection> + Clone {
warp::path!("analytics") warp::path!("analytics")
.and(warp::get()) .and(warp::get())
.and(warp::query::<ListOptions>()) .and(warp::query::<ListOptions>())
.and(with_srv(db)) .and(with_client(client))
.and_then(handlers::list) .and_then(handlers::list)
} }
fn with_srv( fn with_client(
srv: Srv, client: Client,
) -> impl Filter<Extract = (Srv,), Error = std::convert::Infallible> + Clone { ) -> impl Filter<Extract = (Client,), Error = std::convert::Infallible> + Clone {
warp::any().map(move || srv.clone()) warp::any().map(move || client.clone())
} }
} }
mod handlers { mod handlers {
use super::models::{ListOptions, Srv}; use super::models::{Client, ListOptions};
use crate::api::{BadQuery, API}; use crate::api::{BadQuery, API};
pub async fn list(opts: ListOptions, srv: Srv) -> Result<impl warp::Reply, warp::Rejection> { pub async fn list(opts: ListOptions, srv: Client) -> Result<impl warp::Reply, warp::Rejection> {
// match srv.get_threshold_detections(opts.from, opts.to, 10, 100_000.).await { // match srv.get_threshold_detections(opts.from, opts.to, 10, 100_000.).await {
match srv.read().get_pattern_detection(opts.from, opts.to).await { match srv.get_pattern_detection(opts.from, opts.to).await {
Ok(segments) => Ok(API::json(&segments)), Ok(segments) => Ok(API::json(&segments)),
Err(e) => { Err(e) => {
println!("{:?}", e); println!("{:?}", e);
@ -53,13 +53,10 @@ mod models {
use std::sync::Arc; use std::sync::Arc;
use hastic::services::analytic_service; use hastic::services::analytic_service;
use parking_lot::RwLock;
use serde::{Deserialize, Serialize};
// use parking_lot::RwLock; use serde::{Deserialize, Serialize};
// use std::sync::Arc;
pub type Srv = Arc<RwLock<analytic_service::AnalyticService>>; pub type Client = analytic_service::analytic_client::AnalyticClient;
// The query parameters for list_todos. // The query parameters for list_todos.
#[derive(Debug, Deserialize)] #[derive(Debug, Deserialize)]

7
server/src/api.rs → server/src/api/mod.rs

@ -32,7 +32,8 @@ pub struct API<'a> {
user_service: Arc<RwLock<user_service::UserService>>, user_service: Arc<RwLock<user_service::UserService>>,
metric_service: metric_service::MetricService, metric_service: metric_service::MetricService,
data_service: segments_service::SegmentsService, data_service: segments_service::SegmentsService,
analytic_service: Arc<RwLock<AnalyticService>>, // TODO: get analytic service as reference
analytic_service: AnalyticService,
} }
impl API<'_> { impl API<'_> {
@ -45,7 +46,7 @@ impl API<'_> {
user_service: Arc::new(RwLock::new(user_service::UserService::new())), user_service: Arc::new(RwLock::new(user_service::UserService::new())),
metric_service: ms.clone(), metric_service: ms.clone(),
data_service: ss.clone(), data_service: ss.clone(),
analytic_service: Arc::new(RwLock::new(AnalyticService::new(ms, ss))) analytic_service: AnalyticService::new(ms, ss),
}) })
} }
@ -81,7 +82,7 @@ impl API<'_> {
let metrics = metric::get_route(self.metric_service.clone()); let metrics = metric::get_route(self.metric_service.clone());
let login = auth::get_route(self.user_service.clone()); let login = auth::get_route(self.user_service.clone());
let segments = segments::filters::filters(self.data_service.clone()); let segments = segments::filters::filters(self.data_service.clone());
let analytics = analytics::filters::filters(self.analytic_service.clone()); let analytics = analytics::filters::filters(self.analytic_service.get_client());
let public = warp::fs::dir("public"); let public = warp::fs::dir("public");
println!("Start server on {} port", self.config.port); println!("Start server on {} port", self.config.port);

27
server/src/services/analytic_service/analytic_client.rs

@ -0,0 +1,27 @@
use tokio::sync::mpsc;
use crate::services::segments_service::Segment;
use super::types::{AnalyticRequest};
/// CLient to be used multithreaded
///
///
#[derive(Clone)]
pub struct AnalyticClient {
tx: mpsc::Sender<AnalyticRequest>,
}
impl AnalyticClient {
pub fn new(tx: mpsc::Sender<AnalyticRequest>) -> AnalyticClient {
AnalyticClient { tx }
}
pub async fn run_learning(&self) -> anyhow::Result<()> {
self.tx.send(AnalyticRequest::RunLearning).await?;
Ok(())
}
pub async fn get_pattern_detection(&self, from: u64, to: u64) -> anyhow::Result<Vec<Segment>> {
return Ok(Vec::new());
}
}

50
server/src/services/analytic_service.rs → server/src/services/analytic_service/analytic_service.rs

@ -1,21 +1,26 @@
use crate::utils::{self, get_random_str};
use self::pattern_detector::{LearningResults, PatternDetector};
use super::{ use super::{
analytic_client::AnalyticClient,
pattern_detector::{self, LearningResults, PatternDetector},
types::AnalyticRequest,
};
use crate::services::{
metric_service::MetricService, metric_service::MetricService,
segments_service::{self, Segment, SegmentType, SegmentsService, ID_LENGTH}, segments_service::{self, Segment, SegmentType, SegmentsService, ID_LENGTH},
}; };
use crate::utils::{self, get_random_str};
use subbeat::metric::Metric; use subbeat::metric::Metric;
use anyhow; use anyhow;
mod pattern_detector; use tokio::sync::{mpsc, oneshot};
use tokio::time::{sleep, Duration};
use futures::future; use futures::future;
use tokio::sync::oneshot;
use tokio::time::{sleep, Duration}; use super::types;
const DETECTION_STEP: u64 = 10; const DETECTION_STEP: u64 = 10;
const LEARNING_WAITING_INTERVAL: u64 = 100; const LEARNING_WAITING_INTERVAL: u64 = 100;
@ -23,17 +28,19 @@ const LEARNING_WAITING_INTERVAL: u64 = 100;
#[derive(Clone, PartialEq)] #[derive(Clone, PartialEq)]
enum LearningStatus { enum LearningStatus {
Initialization, Initialization,
Starting,
Learning, Learning,
Error, Error,
Ready, Ready,
} }
#[derive(Clone)]
pub struct AnalyticService { pub struct AnalyticService {
metric_service: MetricService, metric_service: MetricService,
segments_service: SegmentsService, segments_service: SegmentsService,
learning_results: Option<LearningResults>, learning_results: Option<LearningResults>,
learning_status: LearningStatus, learning_status: LearningStatus,
tx: mpsc::Sender<AnalyticRequest>,
rx: mpsc::Receiver<AnalyticRequest>,
} }
impl AnalyticService { impl AnalyticService {
@ -41,17 +48,38 @@ impl AnalyticService {
metric_service: MetricService, metric_service: MetricService,
segments_service: segments_service::SegmentsService, segments_service: segments_service::SegmentsService,
) -> AnalyticService { ) -> AnalyticService {
let (tx, rx) = mpsc::channel::<AnalyticRequest>(32);
AnalyticService { AnalyticService {
metric_service, metric_service,
segments_service, segments_service,
// TODO: get it from persistance // TODO: get it from persistance
learning_results: None, learning_results: None,
learning_status: LearningStatus::Initialization, learning_status: LearningStatus::Initialization,
tx,
rx,
}
}
pub fn get_client(&self) -> AnalyticClient {
AnalyticClient::new(self.tx.clone())
}
pub async fn serve(&mut self) {
while let Some(request) = self.rx.recv().await {
match request {
types::AnalyticRequest::RunLearning => {
// TODO: not block and do logic when it's finished
self.run_learning().await;
}
}
} }
} }
// call this from api // call this from api
pub async fn run_learning(&mut self) { async fn run_learning(&mut self) {
self.learning_status = LearningStatus::Starting;
println!("Learning starting");
let prom = self.metric_service.get_prom(); let prom = self.metric_service.get_prom();
let ss = self.segments_service.clone(); let ss = self.segments_service.clone();
@ -101,7 +129,7 @@ impl AnalyticService {
} }
} }
pub async fn get_pattern_detection(&self, from: u64, to: u64) -> anyhow::Result<Vec<Segment>> { async fn get_pattern_detection(&self, from: u64, to: u64) -> anyhow::Result<Vec<Segment>> {
let prom = self.metric_service.get_prom(); let prom = self.metric_service.get_prom();
while self.learning_status == LearningStatus::Learning { while self.learning_status == LearningStatus::Learning {
@ -136,7 +164,7 @@ impl AnalyticService {
Ok(result_segments) Ok(result_segments)
} }
pub async fn get_threshold_detections( async fn get_threshold_detections(
&self, &self,
from: u64, from: u64,
to: u64, to: u64,

7
server/src/services/analytic_service/mod.rs

@ -0,0 +1,7 @@
mod analytic_service;
mod pattern_detector;
mod types;
pub mod analytic_client;
pub use analytic_service::AnalyticService;

8
server/src/services/analytic_service/types.rs

@ -0,0 +1,8 @@
use tokio::sync::oneshot;
#[derive(Debug, PartialEq)]
pub enum AnalyticRequest {
// Status,
RunLearning,
// Detect { from: u64, to: u64 },
}

0
server/src/services.rs → server/src/services/mod.rs

Loading…
Cancel
Save