-
Notifications
You must be signed in to change notification settings - Fork 1
feat: Basic functionality for serving apis #4
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Changes from all commits
Commits
Show all changes
27 commits
Select commit
Hold shift + click to select a range
c4b1985
feat: adds main lib and errors classes
bougyman c4e4ec1
chore: Adds group to Gemfile
bougyman 7a4fccc
feat: Adds basic message wrapper
bougyman 015af76
feat: Basic api server using message wrapper
bougyman 21f66db
test: Adds test for message wrapper
bougyman f6b877d
test: Adds tests for nats_api_server
bougyman 3db03e7
doc: Fills in Readme with current functionality
bougyman ac6cfe1
fix: Remove redundant include of Dry::Configurable
bougyman fa18aa2
doc: Adds link for Dry::Configurable and removes useless internal set…
bougyman e44ecc6
feat: Ditch Ractors for Concurrent::FixedThreadPool
bougyman 80683c2
feat: Adds #group to namespace endpoints
bougyman d32da82
chore: Be more leniant with documentation commit messages
bougyman bf13d94
docs: Updates Readme about the change to Concurrent::FixedThreadPool
bougyman 9136639
docs: Adds bits about Dry::Monads
bougyman fd456c2
docs: Clarifies endpoint mappings
bougyman dcbf2b4
fix: Fixes example echo service
bougyman 114d70e
fix: Got monads at all scope levels
bougyman 549edc6
fix: Extend the base module to reduce boilerplate
bougyman 3781a6e
fix: Get semantic logger out of the example
bougyman 565ab55
feat: Adds some basic logging
bougyman 1e8b0e4
fix: Do not auto require nats api server itself
bougyman 7efe571
docs: Added method documentation
bougyman 777612b
Merge branch 'main' into filling-in-functionality
bougyman f09b4f8
docs: Important note about the callback return expectation
bougyman 746c72a
style: Rubocop fixes
bougyman 3755f51
test: Removes the #run from specs for now, stubbing wasn not working
bougyman 9642c8c
feat: Adds non-blocking mode
bougyman File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,5 +1,6 @@ | ||
| *.gem | ||
| *.rbc | ||
| *.swp | ||
| /.config | ||
| /coverage/ | ||
| /InstalledFiles | ||
|
|
||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,9 +1,109 @@ | ||
| # Leopard Nats ServiceApi Server | ||
| = Leopard NATS ServiceApi Server | ||
| bougyman <[email protected]> | ||
| :service-api: https://github.com/rubyists/nats-pure.rb/blob/main/docs/service_api.md[Service API] | ||
| :service-api: https://github.com/rubyists/nats-pure.rb/blob/main/docs/service_api.md[NATS Service API] | ||
| :conventional-commits: https://www.conventionalcommits.org/en/v1.0.0/[Conventional Commits] | ||
| :dry-configurable: https://github.com/dry-rb/dry-configurable[Dry::Configurable] | ||
| :dry-monads: https://github.com/dry-rb/dry-monads[Dry::Monads] | ||
|
|
||
| The leopard nats serviceapi server provides a simple concurrency | ||
| model for NATS {service-api} workers. It is designed to be used | ||
| similarly to a web server (inspired by puma), defining endpoints | ||
| in your classes, and then serving them via the leopard (Ractor-based) | ||
| service supervisor. | ||
| Leopard is a small framework for building concurrent {service-api} workers. | ||
| It uses `Concurrent::FixedThreadPool` to manage multiple workers in a single process and provides a | ||
| minimal DSL for defining endpoints and middleware. | ||
|
|
||
| == Features | ||
|
|
||
| * Declarative endpoint definitions with `endpoint`. | ||
| * Middleware support using `use`. | ||
| * Simple concurrency via `run` with a configurable number of instances. | ||
| * JSON aware message wrapper that gracefully handles parse errors. | ||
| * Railway Oriented Design, using {dry-monads} for success and failure handling. | ||
| * {dry-configurable} settings container. | ||
|
|
||
| == Requirements | ||
|
|
||
| * Ruby >= 3.3.0 | ||
| * A running NATS server with the Service API enabled. | ||
|
|
||
| == Installation | ||
|
|
||
| Add the gem to your project: | ||
|
|
||
| [source,ruby] | ||
| ---- | ||
| # Gemfile | ||
| gem 'leopard' | ||
| ---- | ||
|
|
||
| Then install it with Bundler. | ||
|
|
||
| [source,bash] | ||
| ---- | ||
| $ bundle install | ||
| ---- | ||
|
|
||
| == Usage | ||
|
|
||
| Create a service class and include `Rubyists::Leopard::NatsApiServer`. | ||
| Define one or more endpoints. Each endpoint receives a | ||
| `Rubyists::Leopard::MessageWrapper` object for each request to the {service-api} endpoint | ||
| that service class is is subscribed to (subject:, or name:). The message handler/callback | ||
| is expected to return a `Dry::Monads[:result]` object, typically a `Success` or `Failure`. | ||
|
|
||
| [source,ruby] | ||
| ---- | ||
| class EchoService | ||
| include Rubyists::Leopard::NatsApiServer | ||
|
|
||
| endpoint :echo do |msg| | ||
| Success(msg.data) | ||
| end | ||
| end | ||
| ---- | ||
|
|
||
| Run the service by providing the NATS connection details and service options: | ||
|
|
||
| [source,ruby] | ||
| ---- | ||
| EchoService.run( | ||
| nats_url: 'nats://localhost:4222', | ||
| service_opts: { name: 'echo' }, | ||
| instances: 4 | ||
| ) | ||
| ---- | ||
|
|
||
| Middleware can be inserted around endpoint dispatch: | ||
|
|
||
| [source,ruby] | ||
| ---- | ||
| class LoggerMiddleware | ||
| def initialize(app) | ||
| @app = app | ||
| end | ||
|
|
||
| def call(wrapper) | ||
| puts "received: #{wrapper.data.inspect}" | ||
| @app.call(wrapper) | ||
| end | ||
| end | ||
|
|
||
| EchoService.use LoggerMiddleware | ||
| ---- | ||
|
|
||
| == Development | ||
|
|
||
| The project uses Minitest and RuboCop. Run tests with Rake: | ||
|
|
||
| [source,bash] | ||
| ---- | ||
| $ bundle exec rake | ||
| ---- | ||
|
|
||
| === Conventional Commits (semantic commit messages) | ||
|
|
||
| This project follows the {conventional-commits} specification. | ||
|
|
||
| To contribute, please follow that commit message format, | ||
| or your pull request may be rejected. | ||
|
|
||
| == License | ||
|
|
||
| MIT |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,27 @@ | ||
| # Client port of 4222 on all interfaces | ||
| port: 4222 | ||
|
|
||
| # HTTP monitoring port | ||
| monitor_port: 8222 | ||
|
|
||
| accounts: { | ||
| $SYS: { | ||
| users: [ | ||
| { user: sys, password: sys } | ||
| ] | ||
| } | ||
| ME: { | ||
| jetstream: enabled | ||
| users: [ | ||
| { user: me, password: youandme } | ||
| ] | ||
| } | ||
| } | ||
| no_auth_user: me | ||
|
|
||
| authorization { | ||
| default_permissions = { | ||
| publish = ">" | ||
| subscribe = ">" | ||
| } | ||
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,33 @@ | ||
| #!/usr/bin/env bash | ||
|
|
||
| NATS_VERSION=2 | ||
|
|
||
| if readlink -f . >/dev/null 2>&1 # {{{ makes readlink work on mac | ||
| then | ||
| readlink=readlink | ||
| else | ||
| if greadlink -f . >/dev/null 2>&1 | ||
| then | ||
| readlink=greadlink | ||
| else | ||
| printf "You must install greadlink to use this (brew install coreutils)\n" >&2 | ||
| fi | ||
| fi # }}} | ||
|
|
||
| # Set here to the full path to this script | ||
| me=${BASH_SOURCE[0]} | ||
| [ -L "$me" ] && me=$($readlink -f "$me") | ||
| here=$(cd "$(dirname "$me")" && pwd) | ||
| just_me=$(basename "$me") | ||
| export just_me | ||
|
|
||
| cd "$here" || exit 1 | ||
| if command -v podman 2>/dev/null | ||
| then | ||
| runtime=podman | ||
| else | ||
| runtime=docker | ||
| fi | ||
|
|
||
| set -x | ||
| exec "$runtime" run --rm -it -p 4222:4222 -p 6222:6222 -p 8222:8222 -v ./accounts.txt:/accounts.txt nats:"$NATS_VERSION" -js -c /accounts.txt "$@" |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,19 @@ | ||
| #!/usr/bin/env ruby | ||
| # frozen_string_literal: true | ||
|
|
||
| require_relative '../lib/leopard/nats_api_server' | ||
|
|
||
| # Example to echo the given message | ||
| class EchoService | ||
| include Rubyists::Leopard::NatsApiServer | ||
|
|
||
| endpoint(:echo) { |msg| Success(msg.data) } | ||
| end | ||
|
|
||
| if __FILE__ == $PROGRAM_NAME | ||
| EchoService.run( | ||
| nats_url: 'nats://localhost:4222', | ||
| service_opts: { name: 'example.echo', version: '1.0.0' }, | ||
| instances: 4, | ||
| ) | ||
| end |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,21 @@ | ||
| # frozen_string_literal: true | ||
|
|
||
| require 'dry/configurable' | ||
| require 'pathname' | ||
| require 'semantic_logger' | ||
| SemanticLogger.add_appender(io: $stdout, formatter: :color) | ||
|
|
||
| class Pathname | ||
| def /(other) | ||
| join other.to_s | ||
| end | ||
| end | ||
|
|
||
| module Rubyists | ||
| module Leopard | ||
| end | ||
| end | ||
|
|
||
| require_relative 'leopard/settings' | ||
| require_relative 'leopard/version' | ||
| require_relative 'leopard/errors' | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,8 @@ | ||
| # frozen_string_literal: true | ||
|
|
||
| module Rubyists | ||
| module Leopard | ||
| class Error < StandardError; end | ||
| class ConfigurationError < Error; end | ||
| end | ||
| end |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.