Glommio 'Hello World'

  • Lets try to fetch some data via HTTP

Alright, lets take this baby out for a spin!

For a simple task, we'll pull JSON temperature data from a public API and write it to a log file.

I found a weather API in this list; here's what the output looks like:

$ curl -s https://goweather.herokuapp.com/weather/baltimore | python3 -m json.tool
{
    "temperature": "+27 \u00b0C",
    "wind": "11 km/h",
    "description": "Partly cloudy",
    "forecast": [
        {
            "day": "1",
            "temperature": "+27 \u00b0C",
            "wind": "14 km/h"
        },
        {
            "day": "2",
            "temperature": "29 \u00b0C",
            "wind": "13 km/h"
        },
        {
            "day": "3",
            "temperature": "18 \u00b0C",
            "wind": "14 km/h"
        }
    ]
}

I picked Baltimore because it's kind of close to me and "washingtondc" didn't work.

I see that the unicode degrees unit symbol (°) in the payload for the "temperature" field -- does anyone want their API data formatted like that!? Please, just give mthe numbers!

To begin with, I'm going to setup a small playground crate just to kick the tires ...

$ cargo new --bin glomtastic

... begin filling in the Cargo.toml ...

[package]
name = "glomtastic"
version = "0.1.0"
edition = "2018"

[dependencies]
glommio = "0.4"

... and see what examples the fine folks at Glommio have put together for us:

Hmm. There are some promising directions, but it's going to be a bit more involved than I'm used to.

The hyper.rs example is a server, not a client. Some of the other examples are intended to demonstrate particular parts of functionality moreso than a working application.

But the docs.rs readme has some good entry points:

use glommio::{Latency, Local, LocalExecutorBuilder, Shares};

LocalExecutorBuilder::new()
    .pin_to_cpu(0)
    .spawn(|| async move {
        let tq1 = Local::create_task_queue(Shares::Static(2), Latency::NotImportant, "test1");
        let tq2 = Local::create_task_queue(Shares::Static(1), Latency::NotImportant, "test2");
        let t1 = Local::local_into(
            async move {
                // your code here
            },
            tq1,
        )
        .unwrap();
        let t2 = Local::local_into(
            async move {
                // your code here
            },
            tq2,
        )
        .unwrap();

        t1.await;
        t2.await;
    })
    .unwrap();

I have concluded this is going to be more involved than my normal routine. For one thing, I won't have my explicit loop to use, i.e.

loop {
    loop_time = Instant::now();
    if loop_time.saturating_duration_since(last.thing) { /* do it again */ }
}

...so I'll need to use a Timer instead.

Secondly, although in this proof-of-concept it doesn't actually matter, it's not clear to me at the outset how I will be integrating HTTP parsing with the arrival of new bytes. (Probably simple, but it's not obvious due to lack of familiarity).

to be continued...