Skip to content

Commit

Permalink
Merge pull request #24 from b5g-ex/readme
Browse files Browse the repository at this point in the history
enrich README
  • Loading branch information
takasehideki authored Feb 22, 2024
2 parents bf116fa + 78ac00b commit cd6678b
Showing 1 changed file with 137 additions and 35 deletions.
172 changes: 137 additions & 35 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,79 +3,181 @@
[![Hex version](https://img.shields.io/hexpm/v/zenohex.svg "Hex version")](https://hex.pm/packages/zenohex)
[![API docs](https://img.shields.io/hexpm/v/zenohex.svg?label=hexdocs "API docs")](https://hexdocs.pm/zenohex/)
[![License](https://img.shields.io/hexpm/l/zenohex.svg)](https://github.com/zenohex/zenohex/blob/main/LICENSE)
[![CI](https://github.com/b5g-ex/zenohex/actions/workflows/ci.yml/badge.svg)](https://github.com/b5g-ex/zenohex/actions/workflows/ci.yml)

Zenohex is the [zenoh](https://zenoh.io/) client library for elixir.
Zenohex is Elixir API for [Zenoh](https://zenoh.io/).

**Currently zenohex uses version 0.10.1-rc of zenoh.
If you want to communicate with other Zenoh clients or routers, please use the same version.**
Zenoh is a new protocol for Zero Overhead Pub/Sub, Store/Query and Compute.
The most obvious explanation is that Zenoh offers publication subscription-based communication capabilities.
Within the same network, Zenoh can autonomously search for communication partner nodes like DDS.
Between different networks, Zenoh can search for nodes through a broker (called a router in Zenoh) like MQTT.
Also, Zenoh provides functions for database operations and computational processing based on the Key-Value Store.
Moreover, it has plugins/bridges for interoperability with MQTT, DDS, REST, etc. as communication middleware, and influxdb, RocksDB, etc. as database stacks.

## Installation
For more details about Zenoh, please refer to the official resources.

If [available in Hex](https://hex.pm/docs/publish), the package can be installed
by adding `zenohex` to your list of dependencies in `mix.exs`:
- [Official Page](https://zenoh.io/)
- [GitHub](https://github.com/eclipse-zenoh/zenoh)
- [Discord](https://discord.gg/vSDSpqnbkm)

```elixir
def deps do
[
{:zenohex, "~> 0.2.0-rc.2"}
]
end
```
Zenoh's core modules are implemented in Rust, but API libraries in various programming languages such as Python ([zenoh-python](https://github.com/eclipse-zenoh/zenoh-python)), C ([zenoh-c](https://github.com/eclipse-zenoh/zenoh-c)), C++ ([zenoh-cpp](https://github.com/eclipse-zenoh/zenoh-cpp)) are officially provided.

So what we need is [Elixir](https://elixir-lang.org/)!
With this library, you can call Zenoh from your Elixir application to perform its basic processing.
This allows the creation and communication of a large number of fault-tolerant nodes with little memory load (we hope :D

Documentation can be generated with [ExDoc](https://github.com/elixir-lang/ex_doc)
and published on [HexDocs](https://hexdocs.pm). Once published, the docs can
be found at <https://hexdocs.pm/zenohex>.
## Usage

### Install rust (Optional)
**Currently, Zenohex uses version 0.10.1-rc of Zenoh.
We recommend you use the same version to communicate with other Zenoh clients or routers.**

Since version 0.1.3, Zenohex uses rustler precompiled and does not require Rust to be installed.
### Installation

If you want to build rust NIFs code, please add following to your config file.
`zenohex` is [available in Hex](https://hex.pm/packages/zenohex).

You can install this package into your project by adding `zenohex` to your list of dependencies in `mix.exs`:

```elixir
config :rustler_precompiled, :force_build, zenohex: true
defp deps do
[
...
{:zenohex, "~> 0.2.0-rc.2"},
...
]
end
```

https://www.rust-lang.org/tools/install
Documentation is also [available in HexDocs](https://hexdocs.pm/zenohex).

Zenohex can be also adapted to your [Nerves](https://nerves-project.org/) application just by adding `zenohex` in `mix.exs`.
Please refer to [pojiro/zenohex_on_nerves](https://github.com/pojiro/zenohex_on_nerves) as the example.

## Getting Started
This repository uses [Rustler](https://github.com/rusterlium/rustler) to call Rust (Zenoh) modules from Elixir, and pre-compiled NIF modules are automatically downloaded at `mix compile` time (since v0.1.3).
IOW, if you just want to use this library from your Elixir application, you do not need to prepare a Rust environment.
If you still want to build Rust NIF modules locally, please refer to [this section](#build-nif-module-locally).

### Low layer Pub/Sub example
### Getting Started

Zenohex has a policy of providing APIs that wrap the basic functionality of Zenoh like other API libraries.

Here is the first step to building an Elixir application and using this feature.

```sh
$ mix deps.get
$ mix compile
$ iex -S mix
```

```elixir
iex(1)> {:ok, session} = Zenohex.open()
iex()> {:ok, session} = Zenohex.open()
{:ok, #Reference<>}
iex(2)> {:ok, publisher} = Zenohex.Session.declare_publisher(session, "pub/sub")
iex()> {:ok, publisher} = Zenohex.Session.declare_publisher(session, "demo/example/test")
{:ok, #Reference<>}
iex(3)> {:ok, subscriber} = Zenohex.Session.declare_subscriber(session, "pub/sub")
iex()> {:ok, subscriber} = Zenohex.Session.declare_subscriber(session, "demo/**")
{:ok, #Reference<>}
iex(4)> Zenohex.Publisher.put(publisher, "Hello Zenoh Dragon")
iex()> Zenohex.Publisher.put(publisher, "Hello Zenoh Dragon")
:ok
iex(5)> Zenohex.Subscriber.recv_timeout(subscriber, 1000)
{:ok, "Hello Zenoh Dragon"}
iex(6)> Zenohex.Subscriber.recv_timeout(subscriber, 1000)
iex()> Zenohex.Subscriber.recv_timeout(subscriber, 1000)
{:ok,
%Zenohex.Sample{
key_expr: "demo/example/test",
value: "Hello Zenoh Dragon",
kind: :put,
reference: #Reference<>
}}
iex()> Zenohex.Subscriber.recv_timeout(subscriber, 1000)
{:error, :timeout}
```

### Practical examples

We implemented practical examples under the [lib/zenohex/examples](https://github.com/b5g-ex/zenohex/tree/v0.2.0-rc.2/lib/zenohex/examples).
Since they consist of `Supervisor` and `GenServer`, we think they are useful as examples of more Elixir-like applications.

Please read the [lib/zenohex/examples/README.md](https://github.com/b5g-ex/zenohex/tree/v0.2.0-rc.2/lib/zenohex/examples/README.md) to use them as your implementation's reference.

## For developer
## For developers

For most users, this section should be skipped.

### Build NIF module locally

This subsection is for developers who want to build NIF module locally in your Elixir application or try to use this repository itself for the contribution (very welcome!!).

First, please install and configure the Rust environment according to [the instructions on the official site](https://www.rust-lang.org/tools/install).

Then, add the following to your config file (e.g., `config/config.exs`) or make sure it is added.

```elixir
import Config

config :rustler_precompiled, :force_build, zenohex: true
```

When you want to build NIF module locally into your project, install Rustler by adding `rustler` to your list of dependencies in `mix.exs`:

```elixir
defp deps do
[
...
{:zenohex, "~> 0.2.0-rc.2"},
{:rustler, ">= 0.0.0", optional: true},
...
]
end
```

### Enhance mix test

This subsection describes some Tips for `mix test`.

The default `mix test` rebuilds the NIF module, so you can reduce the test time by doing the following in advance.

```sh
export API_OPEN_SESSION_DELAY=0 && mix compile --force
```

You can also reduce the test time by adjusting `SCOUTING_DELAY` as the follow.

```sh
SCOUTING_DELAY=30 mix test
```

This parameter is used to set the upper time limit for searching (scouting) for a communication peer node.
The default value (when undefined) is 200 ms.
IOW, if the test fails because the communication partner is not found within the set time, this value should be increased.

Finally, the default `mix test` only checks the communication of Zenoh nodes within the same session.
If you wish to run communication tests between different sessions, please run the following.

```sh
USE_DIFFERENT_SESSION="1" mix test
```

FYI, CI does this in `test-with-another-session` without defining `SCOUTING_DELAY`, so this test sometimes fails on GHA.

### How to release

These steps just follow the [Recommended flow of rustler_precompiled](https://hexdocs.pm/rustler_precompiled/precompilation_guide.html#recommended-flow).

1. Change versions, `mix.exs`, `native/zenohex_nif/Cargo.toml`
2. Run test, this step changes `native/zenohex_nif/Cargo.lock` version
3. Commit them and put the version tag, like v0.2.0-rc.2
4. Puth the tag, like `git push origin v0.2.0-rc.2`. this step triggers the `.github/workflows/nif_precompile.yml`
5. After the artifacts are made, run `mix rustler_precompiled.download Zenohex.Nif --all` to update `checksum-Elixir.Zenohex.Nif.exs` and commit it.
3. Commit them and put the version tag, like v0.2.0
4. Puth the tag, like `git push origin v0.2.0`. This step triggers the `.github/workflows/nif_precompile.yml`
5. After the artifacts are made, run `mix rustler_precompiled.download Zenohex.Nif --all` to update `checksum-Elixir.Zenohex.Nif.exs` and commit it
6. Then publish to Hex

(These steps just follows [Recommended flow](https://hexdocs.pm/rustler_precompiled/precompilation_guide.html#recommended-flow).)
## Resources

- Zenoh meets Elixir in Japan
- presented in [Zenoh User Meeting 2023](https://www.zettascale.tech/news/zenoh-user-meeting-2023/) at 2023/12/12
- [SpeakerDeck](https://speakerdeck.com/takasehideki/zenoh-meets-elixir-in-japan)
- [YouTube archive](https://www.youtube.com/watch?v=4TYn_l6rXIg)
- Zenohex: an eloquent, scalable and fast communication library for Elixir
- (will be) presented in [Code BEAM America 2024](https://codebeamamerica.com/) at 2024/03/07
- Slide and video archive will be added

## License

The source code of this repository itself is published under [MIT License](https://github.com/b5g-ex/zenohex/blob/main/LICENSE).
Please note that this repository mainly uses [Zenoh which is licensed under Apache 2.0 and EPL 2.0](https://github.com/eclipse-zenoh/zenoh/blob/main/LICENSE) and [Rustler which is licensed under either of Apache 2.0 or MIT](https://github.com/rusterlium/rustler?tab=readme-ov-file#license).

0 comments on commit cd6678b

Please sign in to comment.