Coder Social home page Coder Social logo

wasmcloud / interfaces Goto Github PK

View Code? Open in Web Editor NEW
34.0 34.0 23.0 992 KB

wasmCloud API interfaces: smithy IDLs and shared libraries

Home Page: https://wasmcloud.github.io/interfaces/

License: Apache License 2.0

Makefile 0.21% CSS 80.49% Rust 9.34% Handlebars 0.26% Go 8.16% Shell 0.01% Smithy 1.52%
api codegen idl schema smithy smithy-models

interfaces's Introduction

Documentation CNCF sandbox project Stars Powered by WebAssembly
OpenSSF Best Practices OpenSSF Scorecard Artifact Hub CLOMonitor FOSSA Status twitter youtube subscribers youtube views

wasmCloud logo

wasmCloud is a universal application platform that helps you build and run globally distributed WebAssembly applications on any cloud or edge. Our goal is to make development more joyful and efficient by giving developers the tools to write only the code that mattersβ€”and making it easy to run that code anywhere.

wasmCloud leverages WebAssembly's security, portability, and performance to compose applications from tiny, independent building blocks.These building blocks are managed declaratively and reconfigurable at runtime. You shouldn't need to recompile your whole app to upgrade a database client or patch a vulnerability and you shouldn't need to recompile anything to move your app from development to production.

wasmCloud is designed around the following core tenets:

  • Distributed from day one
  • Run anywhere and everywhere
  • Secure by default
  • Faster iteration and lower maintenance

Move from concept to production without changing your design, architecture, or your programming environment.

Getting Started

Installation

Install the wasmCloud Shell (wash) using the installation guide.

Walkthrough

If you're new to the wasmCloud ecosystem, a great place to start is the getting started walkthrough.

Quickstart

The following commands launch wasmCloud in a local development environment and deploy a simple "hello world" WebAssembly component, written in Rust, Go, TypeScript, or Python.

wash up -d
wash new component helloworld
wash build -p ./helloworld
wash app deploy ./helloworld/wadm.yaml
curl localhost:8080

Features

  1. Declarative WebAssembly Orchestration
  2. Seamless Distributed Networking
  3. Vendorless Application Components
  4. Completely OTEL Observable
  5. Defense-In-Depth Security By Default

Examples

πŸ‘Ÿ Runnable examples

wasmCloud is based on and implements WASI 0.2 (aka the Component Model). WebAssembly Components that run on wasmCloud consume interfaces defined in WIT.

Want to get something running quickly? Check out the examples directory of this repository. Examples are organized by programming language so you can easily find samples in your language of choice.

πŸ’₯ Awesome wasmCloud

For even more examples, check out awesome projects using wasmCloud from our community members!

πŸ—ΊοΈ Roadmap and Vision

We have plenty of ideas and things going on in the wasmCloud project. Please check out the Roadmap doc for more information, and the wasmCloud Roadmap project to see the status of new features.

Releases

The latest release and changelog can be found on the releases page.

πŸ§‘β€πŸ’» Contributing

Want to get involved? For more information on how to contribute and our contributor guidelines, check out the contributing readme.


πŸŒ‡ Community Resources

Community Meetings

We host weekly community meetings at 1pm EST on Wednesdays. These community meetings are livestreamed to our Twitter account and to YouTube. You can find the agenda and notes for each meeting in the community secton of our webste. If you're interested in joining in on the call to demo or take part in the discussion, we have a Zoom link on our community calendar.

Slack

We host our own community slack for all community members to join and talk about WebAssembly, wasmCloud, or just general cloud native technology. For those of you who are already on the CNCF Slack, we also have our own channel at #wasmcloud.


πŸ“š Reference Documentation

wasmCloud uses some terminology you might not be familiar with. Check out the concepts section of our docs for a deeper dive.


RPC Framework

wasmCloud uses an RPC API to enable seamless communication among the host runtime, components, and providers.


Declarative Deployments

The wasmCloud Application Deployment Manager wadm uses the Open Application Model to define and deploy application specifications.


Host Runtimes

πŸ¦€ Rust Runtime

wasmCloud's standard runtime is built in Rust for its zero-cost abstractions, safety, security, and WebAssembly support.

πŸ•Έ JavaScript Runtime (Experimental)

For running a wasmCloud host in a browser or embedding in a JavaScript V8 host, use the JavaScript Runtime


SDKs and libraries

Rust Provider SDK

wasmCloud provides an SDK for building capability providers in Rust.

Provider Archive

