Implement Server Logging
This commit is contained in:
		@ -1,5 +1,6 @@
 | 
			
		||||
use super::*;
 | 
			
		||||
 | 
			
		||||
use std::fmt;
 | 
			
		||||
use std::io::*;
 | 
			
		||||
use std::net::*;
 | 
			
		||||
 | 
			
		||||
@ -10,6 +11,14 @@ pub struct Connection<R: Read + Sized, W: Write + Sized> {
 | 
			
		||||
    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 MIB: u32 = 1024 * 1024;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -32,6 +32,8 @@ where
 | 
			
		||||
    H: 'static + ProtocolHandler + Sized,
 | 
			
		||||
{
 | 
			
		||||
    let mut connection = Connection::from_tcp(connection)?;
 | 
			
		||||
    handler.new_connection(&connection);
 | 
			
		||||
 | 
			
		||||
    'outer: loop {
 | 
			
		||||
        let package = connection.receive()?;
 | 
			
		||||
 | 
			
		||||
@ -55,15 +57,17 @@ where
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            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) {
 | 
			
		||||
                (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)) => {
 | 
			
		||||
                    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(
 | 
			
		||||
@ -73,21 +77,25 @@ where
 | 
			
		||||
            },
 | 
			
		||||
 | 
			
		||||
            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 {
 | 
			
		||||
                texture_hash,
 | 
			
		||||
                desired_format,
 | 
			
		||||
            }) => {
 | 
			
		||||
                connection.send(&Package::from(
 | 
			
		||||
                    handler.get_texture_preview(texture_hash, desired_format),
 | 
			
		||||
                ))?;
 | 
			
		||||
                connection.send(&Package::from(handler.get_texture_preview(
 | 
			
		||||
                    &connection,
 | 
			
		||||
                    texture_hash,
 | 
			
		||||
                    desired_format,
 | 
			
		||||
                )))?;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            // TODO: use less nesting.
 | 
			
		||||
            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) => {
 | 
			
		||||
                        connection.send(&Package::Json(JsonValue::True))?;
 | 
			
		||||
                    }
 | 
			
		||||
@ -99,8 +107,12 @@ where
 | 
			
		||||
                        let pkg = connection.receive()?;
 | 
			
		||||
                        match pkg {
 | 
			
		||||
                            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) => {
 | 
			
		||||
                                        connection.send(&Package::Json(JsonValue::True))?;
 | 
			
		||||
                                    }
 | 
			
		||||
 | 
			
		||||
@ -1,31 +1,50 @@
 | 
			
		||||
mod implementation;
 | 
			
		||||
 | 
			
		||||
pub use self::implementation::*;
 | 
			
		||||
use std::fmt::Display;
 | 
			
		||||
 | 
			
		||||
use crate::model::*;
 | 
			
		||||
 | 
			
		||||
use std::io;
 | 
			
		||||
 | 
			
		||||
pub trait ClientConnection: Display {}
 | 
			
		||||
 | 
			
		||||
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(
 | 
			
		||||
        &mut self,
 | 
			
		||||
        con: &ClientConnection,
 | 
			
		||||
        hash: Sha256,
 | 
			
		||||
        format: TextureFormat,
 | 
			
		||||
    ) -> ProtocolResult<Vec<u8>>;
 | 
			
		||||
 | 
			
		||||
    fn replace_texture(
 | 
			
		||||
        &mut self,
 | 
			
		||||
        con: &ClientConnection,
 | 
			
		||||
        delete: Option<Texture>,
 | 
			
		||||
        insert: Option<Texture>,
 | 
			
		||||
        insert_texture_data: Option<Vec<u8>>,
 | 
			
		||||
    ) -> ProtocolResult<ReplaceTextureStatus>;
 | 
			
		||||
 | 
			
		||||
    fn disconnected(&mut self, _con: &ClientConnection) {}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#[derive(Clone, Debug)]
 | 
			
		||||
 | 
			
		||||
@ -21,7 +21,11 @@ impl 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)
 | 
			
		||||
            .map_err(|e| ProtocolError::BadRequest(format!("Invalid Query String: {:?}", e)))?;
 | 
			
		||||
 | 
			
		||||
@ -31,40 +35,83 @@ impl ProtocolHandler for ServerState {
 | 
			
		||||
            .unwrap_or_else(|_| handle_broken_rwlock());
 | 
			
		||||
 | 
			
		||||
        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
 | 
			
		||||
            .data_store
 | 
			
		||||
            .read()
 | 
			
		||||
            .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
 | 
			
		||||
            .data_store
 | 
			
		||||
            .read()
 | 
			
		||||
            .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
 | 
			
		||||
            .data_store
 | 
			
		||||
            .read()
 | 
			
		||||
            .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(
 | 
			
		||||
        &mut self,
 | 
			
		||||
        con: &ClientConnection,
 | 
			
		||||
        hash: Sha256,
 | 
			
		||||
        format: TextureFormat,
 | 
			
		||||
    ) -> ProtocolResult<Vec<u8>> {
 | 
			
		||||
@ -73,17 +120,27 @@ impl ProtocolHandler for ServerState {
 | 
			
		||||
            .write()
 | 
			
		||||
            .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(
 | 
			
		||||
        &mut self,
 | 
			
		||||
        con: &ClientConnection,
 | 
			
		||||
        delete: Option<Texture>,
 | 
			
		||||
        insert: Option<Texture>,
 | 
			
		||||
        insert_texture_data: Option<Vec<u8>>,
 | 
			
		||||
    ) -> ProtocolResult<ReplaceTextureStatus> {
 | 
			
		||||
        println!("{}: Replace Texture Request", con);
 | 
			
		||||
 | 
			
		||||
        let mut data_store = self
 | 
			
		||||
            .data_store
 | 
			
		||||
            .write()
 | 
			
		||||
@ -152,6 +209,10 @@ impl ProtocolHandler for ServerState {
 | 
			
		||||
            (None, None) => Ok(ReplaceTextureStatus::Ok),
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    fn disconnected(&mut self, con: &ClientConnection) {
 | 
			
		||||
        println!("{}: Disconnected", con);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
fn handle_broken_rwlock() -> ! {
 | 
			
		||||
 | 
			
		||||
		Reference in New Issue
	
	Block a user