【问题标题】:Using iron framework, how to exit the listening loop?使用铁框架,如何退出监听循环?
【发布时间】:2015-10-13 04:40:18
【问题描述】:

我在一个需要交互查询的大型文本文件周围有一个简单的休息类皮肤。它可能涉及繁重的计算,所以我使用了 rust。我已经用铁制作了一个简单的宁静皮肤。请注意,我没有对生锈做太多事情。这只是在本地主机上运行。

pub fn query<'a>(parsed: &'a Parsed, context:&Context) -> {
  // parsed.keys is a hash containing config informtion
  // context is what I query
  let local_port = format!("{}:{}", "localhost", parsed.keys[AS_SERVER]);
  fn test_connect<'a>(r: &'a mut Request, c:&'a Context) -> IronResult<Response> {
    let url = r.url.to_string();
    let result = // some logic
    Ok(Response::with((status::Ok,  format!("requested=\"{}:{}\"\n", url, result))))
  } 
  let mut router = Router::new();
  router.get("*", move |r: &mut Request| test_connect(r, &context));
  let connection_status = Iron::new(router).http(&local_port[..]);
  connection_status.ok().expect("could not connect");
} 

现在我的问题是如何让控制权退出监听循环

Iron::new(router).http(&local_port[..]);

我只想说curl http://localhost/done

并让监听函数退出,然后进行一些日志记录,然后继续。这有可能做到这一点吗?我尝试过恐慌,但即使这样也不会退出监听循环?

我尝试返回类似Err(IronError::new(StringError(url),status::ServiceUnavailable))

status::ServiceUnavailable 只是随机的 - 它需要一些东西:我知道它在语义上不正确,不知道该使用什么。但是该错误上没有任何处理程序,因此它会默默消失。

我想我会用 aftermiddleware 设置一些东西,但我不知道是什么?

【问题讨论】:

    标签: rust iron


    【解决方案1】:

    一种方法是在处理程序和启动服务器的线程之间设置消息。消息发送时,主线程可以调用Listening::close

    在这个例子中,我使用了Condvar。我希望您也可以使用频道,但无法快速复制和粘贴示例频道并使其正常工作... ^_^

    extern crate iron;
    
    use iron::prelude::*;
    use iron::status;
    
    use std::sync::{Arc, Mutex, Condvar};
    
    fn main() {
        // Copied from docs
        let pair = Arc::new((Mutex::new(false), Condvar::new()));
        let pair2 = pair.clone();
    
        let handler = move |_: &mut Request| {
            // Copied from docs
            let &(ref lock, ref cvar) = &*pair2;
            let mut should_exit = lock.lock().unwrap();
            *should_exit = true;
            cvar.notify_one();
    
            Ok(Response::with((status::Ok, "Hello World!")))
        };
    
        // Hold onto the listener
        let mut serv = Iron::new(handler).http("localhost:3210").unwrap();
    
        println!("Now listening...");
    
        // Copied from docs
        let &(ref lock, ref cvar) = &*pair;
        let mut should_exit = lock.lock().unwrap();
        while !*should_exit {
            should_exit = cvar.wait(should_exit).unwrap();
        }
    
        serv.close().unwrap();
    
        println!("Exiting...");
    }
    

    【讨论】:

    • 谢谢!是的..这就是这样做的方法。附带说明, cvar.notify_one();使服务器响应变为空 - 它关闭而不发送最后一个响应,但这是合理的。
    【解决方案2】:

    如果所有其他方法都失败了,并且没有人可以给您更好的答案(换句话说:这应该是最后的选择):std::process::exit 应该以一种或另一种方式解决问题。请记住,这只是立即退出进程,因此根本没有进行任何清理

    【讨论】:

    • 啊,是的.. 我可以生成并分离另一个服务器实例,然后退出。这样,分离的副本最终可以在可用时绑定到健全的端口。它假设只有一个线程在查询它 - 否则它也会杀死其他所有人(理想情况下,完成已接受的请求会很好),并且加载到内存中的所有内容都会丢失。但如果没有其他可能,我会接受。
    猜你喜欢
    • 2018-01-22
    • 1970-01-01
    • 1970-01-01
    • 2020-02-19
    • 1970-01-01
    • 1970-01-01
    • 2019-01-04
    • 2017-11-03
    • 1970-01-01
    相关资源
    最近更新 更多