provider-archive is a crate used to create Provider Archive (PAR) files. PARs are used to store, retrieve, and sign capability providers. Today, capability providers are distributed as binary files and run as system processes. In the future, wasmCloud aims to build capability providers as WebAssembly Components, which will remove the need for Provider Archives.

wasmcloud_actor (Experimental)

wasmcloud_actor is a wasmCloud actor library written in Rust which facilitates building of wasmCloud components.

The API of the crate matches closely what wit-bindgen would generate, meaning that one can switch from using plain wit-bindgen-generated bindings to wasmcloud_actor (and back) with minimal or no code changes.

wascap

wascap is a low-level library used to insert and retrieve claims on components and providers. Claims are part of wasmCloud's zero-trust security model.


We are a Cloud Native Computing Foundation sandbox project.

interfaces's People

Contributors

aish-where-ya avatar autodidaddict avatar brooksmtownsend avatar connorsmith256 avatar jordan-rash avatar ktayloriii avatar lachieh avatar protochron avatar rvolosatovs avatar stevelr avatar thomastaylor312 avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar

interfaces's Issues

automate generation of docs/index.html

The index.html file is manually created but it has repeating blocks that should come from a template.

There is probably enough data in the Makefile to have Makefile generate the list of interfaces that need to be included in the index file. Makefile should have a rule to regenerate index.html.

Logging interface macros should suppress failures

