rust/hedgewars-server/src/server/io.rs
author alfadur
Wed, 10 Apr 2019 01:13:29 +0300
changeset 14802 01f8ab45f806
parent 14801 65861ba8b4e8
child 14806 a1077e8d26f4
permissions -rw-r--r--
fix lobby joining
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
14413
e335b3120f59 pull file io out of server handler
alfadur
parents:
diff changeset
     1
use std::{
e335b3120f59 pull file io out of server handler
alfadur
parents:
diff changeset
     2
    fs::{File, OpenOptions},
14478
98ef2913ec73 Apply rustfmt to all files
unc0rr
parents: 14436
diff changeset
     3
    io::{Error, ErrorKind, Read, Result, Write},
14800
f43ab2bd76ae add a thread for internal server IO and implement account checking with it
alfadur
parents: 14478
diff changeset
     4
    sync::mpsc,
f43ab2bd76ae add a thread for internal server IO and implement account checking with it
alfadur
parents: 14478
diff changeset
     5
    thread,
14413
e335b3120f59 pull file io out of server handler
alfadur
parents:
diff changeset
     6
};
e335b3120f59 pull file io out of server handler
alfadur
parents:
diff changeset
     7
14800
f43ab2bd76ae add a thread for internal server IO and implement account checking with it
alfadur
parents: 14478
diff changeset
     8
use crate::server::{
f43ab2bd76ae add a thread for internal server IO and implement account checking with it
alfadur
parents: 14478
diff changeset
     9
    database::Database,
f43ab2bd76ae add a thread for internal server IO and implement account checking with it
alfadur
parents: 14478
diff changeset
    10
    handlers::{IoResult, IoTask},
f43ab2bd76ae add a thread for internal server IO and implement account checking with it
alfadur
parents: 14478
diff changeset
    11
};
14802
01f8ab45f806 fix lobby joining
alfadur
parents: 14801
diff changeset
    12
use log::*;
14800
f43ab2bd76ae add a thread for internal server IO and implement account checking with it
alfadur
parents: 14478
diff changeset
    13
use mio::{Evented, Poll, PollOpt};
f43ab2bd76ae add a thread for internal server IO and implement account checking with it
alfadur
parents: 14478
diff changeset
    14
use mio_extras::channel;
f43ab2bd76ae add a thread for internal server IO and implement account checking with it
alfadur
parents: 14478
diff changeset
    15
f43ab2bd76ae add a thread for internal server IO and implement account checking with it
alfadur
parents: 14478
diff changeset
    16
pub type RequestId = u32;
f43ab2bd76ae add a thread for internal server IO and implement account checking with it
alfadur
parents: 14478
diff changeset
    17
f43ab2bd76ae add a thread for internal server IO and implement account checking with it
alfadur
parents: 14478
diff changeset
    18
pub struct IOThread {
f43ab2bd76ae add a thread for internal server IO and implement account checking with it
alfadur
parents: 14478
diff changeset
    19
    core_tx: mpsc::Sender<(RequestId, IoTask)>,
f43ab2bd76ae add a thread for internal server IO and implement account checking with it
alfadur
parents: 14478
diff changeset
    20
    core_rx: channel::Receiver<(RequestId, IoResult)>,
14413
e335b3120f59 pull file io out of server handler
alfadur
parents:
diff changeset
    21
}
e335b3120f59 pull file io out of server handler
alfadur
parents:
diff changeset
    22
14800
f43ab2bd76ae add a thread for internal server IO and implement account checking with it
alfadur
parents: 14478
diff changeset
    23
impl IOThread {
14413
e335b3120f59 pull file io out of server handler
alfadur
parents:
diff changeset
    24
    pub fn new() -> Self {
14800
f43ab2bd76ae add a thread for internal server IO and implement account checking with it
alfadur
parents: 14478
diff changeset
    25
        let (core_tx, io_rx) = mpsc::channel();
f43ab2bd76ae add a thread for internal server IO and implement account checking with it
alfadur
parents: 14478
diff changeset
    26
        let (io_tx, core_rx) = channel::channel();
f43ab2bd76ae add a thread for internal server IO and implement account checking with it
alfadur
parents: 14478
diff changeset
    27
f43ab2bd76ae add a thread for internal server IO and implement account checking with it
alfadur
parents: 14478
diff changeset
    28
        let mut db = Database::new();
f43ab2bd76ae add a thread for internal server IO and implement account checking with it
alfadur
parents: 14478
diff changeset
    29
        db.connect("localhost");
14413
e335b3120f59 pull file io out of server handler
alfadur
parents:
diff changeset
    30
14800
f43ab2bd76ae add a thread for internal server IO and implement account checking with it
alfadur
parents: 14478
diff changeset
    31
        thread::spawn(move || {
f43ab2bd76ae add a thread for internal server IO and implement account checking with it
alfadur
parents: 14478
diff changeset
    32
            while let Ok((request_id, task)) = io_rx.try_recv() {
14801
65861ba8b4e8 move room saves to IO thread
alfadur
parents: 14800
diff changeset
    33
                let response = match task {
14800
f43ab2bd76ae add a thread for internal server IO and implement account checking with it
alfadur
parents: 14478
diff changeset
    34
                    IoTask::GetAccount {
f43ab2bd76ae add a thread for internal server IO and implement account checking with it
alfadur
parents: 14478
diff changeset
    35
                        nick,
f43ab2bd76ae add a thread for internal server IO and implement account checking with it
alfadur
parents: 14478
diff changeset
    36
                        protocol,
f43ab2bd76ae add a thread for internal server IO and implement account checking with it
alfadur
parents: 14478
diff changeset
    37
                        password_hash,
f43ab2bd76ae add a thread for internal server IO and implement account checking with it
alfadur
parents: 14478
diff changeset
    38
                        client_salt,
f43ab2bd76ae add a thread for internal server IO and implement account checking with it
alfadur
parents: 14478
diff changeset
    39
                        server_salt,
f43ab2bd76ae add a thread for internal server IO and implement account checking with it
alfadur
parents: 14478
diff changeset
    40
                    } => {
14801
65861ba8b4e8 move room saves to IO thread
alfadur
parents: 14800
diff changeset
    41
                        match db.get_account(
14800
f43ab2bd76ae add a thread for internal server IO and implement account checking with it
alfadur
parents: 14478
diff changeset
    42
                            &nick,
f43ab2bd76ae add a thread for internal server IO and implement account checking with it
alfadur
parents: 14478
diff changeset
    43
                            protocol,
f43ab2bd76ae add a thread for internal server IO and implement account checking with it
alfadur
parents: 14478
diff changeset
    44
                            &password_hash,
f43ab2bd76ae add a thread for internal server IO and implement account checking with it
alfadur
parents: 14478
diff changeset
    45
                            &client_salt,
f43ab2bd76ae add a thread for internal server IO and implement account checking with it
alfadur
parents: 14478
diff changeset
    46
                            &server_salt,
f43ab2bd76ae add a thread for internal server IO and implement account checking with it
alfadur
parents: 14478
diff changeset
    47
                        ) {
14802
01f8ab45f806 fix lobby joining
alfadur
parents: 14801
diff changeset
    48
                            Ok(account) => IoResult::Account(account),
14801
65861ba8b4e8 move room saves to IO thread
alfadur
parents: 14800
diff changeset
    49
                            Err(..) => {
65861ba8b4e8 move room saves to IO thread
alfadur
parents: 14800
diff changeset
    50
                                warn!("Unable to get account data: {}", 0);
65861ba8b4e8 move room saves to IO thread
alfadur
parents: 14800
diff changeset
    51
                                IoResult::Account(None)
65861ba8b4e8 move room saves to IO thread
alfadur
parents: 14800
diff changeset
    52
                            }
14800
f43ab2bd76ae add a thread for internal server IO and implement account checking with it
alfadur
parents: 14478
diff changeset
    53
                        }
14802
01f8ab45f806 fix lobby joining
alfadur
parents: 14801
diff changeset
    54
                    }
14801
65861ba8b4e8 move room saves to IO thread
alfadur
parents: 14800
diff changeset
    55
14802
01f8ab45f806 fix lobby joining
alfadur
parents: 14801
diff changeset
    56
                    IoTask::SaveRoom {
01f8ab45f806 fix lobby joining
alfadur
parents: 14801
diff changeset
    57
                        room_id,
01f8ab45f806 fix lobby joining
alfadur
parents: 14801
diff changeset
    58
                        filename,
01f8ab45f806 fix lobby joining
alfadur
parents: 14801
diff changeset
    59
                        contents,
01f8ab45f806 fix lobby joining
alfadur
parents: 14801
diff changeset
    60
                    } => {
14801
65861ba8b4e8 move room saves to IO thread
alfadur
parents: 14800
diff changeset
    61
                        let result = match save_file(&filename, &contents) {
65861ba8b4e8 move room saves to IO thread
alfadur
parents: 14800
diff changeset
    62
                            Ok(()) => true,
65861ba8b4e8 move room saves to IO thread
alfadur
parents: 14800
diff changeset
    63
                            Err(e) => {
65861ba8b4e8 move room saves to IO thread
alfadur
parents: 14800
diff changeset
    64
                                warn!(
65861ba8b4e8 move room saves to IO thread
alfadur
parents: 14800
diff changeset
    65
                                    "Error while writing the room config file \"{}\": {}",
65861ba8b4e8 move room saves to IO thread
alfadur
parents: 14800
diff changeset
    66
                                    filename, e
65861ba8b4e8 move room saves to IO thread
alfadur
parents: 14800
diff changeset
    67
                                );
65861ba8b4e8 move room saves to IO thread
alfadur
parents: 14800
diff changeset
    68
                                false
14802
01f8ab45f806 fix lobby joining
alfadur
parents: 14801
diff changeset
    69
                            }
14801
65861ba8b4e8 move room saves to IO thread
alfadur
parents: 14800
diff changeset
    70
                        };
65861ba8b4e8 move room saves to IO thread
alfadur
parents: 14800
diff changeset
    71
                        IoResult::SaveRoom(room_id, result)
14802
01f8ab45f806 fix lobby joining
alfadur
parents: 14801
diff changeset
    72
                    }
14801
65861ba8b4e8 move room saves to IO thread
alfadur
parents: 14800
diff changeset
    73
14802
01f8ab45f806 fix lobby joining
alfadur
parents: 14801
diff changeset
    74
                    IoTask::LoadRoom { room_id, filename } => {
14801
65861ba8b4e8 move room saves to IO thread
alfadur
parents: 14800
diff changeset
    75
                        let result = match load_file(&filename) {
65861ba8b4e8 move room saves to IO thread
alfadur
parents: 14800
diff changeset
    76
                            Ok(contents) => Some(contents),
65861ba8b4e8 move room saves to IO thread
alfadur
parents: 14800
diff changeset
    77
                            Err(e) => {
65861ba8b4e8 move room saves to IO thread
alfadur
parents: 14800
diff changeset
    78
                                warn!(
65861ba8b4e8 move room saves to IO thread
alfadur
parents: 14800
diff changeset
    79
                                    "Error while writing the room config file \"{}\": {}",
65861ba8b4e8 move room saves to IO thread
alfadur
parents: 14800
diff changeset
    80
                                    filename, e
65861ba8b4e8 move room saves to IO thread
alfadur
parents: 14800
diff changeset
    81
                                );
65861ba8b4e8 move room saves to IO thread
alfadur
parents: 14800
diff changeset
    82
                                None
65861ba8b4e8 move room saves to IO thread
alfadur
parents: 14800
diff changeset
    83
                            }
65861ba8b4e8 move room saves to IO thread
alfadur
parents: 14800
diff changeset
    84
                        };
65861ba8b4e8 move room saves to IO thread
alfadur
parents: 14800
diff changeset
    85
                        IoResult::LoadRoom(room_id, result)
14800
f43ab2bd76ae add a thread for internal server IO and implement account checking with it
alfadur
parents: 14478
diff changeset
    86
                    }
14801
65861ba8b4e8 move room saves to IO thread
alfadur
parents: 14800
diff changeset
    87
                };
65861ba8b4e8 move room saves to IO thread
alfadur
parents: 14800
diff changeset
    88
                io_tx.send((request_id, response));
14800
f43ab2bd76ae add a thread for internal server IO and implement account checking with it
alfadur
parents: 14478
diff changeset
    89
            }
f43ab2bd76ae add a thread for internal server IO and implement account checking with it
alfadur
parents: 14478
diff changeset
    90
        });
f43ab2bd76ae add a thread for internal server IO and implement account checking with it
alfadur
parents: 14478
diff changeset
    91
f43ab2bd76ae add a thread for internal server IO and implement account checking with it
alfadur
parents: 14478
diff changeset
    92
        Self { core_rx, core_tx }
14413
e335b3120f59 pull file io out of server handler
alfadur
parents:
diff changeset
    93
    }
e335b3120f59 pull file io out of server handler
alfadur
parents:
diff changeset
    94
14800
f43ab2bd76ae add a thread for internal server IO and implement account checking with it
alfadur
parents: 14478
diff changeset
    95
    pub fn send(&self, request_id: RequestId, task: IoTask) {
f43ab2bd76ae add a thread for internal server IO and implement account checking with it
alfadur
parents: 14478
diff changeset
    96
        self.core_tx.send((request_id, task)).unwrap();
14413
e335b3120f59 pull file io out of server handler
alfadur
parents:
diff changeset
    97
    }
e335b3120f59 pull file io out of server handler
alfadur
parents:
diff changeset
    98
14800
f43ab2bd76ae add a thread for internal server IO and implement account checking with it
alfadur
parents: 14478
diff changeset
    99
    pub fn try_recv(&self) -> Option<(RequestId, IoResult)> {
f43ab2bd76ae add a thread for internal server IO and implement account checking with it
alfadur
parents: 14478
diff changeset
   100
        match self.core_rx.try_recv() {
f43ab2bd76ae add a thread for internal server IO and implement account checking with it
alfadur
parents: 14478
diff changeset
   101
            Ok(result) => Some(result),
f43ab2bd76ae add a thread for internal server IO and implement account checking with it
alfadur
parents: 14478
diff changeset
   102
            Err(mpsc::TryRecvError::Empty) => None,
f43ab2bd76ae add a thread for internal server IO and implement account checking with it
alfadur
parents: 14478
diff changeset
   103
            Err(mpsc::TryRecvError::Disconnected) => unreachable!(),
f43ab2bd76ae add a thread for internal server IO and implement account checking with it
alfadur
parents: 14478
diff changeset
   104
        }
f43ab2bd76ae add a thread for internal server IO and implement account checking with it
alfadur
parents: 14478
diff changeset
   105
    }
14413
e335b3120f59 pull file io out of server handler
alfadur
parents:
diff changeset
   106
14800
f43ab2bd76ae add a thread for internal server IO and implement account checking with it
alfadur
parents: 14478
diff changeset
   107
    pub fn register_rx(&self, poll: &mio::Poll, token: mio::Token) -> Result<()> {
f43ab2bd76ae add a thread for internal server IO and implement account checking with it
alfadur
parents: 14478
diff changeset
   108
        self.core_rx
f43ab2bd76ae add a thread for internal server IO and implement account checking with it
alfadur
parents: 14478
diff changeset
   109
            .register(poll, token, mio::Ready::readable(), PollOpt::edge())
14413
e335b3120f59 pull file io out of server handler
alfadur
parents:
diff changeset
   110
    }
e335b3120f59 pull file io out of server handler
alfadur
parents:
diff changeset
   111
}
14801
65861ba8b4e8 move room saves to IO thread
alfadur
parents: 14800
diff changeset
   112
