Стратегия синхронизации ржавчины для сервера MUD

Так что, если у вас был сервер MUD, который обрабатывал каждое TCP-соединение в отдельном процессе,

for stream in acceptor.incoming() {
    match stream {
        Err(e) => { /* connection failed */ }
        Ok(stream) => spawn(proc() {
            handle_client(stream)
        })
    }
}

Какова будет стратегия обмена изменчивыми мировыми данными для этого сервера? Я могу представить себе n соединений, отвечающих на команды пользователя. Каждой команде нужно посетить и, возможно, изменить мир.

pub struct Server<'a> {
    world: World<'a>
}

pub struct World<'a> {
    pub chat_rooms: HashMap<&'a str, ChatRoom<'a>>
}


impl<'a> World<'a> {
    pub fn new() -> World<'a> {
        let mut rooms = HashMap::new();
        rooms.insert("General", ChatRoom::new("General"));
        rooms.insert("Help", ChatRoom::new("Help"));
        World{chat_rooms: rooms}
    }
}

Будет ли Арк путь?

let shared_server = Arc::new(server);
let server = shared_server.clone();

spawn(proc() {
    // Work with server
});

Как насчет масштабирования до 100 или 1000 пользователей? Я просто ищу толчок в правильном направлении.

1 ответ

Решение

Arc позволит вам получить доступ к значению из нескольких задач, но не позволит вам позаимствовать значение изменчиво. Компилятор не может статически проверить, что только одна задача заимствует значение изменчиво за раз, а изменение значения одновременно в разных задачах приводит к гонкам данных.

Стандартная библиотека Rust предоставляет некоторые типы, которые позволяют безопасно изменять общий объект. Вот два из них:

  • Mutex: Это простая блокировка взаимного исключения. Mutex оборачивает защищенное значение, поэтому единственный способ получить доступ к значению - заблокировать мьютекс. Только одна задача за раз может получить доступ к перенесенному значению.
  • RWLock: Это блокировка чтения-записи. Этот тип блокировки позволяет нескольким задачам читать значение одновременно, но авторы должны иметь монопольный доступ. Это в основном те же правила, что и проверка заимствования и RefCell иметь (за исключением блокировки ожидает освобождения заимствования, вместо сбоя компиляции или паники).

Вам нужно будет обернуть Mutex или RWLock в Arc сделать его доступным для нескольких задач.

Другие вопросы по тегам