erickt / rust-zmq

Rust zeromq bindings.
Apache License 2.0
886 stars 189 forks source link

Add a weakly-counted context wrapper #307

Open peterjoel opened 4 years ago

peterjoel commented 4 years ago

This need arose when we had some code like this:

lazy_static! {
    static ref ZMQ_CTX: zmq::Context = zmq::Context::new();
}

Which is so we can reuse the context conveniently without have to pass it around. The problem was that some final messages would not be sent, because the context's finalizer would never run.

We could work around this with:

lazy_static! {
    static ref ZMQ_CTX: Mutex<Weak<Context>> = Mutex::new(Weak::new());
}

fn zmq_ctx() -> Arc<Context> {
    let mut ctx = ZMQ_CTX.lock().unwrap();
    if ctx.strong_count() == 0 {
        let new_ctx = Arc::new(zmq::Context::new());
        *ctx = Arc::downgrade(&new_ctx);
    }
    ctx.upgrade().unwrap()
}

But this is adding an additional layer of Arcs, which shouldn't be necessary. With the PR change, we can do something like this instead:

lazy_static! {
    static ref ZMQ_CTX: Mutex<WeakContext> = Mutex::new(WeakContext::new());
}

fn zmq_ctx() -> Context {
    let mut ctx = ZMQ_CTX.lock().unwrap();
    let new_ctx = Context::new_from_weak(&ctx);
    *ctx = new_ctx.to_weak();
    new_ctx
}
peterjoel commented 4 years ago

Alternatively, we could just expose RawContext.