diff options
| author | unitexe <unitexe70@gmail.com> | 2026-01-14 16:43:19 -0600 |
|---|---|---|
| committer | unitexe <unitexe70@gmail.com> | 2026-01-14 16:43:37 -0600 |
| commit | 2ad73c4ea94d42579661dce3074cc075f52e6cc7 (patch) | |
| tree | 5f50c05d2b4de11fd9c586cf867d9d21acbc5aa0 | |
Initial commit
| -rw-r--r-- | .gitignore | 22 | ||||
| -rw-r--r-- | Cargo.toml | 14 | ||||
| -rw-r--r-- | Containerfile | 37 | ||||
| -rw-r--r-- | LICENSE | 21 | ||||
| -rw-r--r-- | build.rs | 4 | ||||
| -rw-r--r-- | proto/countah.proto | 13 | ||||
| -rw-r--r-- | src/main.rs | 57 |
7 files changed, 168 insertions, 0 deletions
diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..ab951f8 --- /dev/null +++ b/.gitignore @@ -0,0 +1,22 @@ +# ---> Rust +# Generated by Cargo +# will have compiled files and executables +debug/ +target/ + +# Remove Cargo.lock from gitignore if creating an executable, leave it for libraries +# More information here https://doc.rust-lang.org/cargo/guide/cargo-toml-vs-cargo-lock.html +Cargo.lock + +# These are backup files generated by rustfmt +**/*.rs.bk + +# MSVC Windows builds of rustc generate these, which store debugging information +*.pdb + +# RustRover +# JetBrains specific template is maintained in a separate JetBrains.gitignore that can +# be found at https://github.com/github/gitignore/blob/main/Global/JetBrains.gitignore +# and can be added to the global gitignore or merged into this file. For a more nuclear +# option (not recommended) you can uncomment the following to ignore the entire idea folder. +#.idea/ diff --git a/Cargo.toml b/Cargo.toml new file mode 100644 index 0000000..1be61ee --- /dev/null +++ b/Cargo.toml @@ -0,0 +1,14 @@ +[package] +name = "pubd" +version = "0.1.0" +edition = "2024" + +[dependencies] +prost = "0.14.3" +tokio = { version = "1.49.0", features = ["macros", "rt-multi-thread"] } +tokio-stream = "0.1.18" +tonic = "0.14.2" +tonic-prost = "0.14.2" + +[build-dependencies] +tonic-prost-build = "0.14.2" diff --git a/Containerfile b/Containerfile new file mode 100644 index 0000000..4c8852b --- /dev/null +++ b/Containerfile @@ -0,0 +1,37 @@ +# A multi-stage container file for the pubd application. + +# +# Build stage +# + +FROM rust:1.91-alpine3.23 AS builder + +RUN apk add --no-cache musl-dev protobuf-dev + +WORKDIR /app + +COPY Cargo.toml Cargo.lock* ./ + +COPY proto ./proto + +COPY build.rs ./ + +COPY src ./src + +RUN cargo build --release + +# +# Run stage +# + +FROM alpine:latest + +RUN apk add --no-cache libgcc + +WORKDIR /app + +COPY --from=builder /app/target/release/pubd /app/pubd + +EXPOSE 60069 + +CMD ["/app/pubd"] @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2025 Closed Circuit Consulting + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE.
\ No newline at end of file diff --git a/build.rs b/build.rs new file mode 100644 index 0000000..5005f6f --- /dev/null +++ b/build.rs @@ -0,0 +1,4 @@ +fn main() -> Result<(), Box<dyn std::error::Error>> { + tonic_prost_build::configure().compile_protos(&["proto/countah.proto"], &["proto/"])?; + Ok(()) +} diff --git a/proto/countah.proto b/proto/countah.proto new file mode 100644 index 0000000..698c3db --- /dev/null +++ b/proto/countah.proto @@ -0,0 +1,13 @@ +syntax = "proto3"; + +package unit.countah.v0; + +service Countah { + rpc Counter (CounterRequest) returns (stream CounterResponse); +} + +message CounterRequest { } + +message CounterResponse { + fixed64 count = 1; +} diff --git a/src/main.rs b/src/main.rs new file mode 100644 index 0000000..fa3657c --- /dev/null +++ b/src/main.rs @@ -0,0 +1,57 @@ +pub mod pb { + tonic::include_proto!("unit.countah.v0"); +} + +use std::pin::Pin; +use tokio_stream::Stream; +use tokio_stream::wrappers::ReceiverStream; +use tonic::{Request, Response, Status, transport::Server}; + +use crate::pb::{CounterRequest, CounterResponse}; + +#[derive(Debug, Default)] +pub struct PubdServer {} + +#[tonic::async_trait] +impl pb::countah_server::Countah for PubdServer { + type CounterStream = Pin<Box<dyn Stream<Item = Result<CounterResponse, Status>> + Send>>; + + async fn counter( + &self, + _request: Request<CounterRequest>, + ) -> Result<Response<Self::CounterStream>, Status> { + let (tx, rx) = tokio::sync::mpsc::channel(128); + + tokio::spawn(async move { + let mut count: u64 = 0; + loop { + count += 1; + let response = CounterResponse { count }; + + if tx.send(Ok(response)).await.is_err() { + break; + } + + tokio::time::sleep(tokio::time::Duration::from_secs(1)).await; + } + }); + + let stream = ReceiverStream::new(rx); + Ok(Response::new(Box::pin(stream))) + } +} + +#[tokio::main] +async fn main() -> Result<(), Box<dyn std::error::Error>> { + let addr = "0.0.0.0:60069".parse().unwrap(); + let server = PubdServer::default(); + + println!("Listening on {}", addr); + + Server::builder() + .add_service(pb::countah_server::CountahServer::new(server)) + .serve(addr) + .await?; + + Ok(()) +} |
