Giter Club home page Giter Club logo

rust-sdk's Introduction

Dapr SDK for Rust (Alpha)

Crates.io Build Status discord License: Apache 2.0 FOSSA Status

Dapr is a portable, event-driven, serverless runtime for building distributed applications across cloud and edge.

Alpha

This SDK is currently in Alpha. Work is underway to bring forward a stable release and will likely involve breaking changes.

  • Documentation is incomplete.
  • Not all building blocks are currently implemented.
  • There may be bugs.
  • The SDK does not have complete test coverage.

The maintainers commit to resolving any issues that arise and bringing this SDK to a stable release. With this in mind, the SDK will follow the norms and conventions of a stable SDK so far as is possible.

This SDK will be accounted for as a part of the release process. Support for the latest runtime release is targeted but not guaranteed.

The main tenet of development will be stability and functionality that improves resiliency.

Prerequisites

Ensure you have Rust version 1.78 or higher installed. If not, install Rust here.

You will also need to install protoc.

How to use

Add the following to your Cargo.toml file:

[dependencies]
dapr = "0.15.0"

Here's a basic example to create a client:

use dapr;

#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
    // Get the Dapr port and create a connection
    let port: u16 = std::env::var("DAPR_GRPC_PORT")?.parse()?;
    let addr = format!("https://127.0.0.1:{}", port);

    // Create the client
    let mut client = dapr::Client::<dapr::client::TonicClient>::connect(addr).await?;
}

Explore more examples

Browse through more examples to understand the SDK better: View examples

Building

To build the SDK run:

cargo build

Note: The protobuf client generation is built into cargo build process so updating the proto files under dapr/ is enough to update the protobuf client.

Developing (Updating .proto files from upstream Dapr)

To fetch the latest .proto files from Dapr execute the script update-protos.sh:

./update-protos.sh

By default, the script fetches the latest proto updates from the master branch of the Dapr repository. If you need to choose a specific release or version, use the -v flag:

./update-protos.sh -v v1.14.0

Protos can then be compiled using:

cargo run proto-gen

Contact Us

Reach out with any questions you may have and we'll be sure to answer them as soon as possible!

Discord Banner

rust-sdk's People

Contributors

aaroncrawfis avatar amanbha avatar artursouza avatar blackwood-ra avatar calebcartwright avatar cscetbon avatar danielgerlag avatar deepanshua avatar dmitsh avatar dwhiteddsoft avatar elena-kolevska avatar franpog859 avatar gdhuper avatar hauju avatar hugome avatar joshvanl avatar marcduiker avatar mikeee avatar nicklarsennz avatar pkedy avatar pruthvidhodda avatar robertojrojas avatar rumblefrog avatar rylev avatar t-eckert avatar tcnghia avatar wcs1only avatar yaron2 avatar youngbupark avatar zedgell 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  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  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  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

rust-sdk's Issues

Fixing dependencies with bad license

Main issue: dapr/dapr#4236

Please refer to the parent issue to help with fixing existing issues with bad licenses.

This is required for Dapr to be compliant with CNCF guidelines, so please add this issue to the SDK planning accordingly.

[Release Enhancement] GHA Workflows to Update Versions Automatically

It would be nice to have an automated process that listens for a new tag to be pushed to the dapr/dapr repo && dapr/cli that updates the version accordingly so we are always up to date on changes and can automate our release candidate testing. This should be automated to minimize the manual steps in the release process.

I propose adding a GitHub Action Workflow to dapr/rust-sdk that listens for a new tag on the dapr/dapr repo && dapr/cli and auto creates a Pull Request that updates that accordingly. Example updates. Protos will need to be updated/automated with this

Note: Use the DAPR_BOT secret

Handle the logic to retry until grpc port is assigned to daprd

Right now we have to introduce some delay in clients so that a grpc port is assigned to daprd before the client tries to make a connection. The logic to handle this issue needs to be handled in the sdk instead.

Logs for this issue when delay is not introduced in client:

$ dapr run --app-id=rustapp --grpc-port 3500 cargo run -- --example client
ℹ️  Starting Dapr with id rustapp. HTTP Port: 38035. gRPC Port: 3500

== APP == Error: TransportError

Clarify "WIP" Status

Hey there.

I considered starting work on a Dapr SDK, but was positively surprised to see an official one already in the works.

Could you update the README with some information on the current state of this project?
As in: why is it WIP, what is supported, what isn't yet, etc.

failed to build dapr v0.5.0 in rust-1.53.0-nightly

error: failed to run custom build command for dapr v0.5.0

