subing works, although be it very prototype like
This commit is contained in:
@@ -10,7 +10,7 @@ use super::Instance;
|
|||||||
use crate::item::{get_raw_from_cbor, Item, ItemData};
|
use crate::item::{get_raw_from_cbor, Item, ItemData};
|
||||||
|
|
||||||
// only created with Instance::new_connection()
|
// only created with Instance::new_connection()
|
||||||
#[derive(Clone)]
|
#[derive(Clone, Debug)]
|
||||||
pub struct Connection {
|
pub struct Connection {
|
||||||
pub tx: Sender<MizeMessage>,
|
pub tx: Sender<MizeMessage>,
|
||||||
pub id: u64,
|
pub id: u64,
|
||||||
@@ -22,7 +22,7 @@ pub trait ConnListener : Send + Sync {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl Connection {
|
impl Connection {
|
||||||
pub fn send(&mut self, msg: MizeMessage) -> MizeResult<()> {
|
pub fn send(&self, msg: MizeMessage) -> MizeResult<()> {
|
||||||
Ok(self.tx.send(msg)?)
|
Ok(self.tx.send(msg)?)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -26,6 +26,7 @@ use crate::proto::MizeMessage;
|
|||||||
use tokio::runtime::Handle;
|
use tokio::runtime::Handle;
|
||||||
|
|
||||||
use self::connection::{ConnListener, Connection};
|
use self::connection::{ConnListener, Connection};
|
||||||
|
use self::updater::handle_operation;
|
||||||
|
|
||||||
#[cfg(feature = "async")]
|
#[cfg(feature = "async")]
|
||||||
use tokio::runtime::Runtime;
|
use tokio::runtime::Runtime;
|
||||||
@@ -46,7 +47,7 @@ pub struct Instance {
|
|||||||
pub store: Arc<Mutex<Box<dyn Store>>>,
|
pub store: Arc<Mutex<Box<dyn Store>>>,
|
||||||
connections: Arc<Mutex<Vec<Connection>>>,
|
connections: Arc<Mutex<Vec<Connection>>>,
|
||||||
next_con_id: Arc<Mutex<u64>>,
|
next_con_id: Arc<Mutex<u64>>,
|
||||||
subs: Arc<Mutex<HashMap<MizeId, Subscription>>>,
|
subs: Arc<Mutex<HashMap<MizeId, Vec<Subscription>>>>,
|
||||||
pub id_pool: Arc<Mutex<VecStringPool>>,
|
pub id_pool: Arc<Mutex<VecStringPool>>,
|
||||||
pub namespace_pool: Arc<Mutex<StringPool>>,
|
pub namespace_pool: Arc<Mutex<StringPool>>,
|
||||||
|
|
||||||
@@ -148,8 +149,11 @@ impl Instance {
|
|||||||
pub fn with_config(config: ItemData) -> MizeResult<Instance> {
|
pub fn with_config(config: ItemData) -> MizeResult<Instance> {
|
||||||
trace!("[ {} ] Instance::with_config()", "CALL".yellow());
|
trace!("[ {} ] Instance::with_config()", "CALL".yellow());
|
||||||
trace!("config: {}", config);
|
trace!("config: {}", config);
|
||||||
|
|
||||||
let mut instance = Instance::empty()?;
|
let mut instance = Instance::empty()?;
|
||||||
instance.set("0", config.clone());
|
|
||||||
|
instance.set_blocking("0", config.clone());
|
||||||
|
|
||||||
instance.init()?;
|
instance.init()?;
|
||||||
|
|
||||||
Ok(instance)
|
Ok(instance)
|
||||||
@@ -212,6 +216,25 @@ impl Instance {
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn set_blocking<I: IntoMizeId, V: Into<ItemData>>(&self, id: I, value: V) -> MizeResult<()> {
|
||||||
|
handle_operation(&mut Operation::Set(id.to_mize_id(self)?, value.into()), self)?;
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn sub<I: IntoMizeId>(&self, id: I, sub: Subscription) -> MizeResult<()> {
|
||||||
|
let mut subs_inner = self.subs.lock()?;
|
||||||
|
let id = id.to_mize_id(self)?;
|
||||||
|
match subs_inner.get_mut(&id) {
|
||||||
|
Some(vec) => {
|
||||||
|
vec.push(sub);
|
||||||
|
},
|
||||||
|
None => {
|
||||||
|
subs_inner.insert(id, vec![sub]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
pub fn new_id<T: IntoMizeId>(&self, value: T) -> MizeResult<MizeId> {
|
pub fn new_id<T: IntoMizeId>(&self, value: T) -> MizeResult<MizeId> {
|
||||||
value.to_mize_id(self)
|
value.to_mize_id(self)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,4 +1,66 @@
|
|||||||
|
use core::fmt;
|
||||||
|
use std::rc::Rc;
|
||||||
|
use crossbeam::channel::Sender;
|
||||||
|
use std::sync::Arc;
|
||||||
|
use tracing::trace;
|
||||||
|
|
||||||
|
use crate::id::MizeId;
|
||||||
|
use crate::instance::connection::Connection;
|
||||||
|
use crate::item::Item;
|
||||||
|
use crate::error::MizeResult;
|
||||||
|
use crate::proto::MizeMessage;
|
||||||
|
|
||||||
#[derive(Debug)]
|
use super::Instance;
|
||||||
pub struct Subscription;
|
|
||||||
|
#[derive(Clone, Debug)]
|
||||||
|
pub struct Update {
|
||||||
|
pub instance: Arc<Instance>,
|
||||||
|
pub id: MizeId,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Update {
|
||||||
|
pub fn new_item(&self) -> MizeResult<Item> {
|
||||||
|
self.instance.get(self.id.clone())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub enum Subscription {
|
||||||
|
Connection(Connection),
|
||||||
|
Closure(Box<dyn Fn(Update) -> MizeResult<()> + Send>),
|
||||||
|
Channel(Sender<Update>),
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Subscription {
|
||||||
|
pub fn from_conn(conn: Connection) -> Subscription {
|
||||||
|
Subscription::Connection(conn)
|
||||||
|
}
|
||||||
|
pub fn from_closure(closure: Box<dyn Fn(Update) -> MizeResult<()> + Send>) -> Subscription {
|
||||||
|
Subscription::Closure(closure)
|
||||||
|
}
|
||||||
|
pub fn from_sender(tx: Sender<Update>) -> Subscription {
|
||||||
|
Subscription::Channel(tx)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn handle(&mut self, update: Update) -> MizeResult<()> {
|
||||||
|
trace!("handleing update");
|
||||||
|
match &self {
|
||||||
|
Subscription::Connection(conn) => {
|
||||||
|
let msg = MizeMessage::new_update(update.id.clone(), update.new_item()?.as_data_full()?, conn.id);
|
||||||
|
conn.send(msg)?;
|
||||||
|
}
|
||||||
|
Subscription::Closure(closure) => {
|
||||||
|
closure(update)?
|
||||||
|
}
|
||||||
|
Subscription::Channel(tx) => {
|
||||||
|
tx.send(update);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl fmt::Debug for Subscription {
|
||||||
|
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||||
|
write!(f, "...Subscription...")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -1,5 +1,7 @@
|
|||||||
use crossbeam::channel::Receiver;
|
use crossbeam::channel::Receiver;
|
||||||
use tracing::{error, trace, warn};
|
use tracing::{error, trace, warn};
|
||||||
|
use std::borrow::BorrowMut;
|
||||||
|
use std::sync::Arc;
|
||||||
|
|
||||||
use crate::mize_err;
|
use crate::mize_err;
|
||||||
use crate::{instance::Instance, item::ItemData};
|
use crate::{instance::Instance, item::ItemData};
|
||||||
@@ -8,6 +10,7 @@ use crate:: error::{MizeResult, MizeError, MizeResultTrait};
|
|||||||
use crate::proto::{MessageCmd, MizeMessage};
|
use crate::proto::{MessageCmd, MizeMessage};
|
||||||
|
|
||||||
use super::connection::{self, Connection};
|
use super::connection::{self, Connection};
|
||||||
|
use super::subscription::{Subscription, Update};
|
||||||
|
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
@@ -21,13 +24,18 @@ pub fn updater_thread(operation_rx : Receiver<Operation>, instance: &Instance) -
|
|||||||
|
|
||||||
loop {
|
loop {
|
||||||
let mut operation = operation_rx.recv()?;
|
let mut operation = operation_rx.recv()?;
|
||||||
trace!("OPERATION {}", count);
|
let op_str = match operation {
|
||||||
|
Operation::Set(_, _) => "SET",
|
||||||
|
Operation::Msg(_) => "MSG",
|
||||||
|
};
|
||||||
|
|
||||||
|
trace!("OPERATION {} - {}", count, op_str);
|
||||||
|
|
||||||
//let mut busy = instance.update_thread_busy.lock()?;
|
//let mut busy = instance.update_thread_busy.lock()?;
|
||||||
|
|
||||||
let result = handle_operation(&mut operation, instance);
|
let result = handle_operation(&mut operation, instance);
|
||||||
|
|
||||||
trace!("OPERATION DONE {}", count);
|
trace!("OPERATION {} DONE", count);
|
||||||
count += 1;
|
count += 1;
|
||||||
|
|
||||||
if let Err(err) = result {
|
if let Err(err) = result {
|
||||||
@@ -40,12 +48,26 @@ pub fn updater_thread(operation_rx : Receiver<Operation>, instance: &Instance) -
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn handle_operation(operation: &mut Operation, instance: &Instance) -> MizeResult<()> {
|
pub fn handle_operation(operation: &mut Operation, instance: &Instance) -> MizeResult<()> {
|
||||||
match operation {
|
match operation {
|
||||||
Operation::Set(id, value) => {
|
Operation::Set(id, value) => {
|
||||||
let item_data: ItemData = value.to_owned();
|
let item_data: ItemData = value.to_owned();
|
||||||
let mut item = instance.get(id.clone())?;
|
let mut item = instance.get(id.clone())?;
|
||||||
item.merge(item_data)?;
|
item.merge(item_data)?;
|
||||||
|
|
||||||
|
//check subs and handle them
|
||||||
|
let mut subs_inner = instance.subs.lock()?;
|
||||||
|
println!("goooooooooooooooooot some subs: {:?}", subs_inner);
|
||||||
|
println!("some subs id: {:?}", id);
|
||||||
|
if let Some(vec) = subs_inner.get_mut(&id) {
|
||||||
|
let update = Update {
|
||||||
|
instance: Arc::new(instance.to_owned()),
|
||||||
|
id: id.clone(),
|
||||||
|
};
|
||||||
|
for sub in vec.iter_mut() {
|
||||||
|
sub.handle(update.clone());
|
||||||
|
}
|
||||||
|
}
|
||||||
},
|
},
|
||||||
Operation::Msg(msg) => {
|
Operation::Msg(msg) => {
|
||||||
handle_msg(msg, instance)?
|
handle_msg(msg, instance)?
|
||||||
@@ -64,10 +86,20 @@ fn handle_msg(msg: &mut MizeMessage, instance: &Instance) -> MizeResult<()> {
|
|||||||
connection.send(msg)?;
|
connection.send(msg)?;
|
||||||
},
|
},
|
||||||
|
|
||||||
|
MessageCmd::GetSub => {
|
||||||
|
let id = msg.id(instance)?;
|
||||||
|
let mut connection = instance.get_connection(msg.conn_id)?.clone();
|
||||||
|
let item = instance.get(id.clone())?;
|
||||||
|
let msg = MizeMessage::new_give(id.clone(), item.as_data_full()?, msg.conn_id);
|
||||||
|
connection.send(msg)?;
|
||||||
|
let sub = Subscription::from_conn(connection.clone());
|
||||||
|
instance.sub(id, sub)?;
|
||||||
|
},
|
||||||
|
|
||||||
MessageCmd::Update => {
|
MessageCmd::Update => {
|
||||||
let data = msg.data()?;
|
let data = msg.data()?;
|
||||||
let id = msg.id(instance)?;
|
let id = msg.id(instance)?;
|
||||||
instance.set(id, data);
|
instance.set(id.clone(), data);
|
||||||
},
|
},
|
||||||
|
|
||||||
// this should check, if the update is valid
|
// this should check, if the update is valid
|
||||||
@@ -75,7 +107,7 @@ fn handle_msg(msg: &mut MizeMessage, instance: &Instance) -> MizeResult<()> {
|
|||||||
MessageCmd::UpdateRequest => {
|
MessageCmd::UpdateRequest => {
|
||||||
let data = msg.data()?;
|
let data = msg.data()?;
|
||||||
let id = msg.id(instance)?;
|
let id = msg.id(instance)?;
|
||||||
instance.set(id, data);
|
instance.set(id.clone(), data);
|
||||||
},
|
},
|
||||||
|
|
||||||
MessageCmd::Give => {
|
MessageCmd::Give => {
|
||||||
|
|||||||
@@ -107,14 +107,14 @@ impl Item<'_> {
|
|||||||
|
|
||||||
pub fn merge<V: Into<ItemData>>(&mut self, mut value: V) -> MizeResult<()> {
|
pub fn merge<V: Into<ItemData>>(&mut self, mut value: V) -> MizeResult<()> {
|
||||||
|
|
||||||
println!("before as_data_full: {}", self.instance.op_tx.len());
|
|
||||||
let mut data = self.as_data_full()?;
|
let mut data = self.as_data_full()?;
|
||||||
println!("data: {:?}", data);
|
println!("item::merge data: {:?}", data);
|
||||||
|
println!("item::merge id: {:?}", self.id());
|
||||||
|
|
||||||
let new_data = value.into();
|
let new_data = value.into();
|
||||||
|
|
||||||
data.merge(new_data);
|
data.merge(new_data);
|
||||||
println!("new_data: {:?}", data);
|
println!("item::merge new_data: {:?}", data);
|
||||||
|
|
||||||
if self.instance.we_are_namespace()? {
|
if self.instance.we_are_namespace()? {
|
||||||
let store_inner = self.instance.store.lock()?;
|
let store_inner = self.instance.store.lock()?;
|
||||||
|
|||||||
@@ -25,6 +25,7 @@ static CMD_GIVE: u16 = 3;
|
|||||||
static CMD_CREATE: u16 = 4;
|
static CMD_CREATE: u16 = 4;
|
||||||
static CMD_CREATE_REPLY: u16 = 5;
|
static CMD_CREATE_REPLY: u16 = 5;
|
||||||
static CMD_UPDATE_REQUEST: u16 = 6;
|
static CMD_UPDATE_REQUEST: u16 = 6;
|
||||||
|
static CMD_GET_SUB: u16 = 7;
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub enum MessageCmd {
|
pub enum MessageCmd {
|
||||||
@@ -34,6 +35,7 @@ pub enum MessageCmd {
|
|||||||
Create,
|
Create,
|
||||||
CreateReply,
|
CreateReply,
|
||||||
UpdateRequest,
|
UpdateRequest,
|
||||||
|
GetSub,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -54,6 +56,16 @@ impl MizeMessage {
|
|||||||
MizeMessage::new(value, conn_id)
|
MizeMessage::new(value, conn_id)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn new_get_sub(id: MizeId, conn_id: u64) -> MizeMessage {
|
||||||
|
let id_path = id.path().into_iter().map(|string| CborValue::Text(string.to_owned())).collect();
|
||||||
|
|
||||||
|
let cmd = (CborValue::Integer(MSG_CMD.into()), CborValue::Integer(CMD_GET_SUB.into()));
|
||||||
|
let id = (CborValue::Integer(MSG_ID.into()), CborValue::Array(id_path));
|
||||||
|
let value = CborValue::Map(vec![cmd, id]);
|
||||||
|
|
||||||
|
MizeMessage::new(value, conn_id)
|
||||||
|
}
|
||||||
|
|
||||||
pub fn new_create(conn_id: u64) -> MizeMessage {
|
pub fn new_create(conn_id: u64) -> MizeMessage {
|
||||||
let cmd = (CborValue::Integer(MSG_CMD.into()), CborValue::Integer(CMD_CREATE.into()));
|
let cmd = (CborValue::Integer(MSG_CMD.into()), CborValue::Integer(CMD_CREATE.into()));
|
||||||
let value = CborValue::Map(vec![cmd]);
|
let value = CborValue::Map(vec![cmd]);
|
||||||
|
|||||||
@@ -1,12 +1,29 @@
|
|||||||
use clap::ArgMatches;
|
use clap::ArgMatches;
|
||||||
use mize::error::MizeResult;
|
use crossbeam::channel::{bounded, unbounded};
|
||||||
|
use mize::error::{MizeResult, MizeError};
|
||||||
|
use mize::instance::subscription::{Subscription, Update};
|
||||||
use mize::instance::Instance;
|
use mize::instance::Instance;
|
||||||
|
use mize::platform::os::config_from_cli_args;
|
||||||
|
|
||||||
pub fn show(sub_matches: &ArgMatches) -> MizeResult<()> {
|
pub fn show(sub_matches: &ArgMatches) -> MizeResult<()> {
|
||||||
|
|
||||||
let instance = Instance::new()?;
|
let instance = Instance::with_config(config_from_cli_args(sub_matches)?)?;
|
||||||
|
|
||||||
println!("0/config/test is: {}", instance.get("0/config/test")?);
|
let id = sub_matches.get_one::<String>("id")
|
||||||
|
.ok_or(MizeError::new().msg("No id Argument specified"))?;
|
||||||
|
|
||||||
|
let item = instance.get(id)?;
|
||||||
|
|
||||||
|
let (tx, rx) = bounded::<Update>(4);
|
||||||
|
let sub = Subscription::from_sender(tx);
|
||||||
|
instance.sub(id, sub)?;
|
||||||
|
|
||||||
|
println!("ItemData: {}", item.as_data_full()?);
|
||||||
|
|
||||||
|
for update in rx {
|
||||||
|
println!("####### GOT UPDATE #######");
|
||||||
|
println!("ItemData: {}", update.new_item()?.as_data_full()?);
|
||||||
|
}
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -30,7 +30,7 @@ pub fn os_instance_init(instance: &mut Instance) -> MizeResult<()> {
|
|||||||
Ok(config_file_path) => {
|
Ok(config_file_path) => {
|
||||||
let config = config_from_file(config_file_path)?;
|
let config = config_from_file(config_file_path)?;
|
||||||
debug!("env var MIZE_CONFIG_FILE present");
|
debug!("env var MIZE_CONFIG_FILE present");
|
||||||
instance.set("0", config)?;
|
instance.set_blocking("0", config)?;
|
||||||
trace!("config after MIZE_CONFIG_FILE env var: {}", instance.get("0/config")?);
|
trace!("config after MIZE_CONFIG_FILE env var: {}", instance.get("0/config")?);
|
||||||
}
|
}
|
||||||
Err(var_err) => match var_err {
|
Err(var_err) => match var_err {
|
||||||
@@ -48,7 +48,7 @@ pub fn os_instance_init(instance: &mut Instance) -> MizeResult<()> {
|
|||||||
Ok(config_string) => {
|
Ok(config_string) => {
|
||||||
let config = config_from_string(config_string)?;
|
let config = config_from_string(config_string)?;
|
||||||
debug!("env var MIZE_CONFIG present");
|
debug!("env var MIZE_CONFIG present");
|
||||||
instance.set("0", config)?;
|
instance.set_blocking("0", config)?;
|
||||||
trace!("config after MIZE_CONFIG env var: {}", instance.get("0/config")?);
|
trace!("config after MIZE_CONFIG env var: {}", instance.get("0/config")?);
|
||||||
}
|
}
|
||||||
Err(var_err) => match var_err {
|
Err(var_err) => match var_err {
|
||||||
@@ -62,6 +62,8 @@ pub fn os_instance_init(instance: &mut Instance) -> MizeResult<()> {
|
|||||||
};
|
};
|
||||||
|
|
||||||
////// if a config.store_path is set, upgrade to the filestore there
|
////// if a config.store_path is set, upgrade to the filestore there
|
||||||
|
let mut test = instance.get("0")?.as_data_full()?;
|
||||||
|
println!("os::Mod test: {}", test);
|
||||||
let mut store_path = instance.get("0/config/store_path")?.value_string()?;
|
let mut store_path = instance.get("0/config/store_path")?.value_string()?;
|
||||||
|
|
||||||
if store_path == "" {
|
if store_path == "" {
|
||||||
|
|||||||
Reference in New Issue
Block a user