Commit 27f4043e authored by Kaiden Fey's avatar Kaiden Fey

netmod-tcp: adding a lot of debug logging - not yet working

parent 7a258ce7
......@@ -6,3 +6,5 @@
- [qaul-hubd](./qaul-hubd/_intro.md)
- [Manual build](./qaul-hubd/build.md)
- [Configuration](./qaul-hubd/config.md)
- [qaul-emberweb](./webgui/_intro.md)
- [Manual build](./webgui/build.md)
# Web GUI
# qaul-emberweb
The **web GUI** is the **HTML5 GUI** for qaul.net. It is
built using [EmberJS](https://emberjs.com/).
This is a web client written in ember.js. It's meant to be installed
on a communal computer and can provide multiple users access to an
underlying qaul.net instance.
* [Install EmberJS & Test Web GUI](install.md)
Requires a running `qaul-hubd` instance to connect to.
# Install EmberJS & Test Web GUI
In order to develop, build and test the qaul.net web GUI
you need to install EmberJS. This is a step by step guide
to get you up and running.
## Prerequisites
You will need the following things properly installed on your computer.
* [Git](https://git-scm.com/)
* [Node.js](https://nodejs.org/)
* [Yarn](https://yarnpkg.com/)
* [Ember CLI](https://ember-cli.com/)
* [Google Chrome](https://google.com/chrome/)
## Installation
The qaul.net web GUI code is in the `webgui` foder of the qaul.net source code repository.
* `git clone https://git.open-communication.net/qaul/qaul.net.git`
* `cd qaul.net/webgui`
* `yarn`
## Running / Development
* `ember serve`
* Visit your app at [http://localhost:4200](http://localhost:4200).
* Visit your tests at [http://localhost:4200/tests](http://localhost:4200/tests).
### Code Generators
Make use of the many generators for code, try `ember help generate` for more details
### Running Tests
* `ember test`
* `ember test --server`
### Linting
* `npm run lint:hbs`
* `npm run lint:js`
* `npm run lint:js -- --fix`
### Building
* `ember build` (development)
* `ember build --environment production` (production)
### Deploying
* `ember deploy production`
## Further Reading / Useful Links
* [ember.js](https://emberjs.com/)
* [ember-cli](https://ember-cli.com/)
* Development Browser Extensions
* [ember inspector for chrome](https://chrome.google.com/webstore/detail/ember-inspector/bmdblncegkenkacieihfhpjfppoconhi)
* [ember inspector for firefox](https://addons.mozilla.org/en-US/firefox/addon/ember-inspector/)
# Manual build
......@@ -93,6 +93,8 @@ pub(crate) struct Peer {
_run: Arc<AtomicBool>,
/// Store packets until they can be delivered
io: Arc<IoPair<Packet>>,
/// Lock this peer from re-introducing multiple times
introducing: Arc<AtomicBool>,
}
impl Peer {
......@@ -108,6 +110,7 @@ impl Peer {
Arc::new(Self {
id: id::next(),
src: AtomPtr::new(Some(src)),
_run: Arc::new(true.into()),
..Default::default()
})
}
......@@ -121,6 +124,7 @@ impl Peer {
let p = Arc::new(Self {
id: id::next(),
dst: Some(dst),
_run: Arc::new(true.into()),
..Default::default()
});
......@@ -171,6 +175,8 @@ impl Peer {
let mut s;
while self.alive() {
s = self.sender.write().await;
trace!("{:?}", s);
if s.is_none() {
// We need to drop `s` here because the
// introduction loop will want to have
......@@ -178,8 +184,11 @@ impl Peer {
// Otherwise we will create a deadlock!
drop(s);
// Run introduction again
Arc::clone(&self).introduce_blocking(port).await;
// Run introduction again if it's not already happening
if !self.get_intro() {
trace!("Sending stream doesn't exist! Re-introducing...");
Arc::clone(&self).introduce_blocking(port).await;
}
} else {
// At this point we should have a valid stream
let addr = s.as_ref().unwrap().peer_addr().unwrap().to_string();
......@@ -203,6 +212,7 @@ impl Peer {
}
// If we reach this point we're good to go
trace!("Successfully sent...");
break;
}
}
......@@ -224,7 +234,11 @@ impl Peer {
/// stream to a destination stream.
pub(crate) fn introduce(self: Arc<Self>, port: u16) {
let _self = Arc::clone(&self);
task::spawn(async move { _self.introduce_blocking(port).await });
task::spawn(async move {
if !_self.get_intro() {
_self.introduce_blocking(port).await
}
});
}
/// The same as `introduce()` but without spawning a new task
......@@ -235,9 +249,9 @@ impl Peer {
let run = Arc::clone(&self._run);
let sender = Arc::clone(&self.sender);
let mut ctr = 0;
self.intro(true);
while run.load(Ordering::Relaxed) {
ctr += 1; // increment the attempt counter
let pre = match ctr {
0 => "".into(),
n => format!("[retry #{}]", n),
......@@ -268,6 +282,7 @@ impl Peer {
// FIXME: Make this configurable
task::sleep(Duration::from_secs(20)).await;
ctr += 1;
continue;
}
};
......@@ -277,6 +292,7 @@ impl Peer {
// Queue a HELLO sending and exit this loop
self.send(Packet::Hello { port }).await;
self.intro(false);
break;
}
}
......@@ -299,4 +315,12 @@ impl Peer {
pub(crate) fn get_dst(&self) -> Option<DstAddr> {
self.dst.clone()
}
fn intro(&self, f: bool) {
self.introducing.swap(f, Ordering::Relaxed);
}
fn get_intro(&self) -> bool {
self.introducing.load(Ordering::Relaxed)
}
}
......@@ -8,6 +8,7 @@ use bincode::deserialize;
use byteorder::{BigEndian, ByteOrder};
use netmod::Frame;
use serde::{Deserialize, Serialize};
use tracing::trace;
/// An internally used packet format
#[derive(Debug, Serialize, Deserialize)]
......@@ -33,23 +34,29 @@ pub(crate) struct PacketBuilder<'s> {
impl<'s> PacketBuilder<'s> {
/// Create a new frame builder from a stream
pub(crate) fn new(stream: &'s mut TcpStream) -> Self {
tracing::warn!("Creating a parser...");
Self { stream, data: None }
}
/// Parse incoming data and initialise the builder
pub(crate) async fn parse(&mut self) -> io::Result<()> {
trace!("Starting to parse a packet!");
let mut len_buf = [0; 8];
self.stream.read_exact(&mut len_buf).await?;
let len = BigEndian::read_u64(&len_buf);
trace!("Got length of {}", len);
let mut data_buf = vec![0; len as usize];
self.stream.read_exact(&mut data_buf).await?;
self.data = Some(data_buf);
trace!("Read data to buffer!");
Ok(())
}
/// Consume the builder and maybe return a frame
pub(crate) fn build(self) -> Option<Packet> {
trace!("Building packet from stream...");
self.data.and_then(|vec| deserialize(&vec).ok())
}
}
......@@ -4,19 +4,29 @@
//! in this file, so we should pull it out into it's own crate at some
//! point. But for now...
use std::cmp::PartialEq;
use std::{ops::Deref, cmp::PartialEq};
use std::sync::{
atomic::{AtomicPtr, Ordering},
Arc,
};
/// An alias for a referenced pointer
pub(crate) type Ref<T> = Box<T>;
pub(crate) struct Ref<T> {
inner: Box<Arc<T>>,
}
impl<T> Deref for Ref<T> {
type Target = Arc<T>;
fn deref(&self) -> &Self::Target {
&self.inner
}
}
/// A safe atomic pointer wrapper
#[derive(Clone, Debug)]
pub(crate) struct AtomPtr<T> {
inner: Arc<AtomicPtr<T>>,
inner: Arc<AtomicPtr<Arc<T>>>,
}
// Implement Default for all T that implement default
......@@ -28,17 +38,15 @@ impl<T: Default> Default for AtomPtr<T> {
impl<T> PartialEq for AtomPtr<T> {
fn eq(&self, other: &Self) -> bool {
let a = Box::into_raw(self.get_ref());
let b = Box::into_raw(other.get_ref());
a == b
Arc::ptr_eq(&self.get_ref().inner, &other.get_ref().inner)
}
}
impl<T> AtomPtr<T> {
/// Create a new atomic pointer for a type
pub(crate) fn new(t: T) -> Self {
let ptr = Box::into_raw(Box::new(t));
let arc = Arc::new(t);
let ptr = Box::into_raw(Box::new(arc));
let inner = Arc::new(AtomicPtr::from(ptr));
Self { inner }
}
......@@ -46,14 +54,24 @@ impl<T> AtomPtr<T> {
/// Get an immutable reference to the current value
pub(crate) fn get_ref(&self) -> Ref<T> {
let ptr = self.inner.load(Ordering::Relaxed);
unsafe { Box::from_raw(ptr) }
let b = unsafe { Box::from_raw(ptr) };
let arc = Arc::clone(&*b);
std::mem::forget(b);
Ref { inner: Box::new(arc) }
}
/// Swap the data entry with a new value, returning the old
pub(crate) fn swap(&self, new: T) -> Ref<T> {
let ptr = Box::into_raw(Box::new(new));
let prev = self.inner.swap(ptr, Ordering::Relaxed);
unsafe { Box::from_raw(prev) }
let ptr = self.inner.load(Ordering::Relaxed);
self.inner.swap(ptr, Ordering::Relaxed);
let b = unsafe { Box::from_raw(ptr) };
let arc = Arc::clone(&*b);
std::mem::forget(b);
Ref { inner: Box::new(arc) }
}
}
......
......@@ -36,7 +36,7 @@ impl Server {
.await
.map(|inner| {
Arc::new(Self {
alive: Default::default(),
alive: Arc::new(true.into()),
incoming: IoPair::default(),
inner,
routes,
......@@ -198,7 +198,7 @@ impl Server {
}
);
let peer = self.routes.get_peer(id).await.unwrap();
task::spawn(async move { Self::send_keepalive(peer) });
task::spawn(async move { Self::send_keepalive(peer).await });
}
}
}
......
......@@ -22,8 +22,7 @@ stdenv.mkDerivation {
llvmPackages.clang-unwrapped
# webgui debugging and development
httpie
nodejs
httpie nodejs yarn
# Required for the code coverage and stuff
openssl
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment