Implement Server Logging
This commit is contained in:
parent
6f9931a04f
commit
c2bd135dd9
|
@ -1,5 +1,6 @@
|
||||||
use super::*;
|
use super::*;
|
||||||
|
|
||||||
|
use std::fmt;
|
||||||
use std::io::*;
|
use std::io::*;
|
||||||
use std::net::*;
|
use std::net::*;
|
||||||
|
|
||||||
|
@ -10,6 +11,14 @@ pub struct Connection<R: Read + Sized, W: Write + Sized> {
|
||||||
writer: W,
|
writer: W,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl<R: Read + Sized, W: Write + Sized> fmt::Display for Connection<R, W> {
|
||||||
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||||
|
write!(f, "<Client>") // Todo use some form of marker??
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<R: Read + Sized, W: Write + Sized> ClientConnection for Connection<R, W> {}
|
||||||
|
|
||||||
const KIB: u32 = 1024;
|
const KIB: u32 = 1024;
|
||||||
const MIB: u32 = 1024 * 1024;
|
const MIB: u32 = 1024 * 1024;
|
||||||
|
|
||||||
|
|
|
@ -32,6 +32,8 @@ where
|
||||||
H: 'static + ProtocolHandler + Sized,
|
H: 'static + ProtocolHandler + Sized,
|
||||||
{
|
{
|
||||||
let mut connection = Connection::from_tcp(connection)?;
|
let mut connection = Connection::from_tcp(connection)?;
|
||||||
|
handler.new_connection(&connection);
|
||||||
|
|
||||||
'outer: loop {
|
'outer: loop {
|
||||||
let package = connection.receive()?;
|
let package = connection.receive()?;
|
||||||
|
|
||||||
|
@ -55,15 +57,17 @@ where
|
||||||
}
|
}
|
||||||
|
|
||||||
Package::Command(Command::Query { query }) => {
|
Package::Command(Command::Query { query }) => {
|
||||||
connection.send(&Package::from(handler.query(&query[..])))?;
|
connection.send(&Package::from(handler.query(&connection, &query[..])))?;
|
||||||
}
|
}
|
||||||
|
|
||||||
Package::Command(Command::GetTexture { id, name }) => match (id, name) {
|
Package::Command(Command::GetTexture { id, name }) => match (id, name) {
|
||||||
(Some(id), None) => {
|
(Some(id), None) => {
|
||||||
connection.send(&Package::from(handler.get_texture_by_id(&id)))?;
|
connection.send(&Package::from(handler.get_texture_by_id(&connection, &id)))?;
|
||||||
}
|
}
|
||||||
(None, Some(name)) => {
|
(None, Some(name)) => {
|
||||||
connection.send(&Package::from(handler.get_texture_by_name(&name)))?;
|
connection.send(&Package::from(
|
||||||
|
handler.get_texture_by_name(&connection, &name),
|
||||||
|
))?;
|
||||||
}
|
}
|
||||||
_ => {
|
_ => {
|
||||||
connection.send(&Package::from(ProtocolError::BadRequest(
|
connection.send(&Package::from(ProtocolError::BadRequest(
|
||||||
|
@ -73,21 +77,25 @@ where
|
||||||
},
|
},
|
||||||
|
|
||||||
Package::Command(Command::GetTextureData { texture_hash }) => {
|
Package::Command(Command::GetTextureData { texture_hash }) => {
|
||||||
connection.send(&Package::from(handler.get_texture_file(texture_hash)))?;
|
connection.send(&Package::from(
|
||||||
|
handler.get_texture_file(&connection, texture_hash),
|
||||||
|
))?;
|
||||||
}
|
}
|
||||||
|
|
||||||
Package::Command(Command::GetTexturePreview {
|
Package::Command(Command::GetTexturePreview {
|
||||||
texture_hash,
|
texture_hash,
|
||||||
desired_format,
|
desired_format,
|
||||||
}) => {
|
}) => {
|
||||||
connection.send(&Package::from(
|
connection.send(&Package::from(handler.get_texture_preview(
|
||||||
handler.get_texture_preview(texture_hash, desired_format),
|
&connection,
|
||||||
))?;
|
texture_hash,
|
||||||
|
desired_format,
|
||||||
|
)))?;
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: use less nesting.
|
// TODO: use less nesting.
|
||||||
Package::Command(Command::ReplaceTexture { old, new }) => {
|
Package::Command(Command::ReplaceTexture { old, new }) => {
|
||||||
match handler.replace_texture(old.clone(), new.clone(), None) {
|
match handler.replace_texture(&connection, old.clone(), new.clone(), None) {
|
||||||
Ok(ReplaceTextureStatus::Ok) => {
|
Ok(ReplaceTextureStatus::Ok) => {
|
||||||
connection.send(&Package::Json(JsonValue::True))?;
|
connection.send(&Package::Json(JsonValue::True))?;
|
||||||
}
|
}
|
||||||
|
@ -99,8 +107,12 @@ where
|
||||||
let pkg = connection.receive()?;
|
let pkg = connection.receive()?;
|
||||||
match pkg {
|
match pkg {
|
||||||
Package::Binary(data) => {
|
Package::Binary(data) => {
|
||||||
match handler.replace_texture(old.clone(), new.clone(), Some(data))
|
match handler.replace_texture(
|
||||||
{
|
&connection,
|
||||||
|
old.clone(),
|
||||||
|
new.clone(),
|
||||||
|
Some(data),
|
||||||
|
) {
|
||||||
Ok(ReplaceTextureStatus::Ok) => {
|
Ok(ReplaceTextureStatus::Ok) => {
|
||||||
connection.send(&Package::Json(JsonValue::True))?;
|
connection.send(&Package::Json(JsonValue::True))?;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,31 +1,50 @@
|
||||||
mod implementation;
|
mod implementation;
|
||||||
|
|
||||||
pub use self::implementation::*;
|
pub use self::implementation::*;
|
||||||
|
use std::fmt::Display;
|
||||||
|
|
||||||
use crate::model::*;
|
use crate::model::*;
|
||||||
|
|
||||||
use std::io;
|
use std::io;
|
||||||
|
|
||||||
|
pub trait ClientConnection: Display {}
|
||||||
|
|
||||||
pub trait ProtocolHandler: Send + Sync + Clone {
|
pub trait ProtocolHandler: Send + Sync + Clone {
|
||||||
fn query(&mut self, query: &[String]) -> ProtocolResult<Vec<Texture>>;
|
fn new_connection(&mut self, _con: &ClientConnection) {}
|
||||||
|
|
||||||
fn get_texture_by_id(&mut self, id: &str) -> ProtocolResult<Option<Texture>>;
|
fn query(&mut self, con: &ClientConnection, query: &[String]) -> ProtocolResult<Vec<Texture>>;
|
||||||
|
|
||||||
fn get_texture_by_name(&mut self, name: &str) -> ProtocolResult<Option<Texture>>;
|
fn get_texture_by_id(
|
||||||
|
&mut self,
|
||||||
|
con: &ClientConnection,
|
||||||
|
id: &str,
|
||||||
|
) -> ProtocolResult<Option<Texture>>;
|
||||||
|
|
||||||
fn get_texture_file(&mut self, hash: Sha256) -> ProtocolResult<Vec<u8>>;
|
fn get_texture_by_name(
|
||||||
|
&mut self,
|
||||||
|
con: &ClientConnection,
|
||||||
|
name: &str,
|
||||||
|
) -> ProtocolResult<Option<Texture>>;
|
||||||
|
|
||||||
|
fn get_texture_file(&mut self, con: &ClientConnection, hash: Sha256)
|
||||||
|
-> ProtocolResult<Vec<u8>>;
|
||||||
|
|
||||||
fn get_texture_preview(
|
fn get_texture_preview(
|
||||||
&mut self,
|
&mut self,
|
||||||
|
con: &ClientConnection,
|
||||||
hash: Sha256,
|
hash: Sha256,
|
||||||
format: TextureFormat,
|
format: TextureFormat,
|
||||||
) -> ProtocolResult<Vec<u8>>;
|
) -> ProtocolResult<Vec<u8>>;
|
||||||
|
|
||||||
fn replace_texture(
|
fn replace_texture(
|
||||||
&mut self,
|
&mut self,
|
||||||
|
con: &ClientConnection,
|
||||||
delete: Option<Texture>,
|
delete: Option<Texture>,
|
||||||
insert: Option<Texture>,
|
insert: Option<Texture>,
|
||||||
insert_texture_data: Option<Vec<u8>>,
|
insert_texture_data: Option<Vec<u8>>,
|
||||||
) -> ProtocolResult<ReplaceTextureStatus>;
|
) -> ProtocolResult<ReplaceTextureStatus>;
|
||||||
|
|
||||||
|
fn disconnected(&mut self, _con: &ClientConnection) {}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Debug)]
|
#[derive(Clone, Debug)]
|
||||||
|
|
|
@ -21,7 +21,11 @@ impl ServerState {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ProtocolHandler for ServerState {
|
impl ProtocolHandler for ServerState {
|
||||||
fn query(&mut self, query: &[String]) -> ProtocolResult<Vec<Texture>> {
|
fn new_connection(&mut self, con: &ClientConnection) {
|
||||||
|
println!("{}: New Connection", con);
|
||||||
|
}
|
||||||
|
|
||||||
|
fn query(&mut self, con: &ClientConnection, query: &[String]) -> ProtocolResult<Vec<Texture>> {
|
||||||
let q = Query::parse(query)
|
let q = Query::parse(query)
|
||||||
.map_err(|e| ProtocolError::BadRequest(format!("Invalid Query String: {:?}", e)))?;
|
.map_err(|e| ProtocolError::BadRequest(format!("Invalid Query String: {:?}", e)))?;
|
||||||
|
|
||||||
|
@ -31,40 +35,83 @@ impl ProtocolHandler for ServerState {
|
||||||
.unwrap_or_else(|_| handle_broken_rwlock());
|
.unwrap_or_else(|_| handle_broken_rwlock());
|
||||||
|
|
||||||
let mut textures = data_store.borrow_textures();
|
let mut textures = data_store.borrow_textures();
|
||||||
Ok(q.search(&mut textures))
|
|
||||||
|
let found = q.search(&mut textures);
|
||||||
|
|
||||||
|
println!("{}: Query '{:?}' found: {}", con, query, found.len());
|
||||||
|
|
||||||
|
Ok(found)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_texture_by_id(&mut self, id: &str) -> ProtocolResult<Option<Texture>> {
|
fn get_texture_by_id(
|
||||||
|
&mut self,
|
||||||
|
con: &ClientConnection,
|
||||||
|
id: &str,
|
||||||
|
) -> ProtocolResult<Option<Texture>> {
|
||||||
let data_store = self
|
let data_store = self
|
||||||
.data_store
|
.data_store
|
||||||
.read()
|
.read()
|
||||||
.unwrap_or_else(|_| handle_broken_rwlock());
|
.unwrap_or_else(|_| handle_broken_rwlock());
|
||||||
|
|
||||||
Ok(data_store.texture_by_id(id))
|
let found = data_store.texture_by_id(id);
|
||||||
|
|
||||||
|
println!(
|
||||||
|
"{}: Texture by id: '{}' found: {}",
|
||||||
|
con,
|
||||||
|
id,
|
||||||
|
found.is_some()
|
||||||
|
);
|
||||||
|
|
||||||
|
Ok(found)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_texture_by_name(&mut self, name: &str) -> ProtocolResult<Option<Texture>> {
|
fn get_texture_by_name(
|
||||||
|
&mut self,
|
||||||
|
con: &ClientConnection,
|
||||||
|
name: &str,
|
||||||
|
) -> ProtocolResult<Option<Texture>> {
|
||||||
let data_store = self
|
let data_store = self
|
||||||
.data_store
|
.data_store
|
||||||
.read()
|
.read()
|
||||||
.unwrap_or_else(|_| handle_broken_rwlock());
|
.unwrap_or_else(|_| handle_broken_rwlock());
|
||||||
|
|
||||||
Ok(data_store.texture_by_name(name))
|
let found = data_store.texture_by_name(name);
|
||||||
|
|
||||||
|
println!(
|
||||||
|
"{}: Texture by name: '{}' found: {}",
|
||||||
|
con,
|
||||||
|
name,
|
||||||
|
found.is_some()
|
||||||
|
);
|
||||||
|
|
||||||
|
Ok(found)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_texture_file(&mut self, hash: Sha256) -> ProtocolResult<Vec<u8>> {
|
fn get_texture_file(
|
||||||
|
&mut self,
|
||||||
|
con: &ClientConnection,
|
||||||
|
hash: Sha256,
|
||||||
|
) -> ProtocolResult<Vec<u8>> {
|
||||||
let data_store = self
|
let data_store = self
|
||||||
.data_store
|
.data_store
|
||||||
.read()
|
.read()
|
||||||
.unwrap_or_else(|_| handle_broken_rwlock());
|
.unwrap_or_else(|_| handle_broken_rwlock());
|
||||||
|
|
||||||
let data = data_store.read_texture_file_by_hash(&hash)?;
|
let data = data_store.read_texture_file_by_hash(&hash);
|
||||||
|
|
||||||
Ok(data)
|
println!(
|
||||||
|
"{}: Texture File: '{:?}' found: {}",
|
||||||
|
con,
|
||||||
|
&hash,
|
||||||
|
data.is_ok()
|
||||||
|
);
|
||||||
|
|
||||||
|
Ok(data?)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_texture_preview(
|
fn get_texture_preview(
|
||||||
&mut self,
|
&mut self,
|
||||||
|
con: &ClientConnection,
|
||||||
hash: Sha256,
|
hash: Sha256,
|
||||||
format: TextureFormat,
|
format: TextureFormat,
|
||||||
) -> ProtocolResult<Vec<u8>> {
|
) -> ProtocolResult<Vec<u8>> {
|
||||||
|
@ -73,17 +120,27 @@ impl ProtocolHandler for ServerState {
|
||||||
.write()
|
.write()
|
||||||
.unwrap_or_else(|_| handle_broken_rwlock());
|
.unwrap_or_else(|_| handle_broken_rwlock());
|
||||||
|
|
||||||
let preview = data_store.get_texture_preview(&hash, format)?;
|
let preview = data_store.get_texture_preview(&hash, format);
|
||||||
|
|
||||||
Ok(preview)
|
println!(
|
||||||
|
"{}: Texture Preview: '{:?}' found: {}",
|
||||||
|
con,
|
||||||
|
&hash,
|
||||||
|
preview.is_ok()
|
||||||
|
);
|
||||||
|
|
||||||
|
Ok(preview?)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn replace_texture(
|
fn replace_texture(
|
||||||
&mut self,
|
&mut self,
|
||||||
|
con: &ClientConnection,
|
||||||
delete: Option<Texture>,
|
delete: Option<Texture>,
|
||||||
insert: Option<Texture>,
|
insert: Option<Texture>,
|
||||||
insert_texture_data: Option<Vec<u8>>,
|
insert_texture_data: Option<Vec<u8>>,
|
||||||
) -> ProtocolResult<ReplaceTextureStatus> {
|
) -> ProtocolResult<ReplaceTextureStatus> {
|
||||||
|
println!("{}: Replace Texture Request", con);
|
||||||
|
|
||||||
let mut data_store = self
|
let mut data_store = self
|
||||||
.data_store
|
.data_store
|
||||||
.write()
|
.write()
|
||||||
|
@ -152,6 +209,10 @@ impl ProtocolHandler for ServerState {
|
||||||
(None, None) => Ok(ReplaceTextureStatus::Ok),
|
(None, None) => Ok(ReplaceTextureStatus::Ok),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn disconnected(&mut self, con: &ClientConnection) {
|
||||||
|
println!("{}: Disconnected", con);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn handle_broken_rwlock() -> ! {
|
fn handle_broken_rwlock() -> ! {
|
||||||
|
|
Loading…
Reference in New Issue