Somewhat working routeguide
This commit is contained in:
@@ -26,6 +26,9 @@ tokio = "=0.2.0-alpha.1"
|
||||
prost = "0.5"
|
||||
prost-derive = "0.5"
|
||||
bytes = "0.4"
|
||||
serde_json = "1.0"
|
||||
serde = { version = "1.0", features = ["derive"] }
|
||||
async-stream = "0.1"
|
||||
|
||||
[build-dependencies]
|
||||
tonic-build = { path = "../tonic-build" }
|
||||
|
||||
@@ -0,0 +1,702 @@
|
||||
[
|
||||
{
|
||||
"location": {
|
||||
"latitude": 407838351,
|
||||
"longitude": -746143763
|
||||
},
|
||||
"name": "Patriots Path, Mendham, NJ 07945, USA"
|
||||
},
|
||||
{
|
||||
"location": {
|
||||
"latitude": 408122808,
|
||||
"longitude": -743999179
|
||||
},
|
||||
"name": "101 New Jersey 10, Whippany, NJ 07981, USA"
|
||||
},
|
||||
{
|
||||
"location": {
|
||||
"latitude": 413628156,
|
||||
"longitude": -749015468
|
||||
},
|
||||
"name": "U.S. 6, Shohola, PA 18458, USA"
|
||||
},
|
||||
{
|
||||
"location": {
|
||||
"latitude": 419999544,
|
||||
"longitude": -740371136
|
||||
},
|
||||
"name": "5 Conners Road, Kingston, NY 12401, USA"
|
||||
},
|
||||
{
|
||||
"location": {
|
||||
"latitude": 414008389,
|
||||
"longitude": -743951297
|
||||
},
|
||||
"name": "Mid Hudson Psychiatric Center, New Hampton, NY 10958, USA"
|
||||
},
|
||||
{
|
||||
"location": {
|
||||
"latitude": 419611318,
|
||||
"longitude": -746524769
|
||||
},
|
||||
"name": "287 Flugertown Road, Livingston Manor, NY 12758, USA"
|
||||
},
|
||||
{
|
||||
"location": {
|
||||
"latitude": 406109563,
|
||||
"longitude": -742186778
|
||||
},
|
||||
"name": "4001 Tremley Point Road, Linden, NJ 07036, USA"
|
||||
},
|
||||
{
|
||||
"location": {
|
||||
"latitude": 416802456,
|
||||
"longitude": -742370183
|
||||
},
|
||||
"name": "352 South Mountain Road, Wallkill, NY 12589, USA"
|
||||
},
|
||||
{
|
||||
"location": {
|
||||
"latitude": 412950425,
|
||||
"longitude": -741077389
|
||||
},
|
||||
"name": "Bailey Turn Road, Harriman, NY 10926, USA"
|
||||
},
|
||||
{
|
||||
"location": {
|
||||
"latitude": 412144655,
|
||||
"longitude": -743949739
|
||||
},
|
||||
"name": "193-199 Wawayanda Road, Hewitt, NJ 07421, USA"
|
||||
},
|
||||
{
|
||||
"location": {
|
||||
"latitude": 415736605,
|
||||
"longitude": -742847522
|
||||
},
|
||||
"name": "406-496 Ward Avenue, Pine Bush, NY 12566, USA"
|
||||
},
|
||||
{
|
||||
"location": {
|
||||
"latitude": 413843930,
|
||||
"longitude": -740501726
|
||||
},
|
||||
"name": "162 Merrill Road, Highland Mills, NY 10930, USA"
|
||||
},
|
||||
{
|
||||
"location": {
|
||||
"latitude": 410873075,
|
||||
"longitude": -744459023
|
||||
},
|
||||
"name": "Clinton Road, West Milford, NJ 07480, USA"
|
||||
},
|
||||
{
|
||||
"location": {
|
||||
"latitude": 412346009,
|
||||
"longitude": -744026814
|
||||
},
|
||||
"name": "16 Old Brook Lane, Warwick, NY 10990, USA"
|
||||
},
|
||||
{
|
||||
"location": {
|
||||
"latitude": 402948455,
|
||||
"longitude": -747903913
|
||||
},
|
||||
"name": "3 Drake Lane, Pennington, NJ 08534, USA"
|
||||
},
|
||||
{
|
||||
"location": {
|
||||
"latitude": 406337092,
|
||||
"longitude": -740122226
|
||||
},
|
||||
"name": "6324 8th Avenue, Brooklyn, NY 11220, USA"
|
||||
},
|
||||
{
|
||||
"location": {
|
||||
"latitude": 406421967,
|
||||
"longitude": -747727624
|
||||
},
|
||||
"name": "1 Merck Access Road, Whitehouse Station, NJ 08889, USA"
|
||||
},
|
||||
{
|
||||
"location": {
|
||||
"latitude": 416318082,
|
||||
"longitude": -749677716
|
||||
},
|
||||
"name": "78-98 Schalck Road, Narrowsburg, NY 12764, USA"
|
||||
},
|
||||
{
|
||||
"location": {
|
||||
"latitude": 415301720,
|
||||
"longitude": -748416257
|
||||
},
|
||||
"name": "282 Lakeview Drive Road, Highland Lake, NY 12743, USA"
|
||||
},
|
||||
{
|
||||
"location": {
|
||||
"latitude": 402647019,
|
||||
"longitude": -747071791
|
||||
},
|
||||
"name": "330 Evelyn Avenue, Hamilton Township, NJ 08619, USA"
|
||||
},
|
||||
{
|
||||
"location": {
|
||||
"latitude": 412567807,
|
||||
"longitude": -741058078
|
||||
},
|
||||
"name": "New York State Reference Route 987E, Southfields, NY 10975, USA"
|
||||
},
|
||||
{
|
||||
"location": {
|
||||
"latitude": 416855156,
|
||||
"longitude": -744420597
|
||||
},
|
||||
"name": "103-271 Tempaloni Road, Ellenville, NY 12428, USA"
|
||||
},
|
||||
{
|
||||
"location": {
|
||||
"latitude": 404663628,
|
||||
"longitude": -744820157
|
||||
},
|
||||
"name": "1300 Airport Road, North Brunswick Township, NJ 08902, USA"
|
||||
},
|
||||
{
|
||||
"location": {
|
||||
"latitude": 407113723,
|
||||
"longitude": -749746483
|
||||
},
|
||||
"name": ""
|
||||
},
|
||||
{
|
||||
"location": {
|
||||
"latitude": 402133926,
|
||||
"longitude": -743613249
|
||||
},
|
||||
"name": ""
|
||||
},
|
||||
{
|
||||
"location": {
|
||||
"latitude": 400273442,
|
||||
"longitude": -741220915
|
||||
},
|
||||
"name": ""
|
||||
},
|
||||
{
|
||||
"location": {
|
||||
"latitude": 411236786,
|
||||
"longitude": -744070769
|
||||
},
|
||||
"name": ""
|
||||
},
|
||||
{
|
||||
"location": {
|
||||
"latitude": 411633782,
|
||||
"longitude": -746784970
|
||||
},
|
||||
"name": "211-225 Plains Road, Augusta, NJ 07822, USA"
|
||||
},
|
||||
{
|
||||
"location": {
|
||||
"latitude": 415830701,
|
||||
"longitude": -742952812
|
||||
},
|
||||
"name": ""
|
||||
},
|
||||
{
|
||||
"location": {
|
||||
"latitude": 413447164,
|
||||
"longitude": -748712898
|
||||
},
|
||||
"name": "165 Pedersen Ridge Road, Milford, PA 18337, USA"
|
||||
},
|
||||
{
|
||||
"location": {
|
||||
"latitude": 405047245,
|
||||
"longitude": -749800722
|
||||
},
|
||||
"name": "100-122 Locktown Road, Frenchtown, NJ 08825, USA"
|
||||
},
|
||||
{
|
||||
"location": {
|
||||
"latitude": 418858923,
|
||||
"longitude": -746156790
|
||||
},
|
||||
"name": ""
|
||||
},
|
||||
{
|
||||
"location": {
|
||||
"latitude": 417951888,
|
||||
"longitude": -748484944
|
||||
},
|
||||
"name": "650-652 Willi Hill Road, Swan Lake, NY 12783, USA"
|
||||
},
|
||||
{
|
||||
"location": {
|
||||
"latitude": 407033786,
|
||||
"longitude": -743977337
|
||||
},
|
||||
"name": "26 East 3rd Street, New Providence, NJ 07974, USA"
|
||||
},
|
||||
{
|
||||
"location": {
|
||||
"latitude": 417548014,
|
||||
"longitude": -740075041
|
||||
},
|
||||
"name": ""
|
||||
},
|
||||
{
|
||||
"location": {
|
||||
"latitude": 410395868,
|
||||
"longitude": -744972325
|
||||
},
|
||||
"name": ""
|
||||
},
|
||||
{
|
||||
"location": {
|
||||
"latitude": 404615353,
|
||||
"longitude": -745129803
|
||||
},
|
||||
"name": ""
|
||||
},
|
||||
{
|
||||
"location": {
|
||||
"latitude": 406589790,
|
||||
"longitude": -743560121
|
||||
},
|
||||
"name": "611 Lawrence Avenue, Westfield, NJ 07090, USA"
|
||||
},
|
||||
{
|
||||
"location": {
|
||||
"latitude": 414653148,
|
||||
"longitude": -740477477
|
||||
},
|
||||
"name": "18 Lannis Avenue, New Windsor, NY 12553, USA"
|
||||
},
|
||||
{
|
||||
"location": {
|
||||
"latitude": 405957808,
|
||||
"longitude": -743255336
|
||||
},
|
||||
"name": "82-104 Amherst Avenue, Colonia, NJ 07067, USA"
|
||||
},
|
||||
{
|
||||
"location": {
|
||||
"latitude": 411733589,
|
||||
"longitude": -741648093
|
||||
},
|
||||
"name": "170 Seven Lakes Drive, Sloatsburg, NY 10974, USA"
|
||||
},
|
||||
{
|
||||
"location": {
|
||||
"latitude": 412676291,
|
||||
"longitude": -742606606
|
||||
},
|
||||
"name": "1270 Lakes Road, Monroe, NY 10950, USA"
|
||||
},
|
||||
{
|
||||
"location": {
|
||||
"latitude": 409224445,
|
||||
"longitude": -748286738
|
||||
},
|
||||
"name": "509-535 Alphano Road, Great Meadows, NJ 07838, USA"
|
||||
},
|
||||
{
|
||||
"location": {
|
||||
"latitude": 406523420,
|
||||
"longitude": -742135517
|
||||
},
|
||||
"name": "652 Garden Street, Elizabeth, NJ 07202, USA"
|
||||
},
|
||||
{
|
||||
"location": {
|
||||
"latitude": 401827388,
|
||||
"longitude": -740294537
|
||||
},
|
||||
"name": "349 Sea Spray Court, Neptune City, NJ 07753, USA"
|
||||
},
|
||||
{
|
||||
"location": {
|
||||
"latitude": 410564152,
|
||||
"longitude": -743685054
|
||||
},
|
||||
"name": "13-17 Stanley Street, West Milford, NJ 07480, USA"
|
||||
},
|
||||
{
|
||||
"location": {
|
||||
"latitude": 408472324,
|
||||
"longitude": -740726046
|
||||
},
|
||||
"name": "47 Industrial Avenue, Teterboro, NJ 07608, USA"
|
||||
},
|
||||
{
|
||||
"location": {
|
||||
"latitude": 412452168,
|
||||
"longitude": -740214052
|
||||
},
|
||||
"name": "5 White Oak Lane, Stony Point, NY 10980, USA"
|
||||
},
|
||||
{
|
||||
"location": {
|
||||
"latitude": 409146138,
|
||||
"longitude": -746188906
|
||||
},
|
||||
"name": "Berkshire Valley Management Area Trail, Jefferson, NJ, USA"
|
||||
},
|
||||
{
|
||||
"location": {
|
||||
"latitude": 404701380,
|
||||
"longitude": -744781745
|
||||
},
|
||||
"name": "1007 Jersey Avenue, New Brunswick, NJ 08901, USA"
|
||||
},
|
||||
{
|
||||
"location": {
|
||||
"latitude": 409642566,
|
||||
"longitude": -746017679
|
||||
},
|
||||
"name": "6 East Emerald Isle Drive, Lake Hopatcong, NJ 07849, USA"
|
||||
},
|
||||
{
|
||||
"location": {
|
||||
"latitude": 408031728,
|
||||
"longitude": -748645385
|
||||
},
|
||||
"name": "1358-1474 New Jersey 57, Port Murray, NJ 07865, USA"
|
||||
},
|
||||
{
|
||||
"location": {
|
||||
"latitude": 413700272,
|
||||
"longitude": -742135189
|
||||
},
|
||||
"name": "367 Prospect Road, Chester, NY 10918, USA"
|
||||
},
|
||||
{
|
||||
"location": {
|
||||
"latitude": 404310607,
|
||||
"longitude": -740282632
|
||||
},
|
||||
"name": "10 Simon Lake Drive, Atlantic Highlands, NJ 07716, USA"
|
||||
},
|
||||
{
|
||||
"location": {
|
||||
"latitude": 409319800,
|
||||
"longitude": -746201391
|
||||
},
|
||||
"name": "11 Ward Street, Mount Arlington, NJ 07856, USA"
|
||||
},
|
||||
{
|
||||
"location": {
|
||||
"latitude": 406685311,
|
||||
"longitude": -742108603
|
||||
},
|
||||
"name": "300-398 Jefferson Avenue, Elizabeth, NJ 07201, USA"
|
||||
},
|
||||
{
|
||||
"location": {
|
||||
"latitude": 419018117,
|
||||
"longitude": -749142781
|
||||
},
|
||||
"name": "43 Dreher Road, Roscoe, NY 12776, USA"
|
||||
},
|
||||
{
|
||||
"location": {
|
||||
"latitude": 412856162,
|
||||
"longitude": -745148837
|
||||
},
|
||||
"name": "Swan Street, Pine Island, NY 10969, USA"
|
||||
},
|
||||
{
|
||||
"location": {
|
||||
"latitude": 416560744,
|
||||
"longitude": -746721964
|
||||
},
|
||||
"name": "66 Pleasantview Avenue, Monticello, NY 12701, USA"
|
||||
},
|
||||
{
|
||||
"location": {
|
||||
"latitude": 405314270,
|
||||
"longitude": -749836354
|
||||
},
|
||||
"name": ""
|
||||
},
|
||||
{
|
||||
"location": {
|
||||
"latitude": 414219548,
|
||||
"longitude": -743327440
|
||||
},
|
||||
"name": ""
|
||||
},
|
||||
{
|
||||
"location": {
|
||||
"latitude": 415534177,
|
||||
"longitude": -742900616
|
||||
},
|
||||
"name": "565 Winding Hills Road, Montgomery, NY 12549, USA"
|
||||
},
|
||||
{
|
||||
"location": {
|
||||
"latitude": 406898530,
|
||||
"longitude": -749127080
|
||||
},
|
||||
"name": "231 Rocky Run Road, Glen Gardner, NJ 08826, USA"
|
||||
},
|
||||
{
|
||||
"location": {
|
||||
"latitude": 407586880,
|
||||
"longitude": -741670168
|
||||
},
|
||||
"name": "100 Mount Pleasant Avenue, Newark, NJ 07104, USA"
|
||||
},
|
||||
{
|
||||
"location": {
|
||||
"latitude": 400106455,
|
||||
"longitude": -742870190
|
||||
},
|
||||
"name": "517-521 Huntington Drive, Manchester Township, NJ 08759, USA"
|
||||
},
|
||||
{
|
||||
"location": {
|
||||
"latitude": 400066188,
|
||||
"longitude": -746793294
|
||||
},
|
||||
"name": ""
|
||||
},
|
||||
{
|
||||
"location": {
|
||||
"latitude": 418803880,
|
||||
"longitude": -744102673
|
||||
},
|
||||
"name": "40 Mountain Road, Napanoch, NY 12458, USA"
|
||||
},
|
||||
{
|
||||
"location": {
|
||||
"latitude": 414204288,
|
||||
"longitude": -747895140
|
||||
},
|
||||
"name": ""
|
||||
},
|
||||
{
|
||||
"location": {
|
||||
"latitude": 414777405,
|
||||
"longitude": -740615601
|
||||
},
|
||||
"name": ""
|
||||
},
|
||||
{
|
||||
"location": {
|
||||
"latitude": 415464475,
|
||||
"longitude": -747175374
|
||||
},
|
||||
"name": "48 North Road, Forestburgh, NY 12777, USA"
|
||||
},
|
||||
{
|
||||
"location": {
|
||||
"latitude": 404062378,
|
||||
"longitude": -746376177
|
||||
},
|
||||
"name": ""
|
||||
},
|
||||
{
|
||||
"location": {
|
||||
"latitude": 405688272,
|
||||
"longitude": -749285130
|
||||
},
|
||||
"name": ""
|
||||
},
|
||||
{
|
||||
"location": {
|
||||
"latitude": 400342070,
|
||||
"longitude": -748788996
|
||||
},
|
||||
"name": ""
|
||||
},
|
||||
{
|
||||
"location": {
|
||||
"latitude": 401809022,
|
||||
"longitude": -744157964
|
||||
},
|
||||
"name": ""
|
||||
},
|
||||
{
|
||||
"location": {
|
||||
"latitude": 404226644,
|
||||
"longitude": -740517141
|
||||
},
|
||||
"name": "9 Thompson Avenue, Leonardo, NJ 07737, USA"
|
||||
},
|
||||
{
|
||||
"location": {
|
||||
"latitude": 410322033,
|
||||
"longitude": -747871659
|
||||
},
|
||||
"name": ""
|
||||
},
|
||||
{
|
||||
"location": {
|
||||
"latitude": 407100674,
|
||||
"longitude": -747742727
|
||||
},
|
||||
"name": ""
|
||||
},
|
||||
{
|
||||
"location": {
|
||||
"latitude": 418811433,
|
||||
"longitude": -741718005
|
||||
},
|
||||
"name": "213 Bush Road, Stone Ridge, NY 12484, USA"
|
||||
},
|
||||
{
|
||||
"location": {
|
||||
"latitude": 415034302,
|
||||
"longitude": -743850945
|
||||
},
|
||||
"name": ""
|
||||
},
|
||||
{
|
||||
"location": {
|
||||
"latitude": 411349992,
|
||||
"longitude": -743694161
|
||||
},
|
||||
"name": ""
|
||||
},
|
||||
{
|
||||
"location": {
|
||||
"latitude": 404839914,
|
||||
"longitude": -744759616
|
||||
},
|
||||
"name": "1-17 Bergen Court, New Brunswick, NJ 08901, USA"
|
||||
},
|
||||
{
|
||||
"location": {
|
||||
"latitude": 414638017,
|
||||
"longitude": -745957854
|
||||
},
|
||||
"name": "35 Oakland Valley Road, Cuddebackville, NY 12729, USA"
|
||||
},
|
||||
{
|
||||
"location": {
|
||||
"latitude": 412127800,
|
||||
"longitude": -740173578
|
||||
},
|
||||
"name": ""
|
||||
},
|
||||
{
|
||||
"location": {
|
||||
"latitude": 401263460,
|
||||
"longitude": -747964303
|
||||
},
|
||||
"name": ""
|
||||
},
|
||||
{
|
||||
"location": {
|
||||
"latitude": 412843391,
|
||||
"longitude": -749086026
|
||||
},
|
||||
"name": ""
|
||||
},
|
||||
{
|
||||
"location": {
|
||||
"latitude": 418512773,
|
||||
"longitude": -743067823
|
||||
},
|
||||
"name": ""
|
||||
},
|
||||
{
|
||||
"location": {
|
||||
"latitude": 404318328,
|
||||
"longitude": -740835638
|
||||
},
|
||||
"name": "42-102 Main Street, Belford, NJ 07718, USA"
|
||||
},
|
||||
{
|
||||
"location": {
|
||||
"latitude": 419020746,
|
||||
"longitude": -741172328
|
||||
},
|
||||
"name": ""
|
||||
},
|
||||
{
|
||||
"location": {
|
||||
"latitude": 404080723,
|
||||
"longitude": -746119569
|
||||
},
|
||||
"name": ""
|
||||
},
|
||||
{
|
||||
"location": {
|
||||
"latitude": 401012643,
|
||||
"longitude": -744035134
|
||||
},
|
||||
"name": ""
|
||||
},
|
||||
{
|
||||
"location": {
|
||||
"latitude": 404306372,
|
||||
"longitude": -741079661
|
||||
},
|
||||
"name": ""
|
||||
},
|
||||
{
|
||||
"location": {
|
||||
"latitude": 403966326,
|
||||
"longitude": -748519297
|
||||
},
|
||||
"name": ""
|
||||
},
|
||||
{
|
||||
"location": {
|
||||
"latitude": 405002031,
|
||||
"longitude": -748407866
|
||||
},
|
||||
"name": ""
|
||||
},
|
||||
{
|
||||
"location": {
|
||||
"latitude": 409532885,
|
||||
"longitude": -742200683
|
||||
},
|
||||
"name": ""
|
||||
},
|
||||
{
|
||||
"location": {
|
||||
"latitude": 416851321,
|
||||
"longitude": -742674555
|
||||
},
|
||||
"name": ""
|
||||
},
|
||||
{
|
||||
"location": {
|
||||
"latitude": 406411633,
|
||||
"longitude": -741722051
|
||||
},
|
||||
"name": "3387 Richmond Terrace, Staten Island, NY 10303, USA"
|
||||
},
|
||||
{
|
||||
"location": {
|
||||
"latitude": 413069058,
|
||||
"longitude": -744597778
|
||||
},
|
||||
"name": "261 Van Sickle Road, Goshen, NY 10924, USA"
|
||||
},
|
||||
{
|
||||
"location": {
|
||||
"latitude": 418465462,
|
||||
"longitude": -746859398
|
||||
},
|
||||
"name": ""
|
||||
},
|
||||
{
|
||||
"location": {
|
||||
"latitude": 411733222,
|
||||
"longitude": -744228360
|
||||
},
|
||||
"name": ""
|
||||
},
|
||||
{
|
||||
"location": {
|
||||
"latitude": 410248224,
|
||||
"longitude": -747127767
|
||||
},
|
||||
"name": "3 Hasta Way, Newton, NJ 07860, USA"
|
||||
}
|
||||
]
|
||||
@@ -0,0 +1,39 @@
|
||||
use serde::Deserialize;
|
||||
use std::fs::File;
|
||||
use std::io::prelude::*;
|
||||
|
||||
#[derive(Debug, Deserialize)]
|
||||
struct Feature {
|
||||
location: Location,
|
||||
name: String,
|
||||
}
|
||||
|
||||
#[derive(Debug, Deserialize)]
|
||||
struct Location {
|
||||
latitude: i32,
|
||||
longitude: i32,
|
||||
}
|
||||
|
||||
#[allow(dead_code)]
|
||||
pub fn load() -> Vec<crate::routeguide::Feature> {
|
||||
let mut file = File::open("tonic-examples/data/route_guide_db.json")
|
||||
.ok()
|
||||
.expect("failed to open data file");
|
||||
let mut data = String::new();
|
||||
file.read_to_string(&mut data)
|
||||
.ok()
|
||||
.expect("failed to read data file");
|
||||
|
||||
let decoded: Vec<Feature> = serde_json::from_str(&data).unwrap();
|
||||
|
||||
decoded
|
||||
.into_iter()
|
||||
.map(|feature| crate::routeguide::Feature {
|
||||
name: feature.name,
|
||||
location: Some(crate::routeguide::Point {
|
||||
longitude: feature.location.longitude,
|
||||
latitude: feature.location.latitude,
|
||||
}),
|
||||
})
|
||||
.collect()
|
||||
}
|
||||
@@ -1,57 +1,170 @@
|
||||
#![feature(async_await)]
|
||||
|
||||
use futures::Stream;
|
||||
use tokio::net::TcpListener;
|
||||
mod data;
|
||||
|
||||
use futures::{Stream, StreamExt};
|
||||
use tokio::{net::TcpListener, sync::{mpsc, Lock}};
|
||||
use tonic::{Request, Response, Status};
|
||||
use tower_h2::Server;
|
||||
use std::sync::Arc;
|
||||
use std::collections::HashMap;
|
||||
use std::hash::{Hash, Hasher};
|
||||
use std::time::Instant;
|
||||
|
||||
pub mod routeguide {
|
||||
include!(concat!(env!("OUT_DIR"), "/routeguide.rs"));
|
||||
}
|
||||
|
||||
use routeguide::*;
|
||||
use routeguide::{Point, Rectangle, Feature, RouteNote, RouteSummary};
|
||||
|
||||
type BoxStream<T> = Pin<Box<dyn Stream<Item = Result<T, Status>> + Send + 'static>>;
|
||||
|
||||
#[derive(Default, Clone)]
|
||||
#[derive(Debug)]
|
||||
pub struct RouteGuide {
|
||||
data: String,
|
||||
state: State,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
struct State {
|
||||
features: Arc<Vec<Feature>>,
|
||||
notes: Lock<HashMap<Point, Vec<RouteNote>>>,
|
||||
}
|
||||
|
||||
#[tonic::server(service = "routeguide.RouteGuide", proto = "routeguide")]
|
||||
impl RouteGuide {
|
||||
pub async fn get_feature(&self, _req: Request<Point>) -> Result<Response<Feature>, Status> {
|
||||
unimplemented!()
|
||||
pub async fn get_feature(&self, request: Request<Point>) -> Result<Response<Feature>, Status> {
|
||||
println!("GetFeature = {:?}", request);
|
||||
|
||||
for feature in &self.state.features[..] {
|
||||
if feature.location.as_ref() == Some(request.get_ref()) {
|
||||
return Ok(Response::new(feature.clone()));
|
||||
}
|
||||
}
|
||||
|
||||
let response = Response::new(Feature {
|
||||
name: "".to_string(),
|
||||
location: None,
|
||||
});
|
||||
|
||||
Ok(response)
|
||||
}
|
||||
|
||||
pub async fn list_features(
|
||||
&self,
|
||||
_req: Request<Rectangle>,
|
||||
) -> Result<Response<BoxStream<Feature>>, Status> {
|
||||
unimplemented!()
|
||||
request: Request<Rectangle>,
|
||||
) -> Result<Response<mpsc::Receiver<Result<Feature, Status>>>, Status> {
|
||||
use std::thread;
|
||||
|
||||
println!("ListFeatures = {:?}", request);
|
||||
|
||||
let (mut tx, rx) = mpsc::channel(4);
|
||||
|
||||
let state = self.state.clone();
|
||||
|
||||
thread::spawn(move || {
|
||||
for feature in &state.features[..] {
|
||||
if in_range(feature.location.as_ref().unwrap(), request.get_ref()) {
|
||||
println!(" => send {:?}", feature);
|
||||
tx.try_send(Ok(feature.clone())).unwrap();
|
||||
}
|
||||
}
|
||||
|
||||
println!(" /// done sending");
|
||||
});
|
||||
|
||||
|
||||
Ok(Response::new(rx))
|
||||
}
|
||||
|
||||
pub async fn record_route(
|
||||
&self,
|
||||
_req: Request<impl Stream<Item = Result<Point, Status>>>,
|
||||
) -> Result<Response<RouteSummary>, Status> {
|
||||
unimplemented!()
|
||||
request: Request<impl Stream<Item = Result<Point, Status>>>,
|
||||
) -> Result<Response<RouteSummary>, Status>
|
||||
{
|
||||
println!("RecordRoute");
|
||||
|
||||
let stream = request.into_inner();
|
||||
|
||||
// Pin the inbound stream to the stack so that we can call next on it
|
||||
futures::pin_mut!(stream);
|
||||
|
||||
let mut summary = RouteSummary::default();
|
||||
let mut last_point = None;
|
||||
let now = Instant::now();
|
||||
|
||||
while let Some(point) = stream.next().await {
|
||||
let point = point?;
|
||||
|
||||
println!(" ==> Point = {:?}", point);
|
||||
|
||||
// Increment the point count
|
||||
summary.point_count += 1;
|
||||
|
||||
// Find features
|
||||
for feature in &self.state.features[..] {
|
||||
if feature.location.as_ref() == Some(&point) {
|
||||
summary.feature_count += 1;
|
||||
}
|
||||
}
|
||||
|
||||
// Calculate the distance
|
||||
if let Some(ref last_point) = last_point {
|
||||
summary.distance += calc_distance(last_point, &point);
|
||||
}
|
||||
|
||||
last_point = Some(point);
|
||||
}
|
||||
|
||||
summary.elapsed_time = now.elapsed().as_secs() as i32;
|
||||
|
||||
Ok(Response::new(summary))
|
||||
}
|
||||
|
||||
// pub async fn route_chat(
|
||||
// &self,
|
||||
// _req: Request<impl Stream<Item = Result<RouteNote, Status>>>,
|
||||
// ) -> Result<Response<impl Stream<Item = Result<RouteNote, Status>>>, Status> {
|
||||
// unimplemented!()
|
||||
// }
|
||||
pub async fn route_chat(
|
||||
&self,
|
||||
request: Request<impl Stream<Item = Result<RouteNote, Status>> + Send + 'static>,
|
||||
) -> Result<Response<impl Stream<Item = Result<RouteNote, Status>> + Send>, Status> {
|
||||
println!("RouteChat");
|
||||
|
||||
let stream = request.into_inner();
|
||||
let mut state = self.state.clone();
|
||||
|
||||
|
||||
|
||||
let output = async_stream::try_stream! {
|
||||
futures::pin_mut!(stream);
|
||||
|
||||
while let Some(note) = stream.next().await {
|
||||
let note = note?;
|
||||
|
||||
let location = note.location.clone().unwrap();
|
||||
|
||||
let mut notes = state.notes.lock().await;
|
||||
let notes = notes.entry(location).or_insert(vec![]);
|
||||
notes.push(note);
|
||||
|
||||
for note in notes {
|
||||
yield note.clone();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
Ok(Response::new(output))
|
||||
}
|
||||
}
|
||||
|
||||
#[tokio::main]
|
||||
async fn main() -> Result<(), Box<dyn std::error::Error>> {
|
||||
let addr = "[::1]:50051".parse().unwrap();
|
||||
let addr = "[::1]:10000".parse().unwrap();
|
||||
let mut bind = TcpListener::bind(&addr)?;
|
||||
|
||||
let route_guide = RouteGuide::default();
|
||||
println!("Listening on: {}", bind.local_addr()?);
|
||||
|
||||
let route_guide = RouteGuide {
|
||||
state: State {
|
||||
// Load data file
|
||||
features: Arc::new(data::load()),
|
||||
notes: Lock::new(HashMap::new()),
|
||||
},
|
||||
};
|
||||
let mut server = Server::new(RouteGuideServer::new(route_guide), Default::default());
|
||||
|
||||
while let Ok((sock, _addr)) = bind.accept().await {
|
||||
@@ -66,3 +179,58 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
// Implement hash for Point
|
||||
impl Hash for Point {
|
||||
fn hash<H>(&self, state: &mut H)
|
||||
where
|
||||
H: Hasher,
|
||||
{
|
||||
self.latitude.hash(state);
|
||||
self.longitude.hash(state);
|
||||
}
|
||||
}
|
||||
|
||||
impl Eq for Point {}
|
||||
|
||||
fn in_range(point: &Point, rect: &Rectangle) -> bool {
|
||||
use std::cmp;
|
||||
|
||||
let lo = rect.lo.as_ref().unwrap();
|
||||
let hi = rect.hi.as_ref().unwrap();
|
||||
|
||||
let left = cmp::min(lo.longitude, hi.longitude);
|
||||
let right = cmp::max(lo.longitude, hi.longitude);
|
||||
let top = cmp::max(lo.latitude, hi.latitude);
|
||||
let bottom = cmp::min(lo.latitude, hi.latitude);
|
||||
|
||||
point.longitude >= left
|
||||
&& point.longitude <= right
|
||||
&& point.latitude >= bottom
|
||||
&& point.latitude <= top
|
||||
}
|
||||
|
||||
/// Calculates the distance between two points using the "haversine" formula.
|
||||
/// This code was taken from http://www.movable-type.co.uk/scripts/latlong.html.
|
||||
fn calc_distance(p1: &Point, p2: &Point) -> i32 {
|
||||
const CORD_FACTOR: f64 = 1e7;
|
||||
const R: f64 = 6371000.0; // meters
|
||||
|
||||
let lat1 = p1.latitude as f64 / CORD_FACTOR;
|
||||
let lat2 = p2.latitude as f64 / CORD_FACTOR;
|
||||
let lng1 = p1.longitude as f64 / CORD_FACTOR;
|
||||
let lng2 = p2.longitude as f64 / CORD_FACTOR;
|
||||
|
||||
let lat_rad1 = lat1.to_radians();
|
||||
let lat_rad2 = lat2.to_radians();
|
||||
|
||||
let delta_lat = (lat2 - lat1).to_radians();
|
||||
let delta_lng = (lng2 - lng1).to_radians();
|
||||
|
||||
let a = (delta_lat / 2f64).sin() * (delta_lat / 2f64).sin()
|
||||
+ (lat_rad1).cos() * (lat_rad2).cos() * (delta_lng / 2f64).sin() * (delta_lng / 2f64).sin();
|
||||
|
||||
let c = 2f64 * a.sqrt().atan2((1f64 - a).sqrt());
|
||||
|
||||
(R * c) as i32
|
||||
}
|
||||
|
||||
+64
-11
@@ -148,7 +148,12 @@ fn generate_methods(service: &ServiceDef) -> TokenStream {
|
||||
&service.proto_path,
|
||||
),
|
||||
|
||||
_ => unimplemented!("method type"),
|
||||
(true, true) => generate_streaming(
|
||||
method,
|
||||
ident.clone(),
|
||||
service.name.clone(),
|
||||
&service.proto_path,
|
||||
),
|
||||
};
|
||||
|
||||
let method = quote! {
|
||||
@@ -228,7 +233,10 @@ fn generate_server_streaming(
|
||||
fn call(&mut self, request: tonic::Request<#request>) -> Self::Future {
|
||||
let inner = self.0.clone();
|
||||
let fut = async move {
|
||||
inner.#method_ident(request).await
|
||||
inner.#method_ident(request)
|
||||
.await
|
||||
.map(|r|
|
||||
r.map(|s| Box::pin(s) as Pin<Box<dyn Stream<Item = Result<Self::Response, Status>> + Send>>))
|
||||
|
||||
};
|
||||
Box::pin(fut)
|
||||
@@ -260,10 +268,8 @@ fn generate_client_streaming(
|
||||
let response: Path =
|
||||
syn::parse_str(&format!("{}::{}", proto_path, method.output_type)).unwrap();
|
||||
|
||||
// TODO: parse response stream type, if it is a concrete type then use that
|
||||
// as the ResponseStream type, if it is a impl Trait then we need to box.
|
||||
quote! {
|
||||
struct #service_ident ;//(pub std::sync::Arc<#service_impl>);
|
||||
struct #service_ident(pub std::sync::Arc<#service_impl>);
|
||||
|
||||
impl<S> tonic::server::ClientStreamingService<S> for #service_ident
|
||||
where S: Stream<Item = Result<#request, Status>> + Unpin + Send + 'static {
|
||||
@@ -271,13 +277,12 @@ fn generate_client_streaming(
|
||||
type Future = BoxFuture<tonic::Response<Self::Response>, tonic::Status>;
|
||||
|
||||
fn call(&mut self, request: tonic::Request<S>) -> Self::Future {
|
||||
// let inner = self.0.clone();
|
||||
// let fut = async move {
|
||||
// inner.#method_ident(request).await
|
||||
let inner = self.0.clone();
|
||||
let fut = async move {
|
||||
inner.#method_ident(request).await
|
||||
|
||||
// };
|
||||
// Box::pin(fut)
|
||||
unimplemented!()
|
||||
};
|
||||
Box::pin(fut)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -293,3 +298,51 @@ fn generate_client_streaming(
|
||||
Box::pin(fut)
|
||||
}
|
||||
}
|
||||
|
||||
fn generate_streaming(
|
||||
method: &Method,
|
||||
method_ident: Ident,
|
||||
service_impl: Path,
|
||||
proto_path: &str,
|
||||
) -> TokenStream {
|
||||
let service_ident = Ident::new(&method.proto_name, Span::call_site());
|
||||
|
||||
let request: Path = syn::parse_str(&format!("{}::{}", proto_path, method.input_type)).unwrap();
|
||||
let response: Path =
|
||||
syn::parse_str(&format!("{}::{}", proto_path, method.output_type)).unwrap();
|
||||
|
||||
// TODO: parse response stream type, if it is a concrete type then use that
|
||||
// as the ResponseStream type, if it is a impl Trait then we need to box.
|
||||
quote! {
|
||||
struct #service_ident(pub std::sync::Arc<#service_impl>);
|
||||
|
||||
impl<S> tonic::server::StreamingService<S> for #service_ident
|
||||
where S: Stream<Item = Result<#request, Status>> + Unpin + Send + 'static {
|
||||
type Response = #response;
|
||||
type ResponseStream = Pin<Box<dyn Stream<Item = Result<Self::Response, Status>> + Send>>;
|
||||
type Future = BoxFuture<tonic::Response<Self::ResponseStream>, tonic::Status>;
|
||||
|
||||
fn call(&mut self, request: tonic::Request<S>) -> Self::Future {
|
||||
let inner = self.0.clone();
|
||||
let fut = async move {
|
||||
inner.#method_ident(request).await
|
||||
.map(|r|
|
||||
r.map(|s| Box::pin(s) as Pin<Box<dyn Stream<Item = Result<Self::Response, Status>> + Send>>))
|
||||
|
||||
};
|
||||
Box::pin(fut)
|
||||
}
|
||||
}
|
||||
|
||||
let inner = self.inner.clone();
|
||||
let fut = async move {
|
||||
let method = #service_ident(inner);
|
||||
let codec = tonic::codec::ProstCodec::new();
|
||||
let mut grpc = tonic::server::Grpc::new(codec);
|
||||
let res = grpc.streaming(method, req).await;
|
||||
Ok(res)
|
||||
};
|
||||
|
||||
Box::pin(fut)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,6 +6,7 @@ use futures_util::{future, StreamExt};
|
||||
use http_body::Body;
|
||||
use prost::Message;
|
||||
use std::marker::PhantomData;
|
||||
use std::pin::Pin;
|
||||
use tokio_codec::{Decoder, Encoder};
|
||||
use tracing::{debug, trace};
|
||||
|
||||
@@ -22,6 +23,26 @@ pub trait Codec {
|
||||
fn decoder(&mut self) -> Self::Decoder;
|
||||
}
|
||||
|
||||
pub struct Streaming<T> {
|
||||
inner: Pin<Box<dyn Stream<Item = Result<T, Status>> + Send + 'static>>,
|
||||
}
|
||||
|
||||
impl<T> Streaming<T> {
|
||||
pub fn new(inner: impl Stream<Item = Result<T, Status>> + Send + 'static) -> Self {
|
||||
let inner = Box::pin(inner);
|
||||
Self { inner }
|
||||
}
|
||||
}
|
||||
|
||||
use std::task::{Context, Poll};
|
||||
impl<T> Stream for Streaming<T> {
|
||||
type Item = Result<T, Status>;
|
||||
|
||||
fn poll_next(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Option<Self::Item>> {
|
||||
Pin::new(&mut self.inner).poll_next(cx)
|
||||
}
|
||||
}
|
||||
|
||||
pub fn encode<T, U>(mut encoder: T, mut source: U) -> impl TryStream<Ok = BytesBuf, Error = Status>
|
||||
where
|
||||
T: Encoder<Error = Status>,
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
use crate::{
|
||||
body::{BoxAsyncBody, BytesBuf},
|
||||
codec::{decode, encode, Codec},
|
||||
codec::{decode, encode, Codec, Streaming},
|
||||
server::{ClientStreamingService, ServerStreamingService, StreamingService, UnaryService},
|
||||
Code, Request, Response, Status,
|
||||
};
|
||||
use futures_core::{Stream, TryStream};
|
||||
use futures_util::{future, stream, StreamExt, TryStreamExt};
|
||||
use futures_util::{future, stream, TryStreamExt};
|
||||
use http_body::Body;
|
||||
use std::pin::Pin;
|
||||
|
||||
@@ -83,18 +83,19 @@ where
|
||||
self.map_response(response).map(BoxAsyncBody::new_try)
|
||||
}
|
||||
|
||||
//BoxStream<T::Decode>,
|
||||
pub async fn client_streaming<S, B>(
|
||||
&mut self,
|
||||
mut service: S,
|
||||
req: http::Request<B>,
|
||||
) -> http::Response<BoxAsyncBody>
|
||||
where
|
||||
S: ClientStreamingService<BoxStream<T::Decode>, Response = T::Encode>,
|
||||
T::Decode: Send,
|
||||
S: ClientStreamingService<Streaming<T::Decode>, Response = T::Encode>,
|
||||
T::Decode: Send + 'static,
|
||||
T::Decoder: Send + 'static,
|
||||
B: Body + Send + 'static,
|
||||
B::Data: Send,
|
||||
B::Error: Into<crate::Error> + Send,
|
||||
B::Data: Send + 'static,
|
||||
B::Error: Into<crate::Error> + Send + 'static,
|
||||
{
|
||||
let request = self.map_request_streaming(req);
|
||||
let response = service
|
||||
@@ -110,7 +111,7 @@ where
|
||||
req: http::Request<B>,
|
||||
) -> http::Response<BoxAsyncBody>
|
||||
where
|
||||
S: StreamingService<BoxStream<T::Decode>, Response = T::Encode> + Send,
|
||||
S: StreamingService<Streaming<T::Decode>, Response = T::Encode> + Send,
|
||||
S::ResponseStream: Send + 'static,
|
||||
B: Body + Send + 'static,
|
||||
B::Data: Send,
|
||||
@@ -146,7 +147,7 @@ where
|
||||
fn map_request_streaming<B>(
|
||||
&mut self,
|
||||
request: http::Request<B>,
|
||||
) -> Request<BoxStream<T::Decode>>
|
||||
) -> Request<Streaming<T::Decode>>
|
||||
where
|
||||
B: Body + Send + 'static,
|
||||
B::Data: Send,
|
||||
@@ -154,7 +155,7 @@ where
|
||||
{
|
||||
Request::from_http(
|
||||
request.map(|b| {
|
||||
decode(self.codec.decoder(), b).into_stream().boxed() as BoxStream<T::Decode>
|
||||
Streaming::new(decode(self.codec.decoder(), b).into_stream())
|
||||
}),
|
||||
)
|
||||
}
|
||||
|
||||
@@ -0,0 +1,139 @@
|
||||
#![feature(async_await, type_alias_impl_trait)]
|
||||
|
||||
use futures_util::future;
|
||||
use futures_core::Stream;
|
||||
use std::pin::Pin;
|
||||
use std::future::Future;
|
||||
use std::task::{Context, Poll};
|
||||
use tokio::net::TcpListener;
|
||||
use tonic::{
|
||||
body,
|
||||
server::{Grpc, UnaryService, ClientStreamingService},
|
||||
Request, Response, Status,
|
||||
};
|
||||
use tower_h2::{RecvBody, Server};
|
||||
use tower_service::Service;
|
||||
|
||||
#[derive(Clone, PartialEq, prost::Message)]
|
||||
pub struct HelloRequest {
|
||||
#[prost(string, tag = "1")]
|
||||
pub name: std::string::String,
|
||||
}
|
||||
/// The response message containing the greetings
|
||||
#[derive(Clone, PartialEq, prost::Message)]
|
||||
pub struct HelloReply {
|
||||
#[prost(string, tag = "1")]
|
||||
pub message: std::string::String,
|
||||
}
|
||||
|
||||
struct SayHello;
|
||||
|
||||
impl UnaryService<HelloRequest> for SayHello {
|
||||
type Response = HelloReply;
|
||||
type Future = impl Future<Output = Result<Response<Self::Response>, Status>>;
|
||||
|
||||
fn call(&mut self, request: Request<HelloRequest>) -> Self::Future {
|
||||
async move {
|
||||
println!("REQUEST = {:?}", request);
|
||||
|
||||
let reply = HelloReply {
|
||||
message: "Zomg, it works!".to_string(),
|
||||
};
|
||||
|
||||
Ok(Response::new(reply))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
struct SayHelloStream;
|
||||
|
||||
impl<S> ClientStreamingService<S> for SayHelloStream
|
||||
where S: Stream<Item = Result<HelloRequest, Status>> + Unpin + Send + 'static {
|
||||
type Response = HelloReply;
|
||||
// type Future = impl Future<Output = Result<Response<Self::Response>, Status>>;
|
||||
type Future = Pin<Box<dyn Future<Output = Result<Response<Self::Response>, Status>> + Send + 'static>>;
|
||||
|
||||
fn call(&mut self, _req: Request<S>) -> Self::Future {
|
||||
let fut = async move {
|
||||
Ok(Response::new(HelloReply { message: "hello".into()}))
|
||||
};
|
||||
Box::pin(fut)
|
||||
}
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn main() {
|
||||
let addr = "[::1]:50051".parse().unwrap();
|
||||
let mut bind = TcpListener::bind(&addr).unwrap();
|
||||
|
||||
let mut server = Server::new(MakeSvc, Default::default());
|
||||
|
||||
while let Ok((sock, _addr)) = bind.accept().await {
|
||||
if let Err(e) = sock.set_nodelay(true) {
|
||||
panic!("error: {}", e);
|
||||
}
|
||||
|
||||
if let Err(e) = server.serve(sock).await {
|
||||
println!("H2 ERROR: {}", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct Svc;
|
||||
|
||||
impl Service<http::Request<RecvBody>> for Svc {
|
||||
type Response = http::Response<body::BoxAsyncBody>;
|
||||
type Error = tonic::error::Never;
|
||||
// type Future = impl Future<Output = Result<Self::Response, Self::Error>>;
|
||||
type Future = Pin<Box<dyn Future<Output = Result<Self::Response, Self::Error>>>>;
|
||||
|
||||
fn poll_ready(&mut self, _cx: &mut Context<'_>) -> Poll<Result<(), Self::Error>> {
|
||||
Ok(()).into()
|
||||
}
|
||||
|
||||
fn call(&mut self, req: http::Request<RecvBody>) -> Self::Future {
|
||||
match req.uri().path() {
|
||||
"/greeter.Helloworld/SayHello" => {
|
||||
let fut = async move {
|
||||
let codec = tonic::codec::ProstCodec::new();
|
||||
let mut grpc = Grpc::new(codec);
|
||||
let response = grpc.unary(SayHello, req).await;
|
||||
Ok(response)
|
||||
};
|
||||
|
||||
Box::pin(fut)
|
||||
}
|
||||
|
||||
"/greeter.Helloworld/SayHelloStreaming" => {
|
||||
let fut = async move {
|
||||
let codec = tonic::codec::ProstCodec::new();
|
||||
let mut grpc = Grpc::new(codec);
|
||||
let response = grpc.client_streaming(SayHelloStream, req).await;
|
||||
Ok(response)
|
||||
};
|
||||
|
||||
Box::pin(fut)
|
||||
}
|
||||
|
||||
_ => unimplemented!()
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
pub struct MakeSvc;
|
||||
|
||||
impl Service<()> for MakeSvc {
|
||||
type Response = Svc;
|
||||
type Error = std::io::Error;
|
||||
type Future = future::Ready<Result<Self::Response, Self::Error>>;
|
||||
|
||||
fn poll_ready(&mut self, _cx: &mut Context<'_>) -> Poll<Result<(), Self::Error>> {
|
||||
Ok(()).into()
|
||||
}
|
||||
|
||||
fn call(&mut self, _: ()) -> Self::Future {
|
||||
future::ok(Svc)
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user