Caused by:
process didn't exit successfully:

error: the 'rustfmt' component which provides the command 'rustfmt' is not available for the 'nightly-x86_64-unknown-linux-gnu' toolchain

Proposal: Querying state store

The state query API is an existing API that is currently in the alpha stage. The Rust SDK does not currently support this.

Since the API already exists, we do not need to make any changes to the state query API. I propose that we can add a new function called query_state_alpha1() inside the Client struct, which is consistent with the other SDKs. It will use the existing proto message QueryStateRequest and QueryStateResponse.

Given that this API is in still in Alpha, I'm not sure if it makes sense to add this to the main crate or to create some kind of experimental/preview that contains all of the APIs that are in alpha stage.

Misleading comment in the Invoke example

Looks like it was copy/pasted from the pubsub example.

Topic A Is not returned here, only the default (which is an empty list, given Vec is Default over T):

/// Lists all topics subscribed by this app.
///
/// NOTE: Dapr runtime will call this method to get
/// the list of topics the app wants to subscribe to.
/// In this example, the app is subscribing to topic `A`.
async fn list_topic_subscriptions(
&self,
_request: Request<()>,
) -> Result<Response<ListTopicSubscriptionsResponse>, Status> {
let list_subscriptions = ListTopicSubscriptionsResponse::default();
Ok(Response::new(list_subscriptions))
}

Perhaps it should read something like:

/// Return an empty list of topics. 

... but on that note, should the trait methods provide these default behaviours so we don't have to implement defaults for each unused method?

Using invoke for HTTP endpoints not possible yet?

I am trying to call some HTTP methods between 2 microservices set up using DAPR and I can't seem to figure out the way? Is it not possible yet? Glancing through the protobuf source and the generated code seems to indicate that the support is there? But the invoke method doesn't provide any customization point to call using HTTP and defaults GRPC.

Sorry if this is silly, I only have basic knowledge of protobuf.

Add Pubsub example

This is the create pubsub sample.

  • Add appcallback.proto
  • Implement AppCallback server for subscription
  • Create Publish sample
  • Add README

Need to update the Contributing guide to be rust specific

This is specific to Go:

rust-sdk/CONTRIBUTING.md

Lines 110 to 119 in 6500db4

### Use of Third-party code
- All third-party code must be placed in the `vendor/` folder.
- `vendor/` folder is managed by Go modules and stores the source code of third-party Go dependencies. - The `vendor/` folder should not be modified manually.
- Third-party code must include licenses.
A non-exclusive list of code that must be places in `vendor/`:
- Open source, free software, or commercially-licensed code.
- Tools or libraries or protocols that are open source, free software, or commercially licensed.

There is currently no vendoring done in this SDK, but here is some information about vendoring with Cargo.

build: add PR template

The Dapr Rust SDK repo should have a PR template for when end users create PRs contributing to the project.

Describe the solution you'd like
We should abide by a standardized PR template across all SDK repositories.