65861ba8b4e8 move room saves to IO thread
alfadur
parents: 14800
diff changeset
   113
fn save_file(filename: &str, contents: &str) -> Result<()> {
65861ba8b4e8 move room saves to IO thread
alfadur
parents: 14800
diff changeset
   114
    let mut writer = OpenOptions::new().create(true).write(true).open(filename)?;
65861ba8b4e8 move room saves to IO thread
alfadur
parents: 14800
diff changeset
   115
    writer.write_all(contents.as_bytes())
65861ba8b4e8 move room saves to IO thread
alfadur
parents: 14800
diff changeset
   116
}
65861ba8b4e8 move room saves to IO thread
alfadur
parents: 14800
diff changeset
   117
65861ba8b4e8 move room saves to IO thread
alfadur
parents: 14800
diff changeset
   118
fn load_file(filename: &str) -> Result<String> {
65861ba8b4e8 move room saves to IO thread
alfadur
parents: 14800
diff changeset
   119
    let mut reader = File::open(filename)?;
65861ba8b4e8 move room saves to IO thread
alfadur
parents: 14800
diff changeset
   120
    let mut result = String::new();
65861ba8b4e8 move room saves to IO thread
alfadur
parents: 14800
diff changeset
   121
    reader.read_to_string(&mut result)?;
65861ba8b4e8 move room saves to IO thread
alfadur
parents: 14800
diff changeset
   122
    Ok(result)
14802
01f8ab45f806 fix lobby joining
alfadur
parents: 14801
diff changeset
   123
}