Skip to content

Commit

Permalink
Added some styling to documentation site
Browse files Browse the repository at this point in the history
  • Loading branch information
sleipnir committed Sep 25, 2024
1 parent 7934d1d commit 76e8106
Show file tree
Hide file tree
Showing 3 changed files with 229 additions and 145 deletions.
27 changes: 27 additions & 0 deletions _config.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
title: Spawn
description: >- # Markdown support is enabled
A Actor based Service Mesh runtime.
# Build settings
markdown: kramdown
theme: minima # Default theme, or you can specify another one

# Custom CSS
sass:
style: compressed

# Include your custom CSS file
defaults:
- scope:
path: ""
type: "page"
values:
layout: "default"

# Add links to your custom CSS
include:
- assets/css/style.css

# Plugins (if any)
plugins:
- jekyll-feed
27 changes: 27 additions & 0 deletions assets/css/style.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
.styled-table {
width: 100%;
border-collapse: collapse;
font-size: 16px;
text-align: left;
margin: 25px 0;
background-color: #f9f9f9;
}

.styled-table thead tr {
background-color: #009879;
color: #ffffff;
}

.styled-table th,
.styled-table td {
border: 1px solid #dddddd;
padding: 12px 15px;
}

.styled-table tbody tr {
border-bottom: 1px solid #dddddd;
}

.styled-table tbody tr:hover {
background-color: #f1f1f1;
}
320 changes: 175 additions & 145 deletions docs/getting_started.md
Original file line number Diff line number Diff line change
Expand Up @@ -53,11 +53,22 @@ You can also check out the following gif for another example:

Once you have done the initial setup you can start developing your actors in several available languages. See below how easy it is to do this:

<details open>
<summary>NodeJS/Bun</summary>

```js
import spawn, { ActorContext, Value } from '@eigr/spawn-sdk'
<table class="styled-table">
<thead>
<tr>
<th>Language</th>
<th>Example</th>
</tr>
</thead>
<tbody>
<tr>
<td>Typescript</td>
<td>
<details open>
<summary>Show Code</summary>

```js
import spawn, { ActorContext, Value } from '@eigr/spawn-sdk'
import { UserState, ChangeUserNamePayload, ChangeUserNameStatus } from 'src/protos/examples/user_example'

const system = spawn.createSystem('SpawnSystemName')
Expand All @@ -75,150 +86,169 @@ Once you have done the initial setup you can start developing your actors in sev
}

actor.addAction({ name: 'setName', payloadType: ChangeUserNamePayload }, setNameHandler)
```
</details>

<details>
<summary>Elixir</summary>

```elixir
defmodule SpawnSdkExample.Actors.MyActor do
use SpawnSdk.Actor,
name: "joe",
kind: :named,
stateful: true,
state_type: Io.Eigr.Spawn.Example.MyState, # or :json if you don't care about protobuf types

require Logger

alias Io.Eigr.Spawn.Example.{MyState, MyBusinessMessage}

action "Sum", fn %Context{state: state} = ctx, %MyBusinessMessage{value: value} = data ->
Logger.info("Received Request: #{inspect(data)}. Context: #{inspect(ctx)}")
new_value = if is_nil(state), do: value, else: (state.value || 0) + value

Value.of(%MyBusinessMessage{value: new_value}, %MyState{value: new_value})
end
end
```
</details>

<details>
<summary>Java</summary>
```
</details>
</td>
</tr>
<tr>
<td>Elixir</td>
<td>
<details>
<summary>Show Code</summary>

```elixir
defmodule SpawnSdkExample.Actors.MyActor do
use SpawnSdk.Actor,
name: "joe",
kind: :named,
stateful: true,
state_type: Io.Eigr.Spawn.Example.MyState, # or :json if you don't care about protobuf types

```java
package io.eigr.spawn.java.demo;

import io.eigr.spawn.api.actors.ActorContext;
import io.eigr.spawn.api.actors.StatefulActor;
import io.eigr.spawn.api.actors.Value;
import io.eigr.spawn.api.actors.behaviors.ActorBehavior;
import io.eigr.spawn.api.actors.behaviors.BehaviorCtx;
import io.eigr.spawn.api.actors.behaviors.NamedActorBehavior;
import io.eigr.spawn.api.actors.ActionBindings;
import domain.Reply;
import domain.Request;
import domain.State;

import static io.eigr.spawn.api.actors.behaviors.ActorBehavior.*;

public final class JoeActor implements StatefulActor<State> {

@Override
public ActorBehavior configure(BehaviorCtx context) {
return new NamedActorBehavior(
name("JoeActor"),
channel("test.channel"),
action("SetLanguage", ActionBindings.of(Request.class, this::setLanguage))
);
}

private Value setLanguage(ActorContext<State> context, Request msg) {
if (context.getState().isPresent()) {
//Do something with previous state
}

return Value.at()
.response(Reply.newBuilder()
.setResponse(String.format("Hi %s. Hello From Java", msg.getLanguage()))
.build())
.state(updateState(msg.getLanguage()))
.reply();
}

private State updateState(String language) {
return State.newBuilder()
.addLanguages(language)
.build();
}
}
```
</details>

<details>
<summary>Python</summary>
require Logger

```python
from domain.domain_pb2 import JoeState, Request
from spawn.eigr.functions.actors.api.actor import Actor
from spawn.eigr.functions.actors.api.settings import ActorSettings
from spawn.eigr.functions.actors.api.context import Context
from spawn.eigr.functions.actors.api.value import Value