To implement, we should add a pull_request_template.md file. Something similar to what we have in dapr/dapr (https://github.com/dapr/dapr/blob/master/.github/pull_request_template.md), but also considering if we need special additions for SDK specific repositories. See Java SDK repo PR template for additional inspiration: https://github.com/dapr/java-sdk/blob/master/.github/pull_request_template.md

Additional context
This will help to improve contributors to easily communicate their changes, as well as maintainers to easily understand what the PR is doing.

Tracking: API / Building block implementations

Building blocks:

  • 🟢 Service invocation
    • Implementation
    • Docs #126
    • Validation/Example(s)
  • 🟠 State management
    • Implementation TBA
    • Docs #126
    • Refactor/Add Methods TBA
    • Validation/Example(s)
    • Query #115
  • 🟠 PubSub messaging
    • Implementation
    • Docs #126
    • Macro(s) #87
    • Bulk Pub/Sub TBA
    • Validation/Example(s)
  • 🟠 Bindings
    • Implementation TBA
    • Docs TBA
    • Macro(s) TBA
    • Validation/Example(s)
  • 🟠 Actors
    • Implementation #99
    • Docs TBA
    • Macro(s)
    • Add missing client methods TBA
    • Validation/Example(s)
  • 🟠 Secrets management 🟠
    • Implementation
    • Docs TBA
    • Bulk secret retrieval method #122
    • Validation/Example(s)
  • 🟠 Configuration 🟠
    • Implementation TBA
    • Docs TBA
    • Validation/Example(s)
  • 🔴 Distributed lock
    • Implementation #86
    • Docs TBA
    • Validation/Example(s) TBA
  • 🔴 Workflow
    • Implementation #142
    • Docs TBA
    • Validation/Example(s) TBA
  • 🟠 Cryptography
    • Implementation #133
    • Docs TBA
    • Validation/Example(s) #133
  • 🟠 Metadata
    • Implementation
    • Docs TBA
    • Validation/Example(s) TBA
  • 🟠Jobs
    • Implementation
    • Docs
    • Validation/Examples

Add some more testing

PR #99 has some tests, which prompted me to look for existing test cases as a baseline and I noticed there weren't any.

I think it would be worth adding in some additional tests for the existing SDK code.

Publisher/subscriber example does not work

Steps:
1- I opened a DAPR app on a given grpc port. The console shows that the Dapr is up and running.
2- Start the subscriber example in the elevated mode, and set the port to the sane one that Dapr is running at. The server will start fine. I noticed that it won't run in debug mode as it will not run in the elevated mode
3- Start the subscriber example. It will run fine. However, subscribers are not triggered upon publish events.

Expected Results:
Subscribers must be triggered upon publish events

Additional Notes
The client example works fine, which indicates that the Dapr at least is operating as expected.

Operating System:
Windows 11

Add Ability For Users to Self-Assign Issues

It would be nice if a user could self assign issues to themselves and have parity with other dapr repos where they may self assign issues.

Steps
That entails having a dapr_bot.js file, like this one from dapr/dapr but simplified with only the ability to run /assign. See here for example on how to have the /assign command. This would entail needing the appropriate dapr-bot.yml file, but with the appropriate changes based on it being a different repository with different maintainers. Please ask in discord or on the PR to find out who the appropriate maintainers are.

Also, please update the the daprbot documentation in dapr/docs noting that this repo now has the /assign command available.

As a final step, please link to the daprbot documentation inside the contributing.md file so that users know what commands they can run in this repo.

inspiration for simple implementation can be found here

Example of a service call

Hi,
I have looked through out the code but there doesnt seem to be any example of an invoke_service call. Am stuck on the data parameter Option<Any>. How do we pass a struct here with the necessary data. Are there any tests or docs that show example usage?

Use Client in an async fashion

I simply want to create a client and pass it to a number of threads to do a publish_event (just looking at throughput). No matter how I try to move, clone, copy Client into another thread, it fails in various ways. Any thoughts on how to accomplish? Here is some example code you can beat up:

    // Create the client
    let mut client = dapr::Client::<dapr::client::TonicClient>::connect(addr).await.unwrap();
    let foo = std::sync::Arc::new(client);
    for x in 0..10 {
        let cli = foo.clone();
        tokio::spawn(async move {
            println!("In spawn");
            let mut metadata = HashMap::<String, String>::new();
            metadata.insert("count".to_string(), x.to_string());
            cli
                .publish_event(
                    "pubsub".to_string(),
                    "A".to_string(),
                    "text/plain".to_string(),
                    format!("{} => hello from rust!", &x).into_bytes(),
                    Some(metadata),
                )
                .await;
        });
    }

Pass metadata into get_configuration and subscribe_configuration

Currently, there is no metadata argument for the client methods get_configuration and subscribe_configuration. Passing metadata is required when subscribing to config store changes with PostgreSQL.

To reproduce, use the following configstore.yaml component with a configured local instance of PostgreSQL running:

apiVersion: dapr.io/v1alpha1
kind: Component
metadata:
  name: configstore
spec:
  type: configuration.postgresql
  version: v1
  metadata:
    - name: connectionString
      value: host=localhost user=postgres password=[pg_password] port=5432 connect_timeout=10 database=[database_name]
    - name: table
      value: "config_table"

Without including metadata in the subscribe_configuration, an "Invalid Argument" Err is returned with the following message:

failed to subscribe [key] from Configuration store configstore: unable to subscribe to 'config_table'. pgNotifyChannel attribute cannot be empty

Client should implement Clone

Currently the signature of the publish_event method of the client is:

    pub async fn publish_event<S>(
        &mut self,
        ...
    ) -> Result<(), Error>

This requires Ownership of the client for every event we emit. This is an extreme and unusual harsh restriction if we comprare the client for example to a MongoDB or other database clients. Is this really neccessary?

In a typical Scenario we will have mutliple sources for events (maybe just the same object multiple times). Due to rust Ownership rules, each object would need it's own client. Alternatively we could work with a central service that get's data via a threadsafe Stream. However even then the central service would be hard to implement due to the required ownership.

It would be much nicer if we could use such methods on a borrowed client instead. This would allow us to simply pass references to one client to all the places that need it.

Is there some dapr specific motivation for this strict implementation?
I guess the question is: What do we need to modify on the client side when sending an event?

This issue might be related:
#52

Rust type information is hidden by include_proto!

I'm trying to work out how to add multiple subscriptions, and in my quest I am digging through types in vscode, for example:

/// ListTopicSubscriptionsResponse is the message including the list of the subscribing topics.
pub type ListTopicSubscriptionsResponse = dapr_v1::ListTopicSubscriptionsResponse;

When I Command+Click on the right hand ListTopicSubscriptionsResponse, I am taken here:

rust-sdk/src/dapr.rs

Lines 1 to 14 in 6500db4

pub mod dapr {
pub mod proto {
pub mod common {
pub mod v1 {
tonic::include_proto!("dapr.proto.common.v1");
}
}
pub mod runtime {
pub mod v1 {
tonic::include_proto!("dapr.proto.runtime.v1");
}
}
}
}

Is there a way to get useful type information? Maybe the code generation can be done without the include_proto! macro?

build: add issue template

The Dapr Rust SDK repo should have an issues template for when end users create issues when working with the project.

Describe the solution you'd like
We should abide by a standardized issue template across all SDK repositories.

To implement, we should add a ISSUE_TEMPLATE directory similar to that of:
https://github.com/dapr/java-sdk/tree/master/.github/ISSUE_TEMPLATE
https://github.com/dapr/python-sdk/tree/master/.github/ISSUE_TEMPLATE

Additional context
This will help to improve contributors to easily communicate their issues, as well as maintainers to easily understand what the issue at hand is.

Unable to add multiple subscriptions

There is currently no way to add additional subscriptions. ListTopicSubscriptionResponse::topic(...) is hard coded to a vector of one subscription: https://docs.rs/dapr/0.9.0/src/dapr/appcallback.rs.html#42

Originally posted by @NickLarsenNZ in #80 (comment)


Other SDKs seem to be able to do it (I have seen it in action with .Net), for example dapr/python-sdk:

https://github.com/dapr/python-sdk/blob/1aab2cb1e06b32899183a285eab5c975408d05b2/ext/dapr-ext-grpc/dapr/ext/grpc/app.py#L137-L140

Proc macros to reduce boiler plate

Dapr seems quite easy to get going in other languages that provide annotations/attributes.
I think the same should be done for the Rust SDK.

For example:

[Topic("pubsub", "orders")]
[HttpPost("/checkout")]
public async Task<ActionResult<Order>>Checkout(Order order, [FromServices] DaprClient daprClient)
{
    // Logic
    return order;
}

Could be expressed as:

#[topic(pub_sub_name = "pubsub", topic = "orders")]
#[post("/checkout")]
async fn hello(order: Order) -> String {
    format!("Order id: {}", order.id)
}

Am I right in thinking that the difficulty comes in the variety of HTTP server crates? Or is that quite decoupled from decorating the handler?

doc: add diagram for how Rust SDK interacts with Dapr runtime

Describe the proposal

Is your feature request related to a problem? Please describe.
There is no visual representation for how the SDK interacts with the Dapr runtime.

Describe the solution you'd like
It would be nice for community members to have a diagram depicting the interactions with end user applications, the Dapr Rust SDK, and the Dapr sidecar close to the codebase, within the README.md file.

The diagram should include:

  • 3 main components: end user application, Dapr Rust SDK, Dapr sidecar:
  • Initialization: which protocol is the application Dapr client using to establish connection with the Dapr sidecar, HTTP or gRPC? That depends on the SDK and should be depicted visually.
  • API calls that one can use the Dapr client for. For example you can save & retrieve state from state stores, publish and subscribe to events using pub/sub, invoke other services using service invocation, etc. We should represent which APIs the SDK supports.
  • Overall request routing (when app makes API call through Dapr client, then the request is sent to the Dapr sidecar running along the app)

Other ideas that can be included in diagram:

  • Sidecar processing
  • Response handling
  • Middleware and observability
  • Error handling
  • Security

Describe alternatives you've considered
We could technically keep the README.md file as is, but it would be nice to have visuals here for community members understanding of these interactions.

Additional context
https://docs.dapr.io/developing-applications/sdks/

Code examples on how to use Rust SDK with each supported building block

Consider adding examples in the Github repo (maybe as a README?) on how to use the Rust SDK for each of the supported Building Blocks, e.g how to use the Rust SDK for Service Invocation.

These examples will provide clarity on how to use the SDK. Additionally, we can raise visibility into the SDK by linking to the examples from each Building Block overview page.

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.