extern crate vec_map;
use self::vec_map::VecMap;
extern crate rustc_serialize;
use self::rustc_serialize::json::Json;
use std::collections::{BTreeMap, HashSet};
use std::sync::atomic::{AtomicBool, Ordering};
use std::sync::mpsc::{Receiver, Sender};
use std::sync::Arc;
use indexing::Key;
use misc::*;
use service::{PrivateAccess, Service};
pub trait PlainRawStorage: Send {
fn store(&mut self, value: u32);
fn to_json(&self, format: &SerializationFormat) -> Json;
}
pub trait KeyedRawStorage: Send {
fn store(&mut self, key: String, value: u32);
fn to_json(&self, format: &SerializationFormat) -> Json;
}
pub enum Op {
RegisterPlain(usize, NamedStorage<dyn PlainRawStorage>),
RegisterKeyed(usize, NamedStorage<dyn KeyedRawStorage>),
RecordPlain(usize, u32),
RecordKeyed(usize, String, u32),
Serialize(Subset, SerializationFormat, Sender<Json>),
Terminate,
}
impl TelemetryTask {
pub fn new(receiver: Receiver<Op>) -> TelemetryTask {
TelemetryTask {
plain: VecMap::new(),
keyed: VecMap::new(),
receiver,
keys: HashSet::new(),
}
}
pub fn run(&mut self) {
for msg in &self.receiver {
match msg {
Op::RegisterPlain(index, storage) => {
assert!(self.keys.insert(storage.name.clone()));
self.plain.insert(index, storage);
}
Op::RegisterKeyed(index, storage) => {
assert!(self.keys.insert(storage.name.clone()));
self.keyed.insert(index, storage);
}
Op::RecordPlain(index, value) => {
let storage = self.plain.get_mut(index).unwrap();
storage.contents.store(value);
}
Op::RecordKeyed(index, key, value) => {
let storage = self.keyed.get_mut(index).unwrap();
storage.contents.store(key, value);
}
Op::Serialize(what, format, sender) => {
let mut object = BTreeMap::new();
match what {
Subset::AllPlain => {
for ref histogram in self.plain.values() {
object.insert(
histogram.name.clone(),
histogram.contents.to_json(&format),
);
}
}
Subset::AllKeyed => {
for ref histogram in self.keyed.values() {
object.insert(
histogram.name.clone(),
histogram.contents.to_json(&format),
);
}
}
}
sender.send(Json::Object(object)).unwrap();
}
Op::Terminate => {
return;
}
}
}
}
}
pub struct TelemetryTask {
plain: VecMap<NamedStorage<dyn PlainRawStorage>>,
keyed: VecMap<NamedStorage<dyn KeyedRawStorage>>,
receiver: Receiver<Op>,
keys: HashSet<String>,
}
impl<K> BackEnd<K>
where
K: Clone,
{
pub fn new(service: &Service, key: Key<K>) -> BackEnd<K> {
BackEnd {
key,
is_active: PrivateAccess::get_is_active(service).clone(),
sender: PrivateAccess::get_sender(service).clone(),
}
}
pub fn get_key(&self) -> Option<&Key<K>> {
if self.is_active.load(Ordering::Relaxed) {
Some(&self.key)
} else {
None
}
}
}
#[derive(Clone)]
pub struct BackEnd<K>
where
K: Clone,
{
key: Key<K>,
pub sender: Sender<Op>,
is_active: Arc<AtomicBool>,
}