actor = Actor(settings=ActorSettings(
name="joe", stateful=True, channel="test"))

alias Io.Eigr.Spawn.Example.{MyState, MyBusinessMessage}

@actor.action("setLanguage")
def set_language(request: Request, ctx: Context) -> Value:
new_state = None
action "Sum", fn %Context{state: state} = ctx, %MyBusinessMessage{value: value} = data ->
Logger.info("Received Request: #{inspect(data)}. Context: #{inspect(ctx)}")
new_value = if is_nil(state), do: value, else: (state.value || 0) + value

if not ctx.state:
new_state = JoeState()
new_state.languages.append("python")
else:
new_state = ctx.state

return Value().state(new_state).noreply()
```
</details>

<details>
<summary>Rust</summary>

```rust
use spawn_examples::domain::domain::{Reply, Request, State};
use spawn_rs::{value::Value, Context, Message};

use log::info;

pub fn set_language(msg: Message, ctx: Context) -> Value {
info!("Actor msg: {:?}", msg);
return match msg.body::<Request>() {
Ok(request) => {
let lang = request.language;
info!("Setlanguage To: {:?}", lang);
let mut reply = Reply::default();
reply.response = lang;

match &ctx.state::<State>() {
Some(state) => Value::new()
.state::<State>(&state.as_ref().unwrap(), "domain.State".to_string())
.response(&reply, "domain.Reply".to_string())
.to_owned(),
_ => Value::new()
.state::<State>(&State::default(), "domain.State".to_string())
.response(&reply, "domain.Reply".to_string())
.to_owned(),
}
}
Err(_e) => Value::new()
.state::<State>(&State::default(), "domain.State".to_string())
.to_owned(),
};
}
```
</details>
Value.of(%MyBusinessMessage{value: new_value}, %MyState{value: new_value})
end
end
```
</details>
</td>
</tr>
<tr>
<td>Java</td>
<td>
<details>
<summary>Show Code</summary>

```java
package io.eigr.spawn.java.demo;

import io.eigr.spawn.api.actors.ActorContext;
import io.eigr.spawn.api.actors.StatefulActor;
import io.eigr.spawn.api.actors.Value;
import io.eigr.spawn.api.actors.behaviors.ActorBehavior;
import io.eigr.spawn.api.actors.behaviors.BehaviorCtx;
import io.eigr.spawn.api.actors.behaviors.NamedActorBehavior;
import io.eigr.spawn.api.actors.ActionBindings;
import domain.Reply;
import domain.Request;
import domain.State;

import static io.eigr.spawn.api.actors.behaviors.ActorBehavior.*;

public final class JoeActor implements StatefulActor<State> {

@Override
public ActorBehavior configure(BehaviorCtx context) {
return new NamedActorBehavior(
name("JoeActor"),
channel("test.channel"),
action("SetLanguage", ActionBindings.of(Request.class, this::setLanguage))
);
}

private Value setLanguage(ActorContext<State> context, Request msg) {
if (context.getState().isPresent()) {
//Do something with previous state
}

return Value.at()
.response(Reply.newBuilder()
.setResponse(String.format("Hi %s. Hello From Java", msg.getLanguage()))
.build())
.state(updateState(msg.getLanguage()))
.reply();
}

private State updateState(String language) {
return State.newBuilder()
.addLanguages(language)
.build();
}
}
```
</details>
</td>
</tr>
<tr>
<td>Python</td>
<td>
<details>
<summary>Show Code</summary>

```python
from domain.domain_pb2 import JoeState, Request
from spawn.eigr.functions.actors.api.actor import Actor
from spawn.eigr.functions.actors.api.settings import ActorSettings
from spawn.eigr.functions.actors.api.context import Context
from spawn.eigr.functions.actors.api.value import Value

actor = Actor(settings=ActorSettings(
name="joe", stateful=True, channel="test"))


@actor.action("setLanguage")
def set_language(request: Request, ctx: Context) -> Value:
new_state = None

if not ctx.state:
new_state = JoeState()
new_state.languages.append("python")
else:
new_state = ctx.state

return Value().state(new_state).noreply()
```
</details>
</td>
</tr>
<tr>
<td>Rust</td>
<td>
<details>
<summary>Show Code</summary>

```rust
use spawn_examples::domain::domain::{Reply, Request, State};
use spawn_rs::{value::Value, Context, Message};

use log::info;

pub fn set_language(msg: Message, ctx: Context) -> Value {
info!("Actor msg: {:?}", msg);
return match msg.body::<Request>() {
Ok(request) => {
let lang = request.language;
info!("Setlanguage To: {:?}", lang);
let mut reply = Reply::default();
reply.response = lang;

match &ctx.state::<State>() {
Some(state) => Value::new()
.state::<State>(&state.as_ref().unwrap(), "domain.State".to_string())
.response(&reply, "domain.Reply".to_string())
.to_owned(),
_ => Value::new()
.state::<State>(&State::default(), "domain.State".to_string())
.response(&reply, "domain.Reply".to_string())
.to_owned(),
}
}
Err(_e) => Value::new()
.state::<State>(&State::default(), "domain.State".to_string())
.to_owned(),
};
}
```
</details>
</td>
</tr>
</tbody> </table>

### Deploy

Expand Down

0 comments on commit 76e8106

Please sign in to comment.