19 releases

Uses old Rust 2015

0.9.2 Jun 25, 2018
0.9.1 Jan 15, 2018
0.9.0 Dec 12, 2017
0.8.2 Oct 27, 2017
0.1.0 Jul 14, 2015

#6 in #locator

MIT license

130KB
2.5K SLoC

Build Status Build status Documentation


lib.rs:

Roadmap:

  • Unicorn wrapper.
  • Send headers.
  • Notify about send events completion.
  • Infinite buffer growing protection.
  • Implement local_addr and peer_addr for Service.
  • Generic multiplexer over the socket type, allowing to work with both TCP and Unix sockets.
  • Receiving headers.
  • HPACK encoder.
  • HPACK decoder.

This framework provides a client-side API for the Cocaine Cloud platform.

There is a concept of services that represent universal cloud resource, which can be accessed using frameworks. These are: Locator, Storage, Unicorn, App and much more.

Examples

The following example demonstrates how to save a BLOB using Storage service.

use cocaine::{Core, Service};
use cocaine::service::Storage;

let mut core = Core::new().unwrap();
let storage = Storage::new(Service::new("storage", &core.handle()));

let future = storage.write("collection", "key", "le message".as_bytes(), &[]);

core.run(future).unwrap();

The framework is fully asynchronous, widely using tokio and futures for communicating with remote services. An example above represents a high-level API, but also does the data copy, which is unnecessary in some cases. However this can be completely avoided by using Dispatch trait in conjunction with Service object, because dispatch objects are called directly from the socket thread, where the data lays in completely zero-copy manner.

extern crate cocaine;
extern crate futures;

use std::mem;
use futures::sync::oneshot::{self, Sender};
use cocaine::{Core, Dispatch, Error, Response, Request, Service};
use cocaine::protocol::{Flatten, Primitive};

struct ReadDispatch {
    completion: Sender<()>,
}

impl Dispatch for ReadDispatch {
    fn process(self: Box<Self>, response: &Response) -> Option<Box<Dispatch>> {
        let data = response.deserialize::<Primitive<&str>>().flatten();

        println!("Data: {:?}", data);

        mem::drop(self.completion);
        None
    }
    fn discard(self: Box<Self>, err: &Error) {
        println!("Error: {}", err);
        mem::drop(self.completion);
    }
}

fn main() {
    let mut core = Core::new().unwrap();
    let service = Service::new("storage", &core.handle());
    let (tx, rx) = oneshot::channel();
    service.call(Request::new(0, &("collection", "key")).unwrap(), ReadDispatch { completion: tx });

    core.run(rx).unwrap();
}

Modules

There are both low-level API defined in the root module and more high-level API located in the service module.

Requirements

  • Rust nightly, because it widely uses currently unstable impl Trait feature.

Dependencies

~8MB
~130K SLoC