Xudong-Huang / may

rust stackful coroutine library

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

why this post request in go! didn't work

coolit opened this issue · comments

#[macro_use]
extern crate may;
use may::coroutine;
use may::coroutine::yield_now;
use reqwest;
use reqwest::header::*;
use std::{
    collections::HashMap,
    error::Error,
    fs, process, str,
    sync::{Arc, Mutex},
    thread,
    time::Duration,
};

fn construct_headers() -> HeaderMap {
    let mut headers = HeaderMap::new();
    headers.insert(USER_AGENT, HeaderValue::from_static("reqwest"));
    headers.insert(CONTENT_TYPE, HeaderValue::from_static("hello"));
    headers
}

fn gen_client() -> my_client {
    let client = Arc::new(reqwest::Client::new());
    client
}

type my_client = Arc<reqwest::Client>;

fn main() {
    let client = gen_client();

    let client_one = client.clone();
    let h = go!(move || {
        println!("hi, I'm parent");
        let client_outer = client_one.clone();
        let v = (0..3)
            .map(|i| {
                coroutine::sleep(Duration::from_millis(1));
                println!("---{:?}", 12);
                let client_inner = client_outer.clone();

                go!(move || {
                    println!("---{:?}", 15);
                    match i {
                        0 => {
                            println!("hi, I'm child{:?}", 0);
                            let res = req(client_inner);
                            println!("{:?}", res);
                            yield_now();
                            println!("bye from child{:?}", 0);
                        }
                        1 => {
                            println!("hi, I'm child{:?}", 1);
                            let res = req(client_inner);
                            println!("{:?}", res);
                            yield_now();
                            println!("bye from child{:?}", 1);
                        }
                        2 => {
                            println!("hi, I'm child{:?}", 2);
                            let res = req(client_inner);
                            println!("{:?}", res);
                            yield_now();
                            println!("bye from child{:?}", 2);
                        }
                        _ => {}
                    }
                })
            })
            .collect::<Vec<_>>();
        yield_now();
        // wait child finish
        for i in v {
            i.join().unwrap();
        }
        println!("bye from parent");
    });
    h.join().unwrap();
}

fn req(client: my_client) -> String {
    let res = client
        .post("http://httpbin.org/post")
        .headers(construct_headers())
        .body("hello")
        .send()
        .unwrap()
        .text()
        .unwrap();
    res
}

Could you please add the syntax highlighting to your code? Something like this:

```rust
bla-bla-bla
```

Could you please add the syntax highlighting to your code? Something like this:

bla-bla-bla

thanks

Apparently you don't get enough stack size. the coroutine has a very limit stack size by default and it's guard page protected.

From debugger you could see the info

[Switching to Thread 0x7ffff566a700 (LWP 32106)]
0x00005555561cc703 in **__rust_probestack** () at /cargo/registry/src/github.com-1ecc6299db9ec823/compiler_builtins-0.1.18/src/probestack.rs:55
55      /cargo/registry/src/github.com-1ecc6299db9ec823/compiler_builtins-0.1.18/src/probestack.rs: No such file or directory.
(gdb) bt
#0  0x00005555561cc703 in __rust_probestack () at /cargo/registry/src/github.com-1ecc6299db9ec823/compiler_builtins-0.1.18/src/probestack.rs:55
#1  0x0000000000000000 in ?? ()

reqwest crate internally use a bigger stack. And note that debug and release version has different stack usage.

just add the following config at the beginning of you main file should work.

may::config().set_stack_size(0x10000);

output is

    Finished dev [unoptimized + debuginfo] target(s) in 52.98s
     Running `target/debug/examples/req`
hi, I'm parent
---12
---15
hi, I'm child0
---12
---15
hi, I'm child1
---12
---15
hi, I'm child2
"{\n  \"args\": {}, \n  \"data\": \"hello\", \n  \"files\": {}, \n  \"form\": {}, \n  \"headers\": {\n    \"Accept\": \"*/*\", \n    \"Accept-Encoding\": \"gzip\", \n    \"Content-Length\": \"5\", \n    \"Content-Type\": \"hello\", \n    \"Host\": \"httpbin.org\", \n    \"User-Agent\": \"reqwest\"\n  }, \n  \"json\": null, \n  \"origin\": \"123.114.177.145, 123.114.177.145\", \n  \"url\": \"https://httpbin.org/post\"\n}\n"
bye from child2
"{\n  \"args\": {}, \n  \"data\": \"hello\", \n  \"files\": {}, \n  \"form\": {}, \n  \"headers\": {\n    \"Accept\": \"*/*\", \n    \"Accept-Encoding\": \"gzip\", \n    \"Content-Length\": \"5\", \n    \"Content-Type\": \"hello\", \n    \"Host\": \"httpbin.org\", \n    \"User-Agent\": \"reqwest\"\n  }, \n  \"json\": null, \n  \"origin\": \"123.114.177.145, 123.114.177.145\", \n  \"url\": \"https://httpbin.org/post\"\n}\n"
bye from child1
"{\n  \"args\": {}, \n  \"data\": \"hello\", \n  \"files\": {}, \n  \"form\": {}, \n  \"headers\": {\n    \"Accept\": \"*/*\", \n    \"Accept-Encoding\": \"gzip\", \n    \"Content-Length\": \"5\", \n    \"Content-Type\": \"hello\", \n    \"Host\": \"httpbin.org\", \n    \"User-Agent\": \"reqwest\"\n  }, \n  \"json\": null, \n  \"origin\": \"123.114.177.145, 123.114.177.145\", \n  \"url\": \"https://httpbin.org/post\"\n}\n"
bye from child0
bye from parent

Thank you.