Calling an unsafe library object of from a different thread

别来无恙 提交于 2021-01-28 21:22:17

问题


I am using tikv/raft-rs library for implementing a consensus system. This library has a RawNode object which is a thread-unsafe object. We must execute some functions on this object periodically (example), hence I use a new thread for executing.

Here are the constraints:

  • I need to have this object on the main-thread doesn't have this object for accessing some its internal states. (e.g.: raw_node.is_leader)
  • This object must be accessed on a worker thread.

Because of these constraints, this seems impossible because:

  • If I create this object, and move to the new thread, the main thread cannot call its state.
  • If I keep this object on the main thread object, I cannot use Arc<Mutex<>> because this object doesn't implement Copy method.

Here is my code:

use std::thread::JoinHandle;
use std::sync::{Arc, Mutex, mpsc};
use std::collections::{VecDeque, HashMap};
use raft::RawNode;
use std::sync::mpsc::{Receiver, Sender, TryRecvError};

use protobuf::Message as PbMessage;
use raft::eraftpb::ConfState;
use raft::storage::MemStorage;
use raft::{prelude::*, StateRole};
use regex::Regex;
use crate::proposal::Proposal;
use crate::{proposal, batch};
use std::{str, thread};
use std::time::{Instant, Duration};
use crate::batch::Mailbox;

pub struct Node {
    core: Arc<Mutex<CoreNode>>
}

#[derive(Copy)]
struct CoreNode {
    raft_group: RawNode<MemStorage>,
}


impl Node {
    pub fn new() -> Self {
        let cfg = Config {
            election_tick: 10,
            heartbeat_tick: 3,
            ..Default::default()
        };
        let storage = MemStorage::new();

        let core = Arc::new(Mutex::new(CoreNode {
            raft_group: RawNode::new(&cfg, storage).unwrap()
        }));

        thread::spawn(move || {
            core.lock().unwrap().run();
            return;
        });

        Node { core: core.clone() }
    }

    pub fn is_leader(&self) -> bool {
        return self.core.lock().unwrap().raft_group.raft.state == StateRole::Leader;

    }
}

impl CoreNode {
    pub fn run(mut self) {}
}

When compiling, here is the error:

22 | #[derive(Copy)]
   |          ^^^^
23 | struct CoreNode {
24 |     raft_group: RawNode<MemStorage>,
   |     ------------------------------- this field does not implement `Copy`
   |

My question is: How can I design around this problem.

来源:https://stackoverflow.com/questions/65654251/calling-an-unsafe-library-object-of-from-a-different-thread

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!