2. Make It Your own
In the next 5 minutes we will take you through making your first changes to a Rust application running in Wasm. If you haven't got the demo running yet, check out the quick start guide.
3. Making it Your Own
As a reminder, since we'll be editing Rust code, make sure you have Rust installed, and ensure you have a WebAssembly target added to your toolchain. You can add this target with:
bash
rustup target add wasm32-unknown-unknown
bash
rustup target add wasm32-unknown-unknown
Generating a New Actor
Let's see how easy it is to update an application with new code. First we'll generate a new actor project.
bash
cosmo new actor --git https://github.com/cosmonic/awesome-cosmonic --subfolder xkcdgenerator my-xkcd
bash
cosmo new actor --git https://github.com/cosmonic/awesome-cosmonic --subfolder xkcdgenerator my-xkcd
This command generated a git repository in the my-xkcd
directory with everything you need to
compile and run your actor. Other than the code itself, the most important file here is
wasmcloud.toml
. This file contains metadata for your project, including the claims
, which are a
set of capabilities that your actor may use (think of the
capability providers mentioned earlier)
claims = ["wasmcloud:httpserver", "wasmcloud:httpclient", "wasmcloud:builtin:numbergen"]
claims = ["wasmcloud:httpserver", "wasmcloud:httpclient", "wasmcloud:builtin:numbergen"]
We have three claims in this actor already: the HTTP server to respond to requests, the HTTP client
to get images, and numbergen
to generate random numbers.
Compiling and Signing an Actor
Building an actor takes just one command:
bash
cosmo build
bash
cosmo build
This command uses your local toolchain to compile the actor into a WebAssembly module. It then signs your actor.
Launching an Actor Locally
Once again, launching an actor is a single command:
bash
cosmo launch
bash
cosmo launch
All actors run in a host. cosmo launch
runs your actors in a local host
(and starts a host for you, if one is not already running). Unpacking this, the first time you run
cosmo launch
we will start wasmCloud on your machine (a new host), then start an actor on that new
host!
If you return to the Logic View, you'll see a new actor has appeared in your constellation. It has a similar name to the one that you started with the initial tutorial command. However, you'll notice the new actor has a different icon. The Cosmonic UI provides a visual indicator of whether your components are running on a host managed by Cosmonic.
However, it doesn't matter whether your components are running on a Cosmonic host or a host on your laptop locally. Cosmonic is designed for distributed applications; whether parts of your application are running on a laptop, in a cloud provider's VM, or on a Raspberry Pi is irrelevant!
Connecting an Actor to Capability Providers
You'll also notice that the new actor is not connected to any capability providers. This is because the actor you generated has its own unique identity key, different from the pre-built actor you started with the tutorial command, and links are based on the actor's ID.
To link your new actor to the capability providers, you can simply drag from each of the capability names on the actor to the corresponding provider.
As you can see, a modal will open, allowing you to provide custom configuration, but the default values are fine, so you can just click "Create Link."
Allowing Inbound Traffic
Your new actor is linked up and ready to go! The only remaining step is to create a new wormhole, which is an HTTP ingress point associated with a randomly-generated domain name. Starting from the Logic View once again, click the + Wormhole button.
This will open a new modal where you select which actor to connect to HTTP requests coming from
outside Cosmonic. Select your new actor xkcdgenerator
(the one without the space) and click
"Create Wormhole."
Now we can click on the new wormhole node that has appeared on the canvas. This will open a side panel with details about your new wormhole. From here, we click the "Access your Wormhole" button to open a new tab. You should see another XKCD comic! This time, the comics are being generated by your new actor that is running locally.
Notice what you didn't do: start any new capability providers. Your new actor is running locally, but it's connected to the capability providers running on Cosmonic. This isn't unique to actors, either; you can also run capability providers locally, and connect them to actors running anywhere!
Updating an Actor
Let's return to the new actor. The source code is in src/lib.rs
. Open this file and we can take a
look at what this does.
The actor implements a single function handle_request
. In this function, we generate a random
number, issue an HTTP request to the XKCD API, and return an HTML response (which is rendered by
your browser).
The random number is generated in a range, representing the list of comic IDs which were valid at the time this template was first written. This is being done using one of the capability providers which are built into the host that your actor is running on (another is a logging capability). These work the same way (through contracts and claims), but you don't need to explicitly start a provider to access these capabilities.
At the time of writing, 2779 was the latest comic ID. Since some time has passed, you could increase the upper end of the range to the new maximum comic ID. Or, you could restrict the range, or eliminate the randomness altogether and always request the same comic! A personal favorite is #1053.
In your editor, change the logic related to selecting a comic. Feel free to change some of the HTML response as well. For example:
rust
let random_num = random_in_range(1053, 1053).await?; // Sample from the best 😉
rust
let random_num = random_in_range(1053, 1053).await?; // Sample from the best 😉
rust
let body = format!(r#"<!DOCTYPE html><html><head><title>Your Not-So-Random XKCD comic</title></head><body><h1>A classic: {}</h1><img src="{}"/></body></html>"#,comic.title, comic.img);
rust
let body = format!(r#"<!DOCTYPE html><html><head><title>Your Not-So-Random XKCD comic</title></head><body><h1>A classic: {}</h1><img src="{}"/></body></html>"#,comic.title, comic.img);
Once you've updated your actor's code, you can launch a new version by running:
bash
cosmo launch
bash
cosmo launch
cosmo
will take care of replacing your actor with the updated code. If you refresh the tab
connected to your wormhole, you'll see the results of your changes! It's that easy to iterate
quickly on your ideas.
What else made this work?
This XKCD application used three capabilities: HTTP Server,
HTTP Client, and (builtin) numbergen
. This allowed our app to
receive/reply to HTTP requests through a wormhole and query an external API. Notice the lack of
boilerplate details in this code: no ports, no TLS certificates, and yet you were able to make a
request and receive your response. Cosmonic believes this is the way applications should be built.
In other words, Write the Right Code. Let us handle the
rest.
To make more dynamic applications, you'll want to explore more capabilities.
What next?
Now that you have been through a fun example, we recommend looking at serving files over HTTP. Check out our next example app to get started: https://cosmonic.com/docs/to-build/blobby