Right now the logging interface macros all use ?.await (e.g. the debug!, info!, etc). This forces these macros to only be usable inside a function that returns a Result/RpcResult. Rather than enforcing this, the macros should gracefully do nothing if logging attempts fail (because, after all, what other recourse does an actor have if logging fails? It can't log the failure...).

This lets developers use these macros in functions that don't return results.

Blobstore `Chunk`s do not support borrowed data in Rust

This is a Rust only request

Right now the put_object and put_chunk functions use the Chunk object. This object requires the bytes to be an owned Vec<u8>. Because the data on incoming requests (like from an HttpRequest from wasmcloud:httpserver) isn't owned, this means that the data has to be cloned to send to the blobstore. So if someone sends a 20 MB file (just as an example), we then have to allocate another 20MB of memory in order to send things.

There are two possible solutions (both of which should be implemented IMO)

  1. This is the easier one. Make the blobstore contract support borrowed data for Chunk. This should probably be done either way
  2. This is the harder one: Most interfaces should accept owned rather than borrowed data. So for example, the httpserver contract should change from
async fn handle_request(&self, ctx: &Context, req: &HttpRequest) -> RpcResult<HttpResponse>

to

async fn handle_request(&self, ctx: &Context, req: HttpRequest) -> RpcResult<HttpResponse>

NOTE: This could be more of a https://github.com/wasmCloud/weld issue in the end as it deals with generated interface code, but I thought it would be good to start here

httpserver.HttpResponse json constructor has unwrap in it

As a code standard we don't want unwrap() anywhere unless there is documentation explaining why a panic isn't possible.
In this case, the return value from json should be a Result. If the caller believes that their data is guaranteed to serialize correctly, the caller can use unwrap().

Host inventory is outdated

Right now the host inventory structure assumes that there's only a single version of an actor on any given host. This is no longer accurate, as different instances of the same actor on the host can have varying claims, which includes name, revision, reference URI, and more.

This needs to be updated so that only the information fixed to a given actor is in the actor's high level information and all the other metadata is moved to the instances field.

10 suggestions for improving keyvalue api

The wasmcloud:keyvalue api has several inconsistencies and spots where it could be improved. These are a few opinionated suggestions.

  1. Don't have implementation-defined results

    • ListClear : may or may not delete the list
    • Range parameters may be open or closed, implementation-defined
    • The interface should be defined with clear meanings for parameters and results. The provider implementer should implement the interface spec, even if it means they have to do extra code to adapt the interface to a particular back-end.
    • If the spec is indeterminate, then a developer either won't use it, or they have to depend on a specific implementation, negating the value of a generic interface.
  2. This API is not a very generic key-value store. Many of its functions are relatively unique to Redis. A "lowest-common-denominator" type of interface would more closely model a hashmap, or a btreemap if you want sorted keys.

  3. Clear() was defined to return a String. Why not nothing?

  4. Get returns two values: (string value + boolean exists) - replace with "struct MaybeValue { value: Option }"

  5. Set and Del return a string (which is implemented to return the request key, which the caller already has). A cleaner result would be to return nothing (void), or, alternately, implement them to return Option with the previous value, if it existed

  6. List methods naming consistentency:

    • ListDel (rename from Clear and clarify that it deletes the list after removing items),
    • ListItemAdd (rename from Push),
    • ListItemDel (rename from ListItemDelete)
    • ListiItemExists (new, parallel to KeyExists)
  7. Set methods naming consistency: SetDel, SetItemAdd, SetItemDel, SetItemExists, parallel to List methods

  8. Range improvements:

    • rename existing Range to ListItemRange
    • add range query for values: KeyRange (return range of keys), ValueRange (return range of KV pairs). For both KeyRange and ValueRange, rage start/end should be strings.
  9. All values (including list and set items) should be type blob .(non-empty array of bytes), so keyvalue can store arbitrary data, not String, which is limited to utf-8.

  10. All range queries should use pagination

Remove async from Rust wasm32 interfaces

Part of the value proposition of the actor model, and by extension wasmCloud, is that actors are all internally synchronous. They are single-threaded and developers don't have to worry about writing asynchronous code. Unfortunately, because Rust makes it a little too easy to compile certain things inside wasm32, it was pretty easy to make the generated code produce async stuff that can be used by either side of the provider/actor exchange.

What I'd like to see is that anything that an actor might use from the generated output be purely synchronous without any use of the async keyword. It should still be possible to allow the capability providers to utilize an async version of the trait with conditional compilation.

I suspect that in the absence of async, the process of building actors will be simpler, faster, and easier to learn for newer Rust developers. Further, I also suspect that without having to compile a single-threaded executor like tokio into the wasm module will reduce the overall actor size as well.

[BUG] Log macros require an async function that returns RpcResult<()>

For example, here's a normal usage of the log macros

#[async_trait]
impl HttpServer for LogtestActor {
    async fn handle_request(
        &self,
        ctx: &Context,
        req: &HttpRequest,
    ) -> std::result::Result<HttpResponse, RpcError> {
        let text = form_urlencoded::parse(req.query_string.as_bytes())
            .find(|(n, _)| n == "name")
            .map(|(_, v)| v.to_string())
            .unwrap_or_else(|| "World".to_string());

        wasmcloud_interface_logging::info!("Neat! works fine"); /// <- here

        Ok(HttpResponse {
            body: format!("Hello {}", text).as_bytes().to_vec(),
            ..Default::default()
        })
    }
}

This works fine as expected, but as actors get larger it's usually desirable to split functionality off into helper functions. So when one tries to do this they get:

error[E0728]: `await` is only allowed inside `async` functions and blocks
  --> src/lib.rs:46:5
   |
45 | fn foo() {
   |    --- this is not `async`
46 |     info!("hey, why doesn't this work?");
   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ only allowed inside `async` functions and blocks
   |
   = note: this error originates in the macro `info` (in Nightly builds, run with -Z macro-backtrace for more info)

Then when they try to make it async:

error[E0277]: the `?` operator can only be used in an async function that returns `Result` or `Option` (or another type that implements `FromResidual`)
  --> src/lib.rs:50:5
   |
49 |   async fn bar() {
   |  ________________-
50 | |     info!("Woah, no compile?");
   | |     ^^^^^^^^^^^^^^^^^^^^^^^^^^ cannot use the `?` operator in an async function that returns `()`
51 | | }
   | |_- this function should return `Result` or `Option` to accept `?`
   |
   = help: the trait `FromResidual<Result<Infallible, wasmbus_rpc::error::RpcError>>` is not implemented for `()`
   = note: this error originates in the macro `info` (in Nightly builds, run with -Z macro-backtrace for more info)

And then, if they forget async and do end up returning an RpcResult

error[E0728]: `await` is only allowed inside `async` functions and blocks
  --> src/lib.rs:54:5
   |
53 | fn baz() -> RpcResult<()> {
   |    --- this is not `async`
54 |     info!("Woah, not here either?");
   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ only allowed inside `async` functions and blocks
   |
   = note: this error originates in the macro `info` (in Nightly builds, run with -Z macro-backtrace for more info)

If they have their own result type that doesn't have an implementation from the error type to wasmbus_rpc::error::Error, then the error shows as well (@mattgilbride ran into this)

This is mostly to provide a few examples where developers are commonly going to hit errors trying to log outside of the actor handlers itself. The following bit of code helps, but requires constructing a Struct and passing ctx around.

        let log_sender = LoggingSender::new();
        log_sender
            .write_log(
                ctx,
                &LogEntry {
                    level: "info".to_string(),
                    text: "my text".to_string(),
                },
            )
            .await?;

Ideally, log macros should be able to be called from synchronous contexts that don't return results (a sync, void macro)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    πŸ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. πŸ“ŠπŸ“ˆπŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❀️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.