From 874d06ce2f307e609fdb51fd1fcdbb8bc84169c8 Mon Sep 17 00:00:00 2001 From: John Anderson Date: Wed, 8 May 2024 12:58:29 -0400 Subject: [PATCH] it lives! --- .env | 15 ++++ .gitignore | 2 + .vscode/settings.json | 3 + Cargo.lock | 25 +++++++ Cargo.toml | 20 ++++++ docker-compose.yaml | 157 ++++++++++++++++++++++++++++++++++++++++++ src/bindings.rs | 85 +++++++++++++++++++++++ src/lib.rs | 31 +++++++++ wit/yoyo.wit | 12 ++++ 9 files changed, 350 insertions(+) create mode 100644 .env create mode 100644 .gitignore create mode 100644 .vscode/settings.json create mode 100644 Cargo.lock create mode 100644 Cargo.toml create mode 100644 docker-compose.yaml create mode 100644 src/bindings.rs create mode 100644 src/lib.rs create mode 100644 wit/yoyo.wit diff --git a/.env b/.env new file mode 100644 index 0000000..54e3fa0 --- /dev/null +++ b/.env @@ -0,0 +1,15 @@ +REDIS_PORT=6380 +POSTGRES_PORT=5432 +GOLEM_ROUTER_PORT=9881 +GOLEM_ROUTER_COMPONENT_MAX_SIZE_ALLOWED=1g +COMPONENT_SERVICE_HTTP_PORT=8083 +COMPONENT_SERVICE_GRPC_PORT=9090 +COMPONENT_COMPILATION_SERVICE_HTTP_PORT=8084 +COMPONENT_COMPILATION_SERVICE_GRPC_PORT=9091 +SHARD_MANAGER_HTTP_PORT=8081 +SHARD_MANAGER_GRPC_PORT=9002 +WORKER_EXECUTOR_HTTP_PORT=8082 +WORKER_EXECUTOR_GRPC_PORT=9000 +WORKER_SERVICE_HTTP_PORT=9005 +WORKER_SERVICE_CUSTOM_REQUEST_PORT=9006 +WORKER_SERVICE_GRPC_PORT=9007 diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..2bfe253 --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +**/target/** + diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 0000000..7530c05 --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,3 @@ +{ + "rust-analyzer.server.extraEnv": { "CARGO": "cargo-component" } +} \ No newline at end of file diff --git a/Cargo.lock b/Cargo.lock new file mode 100644 index 0000000..8e8e448 --- /dev/null +++ b/Cargo.lock @@ -0,0 +1,25 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 3 + +[[package]] +name = "bitflags" +version = "2.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cf4b9d6a944f767f8e5e0db018570623c85f3d925ac718db4e06d0187adb21c1" + +[[package]] +name = "wit-bindgen" +version = "0.17.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6237168d93497b26dacdab157b08ad2787d74cdce10f89735f791b2a225eba4d" +dependencies = [ + "bitflags", +] + +[[package]] +name = "yoyo" +version = "0.0.1" +dependencies = [ + "wit-bindgen", +] diff --git a/Cargo.toml b/Cargo.toml new file mode 100644 index 0000000..17ab12a --- /dev/null +++ b/Cargo.toml @@ -0,0 +1,20 @@ +[package] +name = "yoyo" +version = "0.0.1" +edition = "2021" + +[lib] +path = "src/lib.rs" +crate-type = ["cdylib"] + +[profile.release] +lto = true +opt-level = 's' + +[dependencies] +wit-bindgen = { version = "0.17.0", default-features = false, features = ["realloc"] } + +[package.metadata.component.target] +path = "wit" + +[package.metadata.component.target.dependencies] \ No newline at end of file diff --git a/docker-compose.yaml b/docker-compose.yaml new file mode 100644 index 0000000..db7e034 --- /dev/null +++ b/docker-compose.yaml @@ -0,0 +1,157 @@ +version: "3.8" + +services: + router: + image: golemservices/golem-router:latest + pull_policy: always + ports: + - "${GOLEM_ROUTER_PORT}:80" + environment: + - GOLEM_COMPONENT_MAX_SIZE_ALLOWED=${GOLEM_ROUTER_COMPONENT_MAX_SIZE_ALLOWED} + - GOLEM_WORKER_SERVICE_HOST=golem-worker-service + - GOLEM_WORKER_SERVICE_PORT=${WORKER_SERVICE_HTTP_PORT} + - GOLEM_COMPONENT_SERVICE_HOST=golem-component-service + - GOLEM_COMPONENT_SERVICE_PORT=${COMPONENT_SERVICE_HTTP_PORT} + depends_on: + - golem-worker-service + - golem-component-service + - golem-shard-manager + + redis: + image: redis:latest + volumes: + - redis_data:/data + command: --port ${REDIS_PORT} + ports: + - "${REDIS_PORT}:${REDIS_PORT}" + + golem-shard-manager: + image: golemservices/golem-shard-manager:latest + pull_policy: always + environment: + - WASMTIME_BACKTRACE_DETAILS=1 + - RUST_BACKTRACE=1 + - RUST_LOG=info,h2=warn,hyper=warn,tower=warn + - GOLEM__REDIS__HOST=redis + - GOLEM__REDIS__PORT=${REDIS_PORT} + - GOLEM__HTTP_PORT=${SHARD_MANAGER_HTTP_PORT} + - GOLEM_SHARD_MANAGER_PORT=${SHARD_MANAGER_GRPC_PORT} + depends_on: + - redis + + golem-component-service: + image: golemservices/golem-component-service:latest + pull_policy: always + environment: + - ENVIRONMENT=local + - WASMTIME_BACKTRACE_DETAILS=1 + - RUST_BACKTRACE=1 + - RUST_LOG=info,h2=warn,hyper=warn,tower=warn + - GOLEM__COMPONENT_STORE__TYPE="Local" + - GOLEM__COMPONENT_STORE__CONFIG__OBJECT_PREFIX="" + - GOLEM__COMPONENT_STORE__CONFIG__ROOT_PATH=/component_store + - GOLEM__COMPILATION__TYPE="Enabled" + - GOLEM__COMPILATION__CONFIG__HOST=golem-component-compilation-service + - GOLEM__COMPILATION__CONFIG__PORT=${COMPONENT_COMPILATION_SERVICE_GRPC_PORT} + - GOLEM__DB__TYPE=Sqlite + - GOLEM__DB__CONFIG__DATABASE=/app/golem_db/golem.sqlite + - GOLEM__DB__CONFIG__MAX_CONNECTIONS=10 + - GOLEM__GRPC_PORT=${COMPONENT_SERVICE_GRPC_PORT} + - GOLEM__HTTP_PORT=${COMPONENT_SERVICE_HTTP_PORT} + volumes: + - component_store:/component_store + - golem_db:/app/golem_db + ports: + - "${COMPONENT_SERVICE_HTTP_PORT}:${COMPONENT_SERVICE_HTTP_PORT}" + - "${COMPONENT_SERVICE_GRPC_PORT}:${COMPONENT_SERVICE_GRPC_PORT}" + + golem-worker-service: + image: golemservices/golem-worker-service:latest + pull_policy: always + environment: + - RUST_BACKTRACE=1 + - RUST_LOG=info,h2=warn,hyper=warn,tower=warn + - GOLEM__REDIS__HOST=redis + - GOLEM__REDIS__PORT=${REDIS_PORT} + - GOLEM__REDIS__DATABASE=1 + - GOLEM__ENVIRONMENT=local + - GOLEM__COMPONENT_SERVICE__HOST=golem-component-service + - GOLEM__COMPONENT_SERVICE__PORT=${COMPONENT_SERVICE_GRPC_PORT} + - GOLEM__COMPONENT_SERVICE__ACCESS_TOKEN="5C832D93-FF85-4A8F-9803-513950FDFDB1" + - GOLEM__ROUTING_TABLE__HOST="golem-shard-manager" + - GOLEM__ROUTING_TABLE__PORT=${SHARD_MANAGER_GRPC_PORT} + - GOLEM__CUSTOM_REQUEST_PORT=${WORKER_SERVICE_CUSTOM_REQUEST_PORT} + - GOLEM__PORT=${WORKER_SERVICE_HTTP_PORT} + - GOLEM__WORKER_GRPC_PORT=${WORKER_SERVICE_GRPC_PORT} + ports: + - "${WORKER_SERVICE_HTTP_PORT}:${WORKER_SERVICE_HTTP_PORT}" + - "${WORKER_SERVICE_CUSTOM_REQUEST_PORT}:${WORKER_SERVICE_CUSTOM_REQUEST_PORT}" + - "${WORKER_SERVICE_GRPC_PORT}:${WORKER_SERVICE_GRPC_PORT}" + depends_on: + - redis + + golem-component-compilation-service: + image: golemservices/golem-component-compilation-service:latest + pull_policy: always + environment: + - RUST_BACKTRACE=1 + - RUST_LOG=info,h2=warn,hyper=warn,tower=warn + - GOLEM__COMPONENT_SERVICE__HOST=golem-component-service + - GOLEM__COMPONENT_SERVICE__PORT=${COMPONENT_SERVICE_GRPC_PORT} + - GOLEM__COMPONENT_SERVICE__ACCESS_TOKEN="5C832D93-FF85-4A8F-9803-513950FDFDB1" + - GOLEM__COMPILED_COMPONENT_SERVICE__CONFIG__ROOT="/component_compiled_store" + - GOLEM__COMPILED_COMPONENT_SERVICE__TYPE="Local" + - GOLEM__HTTP_PORT=${COMPONENT_COMPILATION_SERVICE_HTTP_PORT} + - GOLEM__GRPC_PORT=${COMPONENT_COMPILATION_SERVICE_GRPC_PORT} + volumes: + - component_compiled_store:/component_compiled_store + ports: + - "${COMPONENT_COMPILATION_SERVICE_HTTP_PORT}:${COMPONENT_COMPILATION_SERVICE_HTTP_PORT}" + - "${COMPONENT_COMPILATION_SERVICE_GRPC_PORT}:${COMPONENT_COMPILATION_SERVICE_GRPC_PORT}" + depends_on: + - golem-component-service + + golem-worker-executor: + image: golemservices/golem-worker-executor:latest + pull_policy: always + environment: + - ENVIRONMENT=local + - WASMTIME_BACKTRACE_DETAILS=1 + - RUST_BACKTRACE=1 + - RUST_LOG=info + - GOLEM__REDIS__PORT=${REDIS_PORT} + - GOLEM__REDIS__HOST=redis + - GOLEM__COMPONENT_SERVICE__CONFIG__HOST=golem-component-service + - GOLEM__COMPONENT_SERVICE__CONFIG__PORT=${COMPONENT_SERVICE_GRPC_PORT} + - GOLEM__COMPONENT_SERVICE__CONFIG__ACCESS_TOKEN="2A354594-7A63-4091-A46B-CC58D379F677" + - GOLEM__PORT=${WORKER_EXECUTOR_GRPC_PORT} + - GOLEM__HTTP_PORT=${WORKER_EXECUTOR_HTTP_PORT} + - GOLEM__SHARD_MANAGER_SERVICE__CONFIG__HOST=golem-shard-manager + - GOLEM__SHARD_MANAGER_SERVICE__CONFIG__PORT=${SHARD_MANAGER_GRPC_PORT} + - GOLEM__SHARD_MANAGER_SERVICE__CONFIG__RETRIES__MAX_ATTEMPTS=5 + - GOLEM__SHARD_MANAGER_SERVICE__CONFIG__RETRIES__MIN_DELAY="100ms" + - GOLEM__SHARD_MANAGER_SERVICE__CONFIG__RETRIES__MAX_DELAY="2s" + - GOLEM__SHARD_MANAGER_SERVICE__CONFIG__RETRIES__MULTIPLIER=2 + - GOLEM__PUBLIC_WORKER_API__HOST=golem-worker-service + - GOLEM__PUBLIC_WORKER_API__PORT=${WORKER_SERVICE_GRPC_PORT} + - GOLEM__PUBLIC_WORKER_API__ACCESS_TOKEN="2A354594-7A63-4091-A46B-CC58D379F677" + - GOLEM__BLOB_STORE_SERVICE__CONFIG__REGION=us-east-1 + - GOLEM__COMPILED_COMPONENT_SERVICE__CONFIG__ROOT="/component_compiled_store" + - GOLEM__COMPILED_COMPONENT_SERVICE__TYPE="Local" + - GOLEM__SHARD_MANAGER_SERVICE__TYPE="Grpc" + volumes: + - component_compiled_store:/component_compiled_store + ports: + - "${WORKER_EXECUTOR_HTTP_PORT}:${WORKER_EXECUTOR_HTTP_PORT}" + depends_on: + - redis + +volumes: + redis_data: + driver: local + component_store: + driver: local + golem_db: + driver: local + component_compiled_store: + driver: local diff --git a/src/bindings.rs b/src/bindings.rs new file mode 100644 index 0000000..134f7da --- /dev/null +++ b/src/bindings.rs @@ -0,0 +1,85 @@ +// Generated by `wit-bindgen` 0.16.0. DO NOT EDIT! +pub mod exports { + pub mod golem { + pub mod component { + + #[allow(clippy::all)] + pub mod api { + #[used] + #[doc(hidden)] + #[cfg(target_arch = "wasm32")] + static __FORCE_SECTION_REF: fn() = super::super::super::super::__link_section; + const _: () = { + + #[doc(hidden)] + #[export_name = "golem:component/api#add"] + #[allow(non_snake_case)] + unsafe extern "C" fn __export_add(arg0: i64,) { + #[allow(unused_imports)] + use wit_bindgen::rt::{alloc, vec::Vec, string::String}; + + // Before executing any other code, use this function to run all static + // constructors, if they have not yet been run. This is a hack required + // to work around wasi-libc ctors calling import functions to initialize + // the environment. + // + // This functionality will be removed once rust 1.69.0 is stable, at which + // point wasi-libc will no longer have this behavior. + // + // See + // https://github.com/bytecodealliance/preview2-prototyping/issues/99 + // for more details. + #[cfg(target_arch="wasm32")] + wit_bindgen::rt::run_ctors_once(); + + <_GuestImpl as Guest>::add(arg0 as u64); + } + }; + const _: () = { + + #[doc(hidden)] + #[export_name = "golem:component/api#get"] + #[allow(non_snake_case)] + unsafe extern "C" fn __export_get() -> i64 { + #[allow(unused_imports)] + use wit_bindgen::rt::{alloc, vec::Vec, string::String}; + + // Before executing any other code, use this function to run all static + // constructors, if they have not yet been run. This is a hack required + // to work around wasi-libc ctors calling import functions to initialize + // the environment. + // + // This functionality will be removed once rust 1.69.0 is stable, at which + // point wasi-libc will no longer have this behavior. + // + // See + // https://github.com/bytecodealliance/preview2-prototyping/issues/99 + // for more details. + #[cfg(target_arch="wasm32")] + wit_bindgen::rt::run_ctors_once(); + + let result0 = <_GuestImpl as Guest>::get(); + wit_bindgen::rt::as_i64(result0) + } + }; + use super::super::super::super::super::Component as _GuestImpl; + pub trait Guest { + fn add(value: u64,); + fn get() -> u64; + } + + } + + } + } +} + +#[cfg(target_arch = "wasm32")] +#[link_section = "component-type:yoyo"] +#[doc(hidden)] +pub static __WIT_BINDGEN_COMPONENT_TYPE: [u8; 435] = [3, 0, 4, 121, 111, 121, 111, 0, 97, 115, 109, 13, 0, 1, 0, 7, 63, 1, 65, 2, 1, 66, 4, 1, 64, 1, 5, 118, 97, 108, 117, 101, 119, 1, 0, 4, 0, 3, 97, 100, 100, 1, 0, 1, 64, 0, 0, 119, 4, 0, 3, 103, 101, 116, 1, 1, 4, 1, 19, 103, 111, 108, 101, 109, 58, 99, 111, 109, 112, 111, 110, 101, 110, 116, 47, 97, 112, 105, 5, 0, 11, 9, 1, 0, 3, 97, 112, 105, 3, 0, 0, 7, 91, 1, 65, 2, 1, 65, 2, 1, 66, 4, 1, 64, 1, 5, 118, 97, 108, 117, 101, 119, 1, 0, 4, 0, 3, 97, 100, 100, 1, 0, 1, 64, 0, 0, 119, 4, 0, 3, 103, 101, 116, 1, 1, 4, 1, 19, 103, 111, 108, 101, 109, 58, 99, 111, 109, 112, 111, 110, 101, 110, 116, 47, 97, 112, 105, 5, 0, 4, 1, 20, 103, 111, 108, 101, 109, 58, 99, 111, 109, 112, 111, 110, 101, 110, 116, 47, 121, 111, 121, 111, 4, 0, 11, 10, 1, 0, 4, 121, 111, 121, 111, 3, 2, 0, 0, 164, 1, 12, 112, 97, 99, 107, 97, 103, 101, 45, 100, 111, 99, 115, 0, 123, 34, 105, 110, 116, 101, 114, 102, 97, 99, 101, 115, 34, 58, 123, 34, 97, 112, 105, 34, 58, 123, 34, 100, 111, 99, 115, 34, 58, 34, 83, 101, 101, 32, 104, 116, 116, 112, 115, 58, 47, 47, 103, 105, 116, 104, 117, 98, 46, 99, 111, 109, 47, 87, 101, 98, 65, 115, 115, 101, 109, 98, 108, 121, 47, 99, 111, 109, 112, 111, 110, 101, 110, 116, 45, 109, 111, 100, 101, 108, 47, 98, 108, 111, 98, 47, 109, 97, 105, 110, 47, 100, 101, 115, 105, 103, 110, 47, 109, 118, 112, 47, 87, 73, 84, 46, 109, 100, 32, 102, 111, 114, 32, 109, 111, 114, 101, 32, 100, 101, 116, 97, 105, 108, 115, 32, 97, 98, 111, 117, 116, 32, 116, 104, 101, 32, 87, 73, 84, 32, 115, 121, 110, 116, 97, 120, 34, 125, 125, 125, 0, 70, 9, 112, 114, 111, 100, 117, 99, 101, 114, 115, 1, 12, 112, 114, 111, 99, 101, 115, 115, 101, 100, 45, 98, 121, 2, 13, 119, 105, 116, 45, 99, 111, 109, 112, 111, 110, 101, 110, 116, 6, 48, 46, 49, 56, 46, 50, 16, 119, 105, 116, 45, 98, 105, 110, 100, 103, 101, 110, 45, 114, 117, 115, 116, 6, 48, 46, 49, 54, 46, 48]; + +#[inline(never)] +#[doc(hidden)] +#[cfg(target_arch = "wasm32")] +pub fn __link_section() {} diff --git a/src/lib.rs b/src/lib.rs new file mode 100644 index 0000000..bcaf18d --- /dev/null +++ b/src/lib.rs @@ -0,0 +1,31 @@ +mod bindings; + +use crate::bindings::exports::golem::component::api::*; +use std::cell::RefCell; + +/// This is one of any number of data types that our application +/// uses. Golem will take care to persist all application state, +/// whether that state is local to a function being executed or +/// global across the entire program. +struct State { + total: u64, +} + +thread_local! { + /// This holds the state of our application. + static STATE: RefCell = RefCell::new(State { + total: 0, + }); +} + +struct Component; + +impl Guest for Component { + fn add(value: u64) { + STATE.with_borrow_mut(|state| state.total += value); + } + + fn get() -> u64 { + STATE.with_borrow(|state| state.total) + } +} diff --git a/wit/yoyo.wit b/wit/yoyo.wit new file mode 100644 index 0000000..1961e20 --- /dev/null +++ b/wit/yoyo.wit @@ -0,0 +1,12 @@ +package golem:component; + +// See https://github.com/WebAssembly/component-model/blob/main/design/mvp/WIT.md for more details about the WIT syntax + +interface api { + add: func(value: u64); + get: func() -> u64; +} + +world yoyo { + export api; +} \ No newline at end of file