tcp-server-jruby
This is a small tcp server for JRuby available as a ruby gem.
It is based on the Netty project. Netty is written in java, but I wanted to write ruby.
Quick-start
Follow these instructions to get a tcp server echo program running.
Container
You may run the websocket server in a container. Using [colima]
for a container runtime is recommended.
colima start
docker-compose up --detach
nc localhost 4000
docker-compose down
Building the image or running the container:
docker build --tag tcp-server-jruby .
docker run --detach --publish 4000:4000 --name tcp-server-jruby tcp-server-jruby
Manually
If one insists, one may run everything directly with the required dependencies installed.
Install mise-en-place
The mise CLI tool used to manage multiple runtime versions.
See: https://mise.jdx.dev/getting-started.html
curl https://mise.jdx.dev/install.sh | sh
~/.local/bin/mise --version
mise 2024.x.x
Enable mise activation in future zsh sessions.
echo 'eval "$(~/.local/bin/mise activate zsh)"' >> ~/.zshrc
Install required runtime software
Use mise to install the runtime software defined as requirements
in the .tool-versions file.
mise install
Install the project dependencies.
gem install bundler
bundle install
Run
The entrypoint for the web application service may now be invoked from a command line interface terminal shell.
bundle exec ./tcp_server.rb
Build the gem
To run linting, unit tests, build the gem file, execute:
bundle exec rake
Publish the gem
To publish the gem after first verifying that the built gem works, execute:
version=$(ruby -r lib/server/version -I . -e 'puts ::Server::VERSION')
git tag --annotate --message "Release ${version}" "${version}-release"
git push origin --tags
Or manually, if necessary:
bundle exec rake verify
bundle exec rake publish
Clean up gem artifacts
To clean the project, execute:
bundle exec rake clean clobber
Project file tree
Here is a bird's-eye view of the project layout.
Sat Jul 23 22:12:37 CDT 2022
.
├── Dockerfile
├── Gemfile
├── Gemfile.lock
├── LICENSE
├── README.md
├── Rakefile
├── docker-compose.yaml
├── exe
│ └── tcp_server
├── lib
│ ├── client.rb
│ ├── demo_listener.rb
│ ├── logging.rb
│ ├── server
│ │ ├── argument_parser.rb
│ │ ├── channel_initializer.rb
│ │ ├── config.rb
│ │ ├── instance_methods.rb
│ │ ├── listenable.rb
│ │ ├── message_handler.rb
│ │ ├── modular_handler.rb
│ │ ├── server.rb
│ │ ├── shutdown_hook.rb
│ │ └── version.rb
│ ├── server.rb
│ ├── tcp-server.rb
│ └── tcp_server.rb
├── spec
│ ├── spec_helper.rb
│ ├── test_spec.rb
│ └── verify
│ └── verify_spec.rb
├── tcp-server-1.0.8-java.gem
├── tcp-server-jruby.gemspec
├── tcp_server.png
└── tcp_server.rb
5 directories, 31 files
CI linting
Use the GitLab CI Linting API to validate the syntax of a CI definition file.
jq --null-input --arg yaml "$(<.gitlab/ci/gem.gitlab-ci.yml)" '.content=$yaml' | curl --silent --location https://gitlab.com/api/v4/ci/lint --header "PRIVATE-TOKEN: ${GITLAB_COM_API_PRIVATE_TOKEN}" --header "Content-Type: application/json" --data @- | jq --raw-output '.errors[0]'
CI configuration
Generate a deploy key.
ssh-keygen -t ed25519 -P '' -C deploy_key -f deploy_key_ed25519
Use the GitLab Project-level Variables API to add the deploy key as a ssh private key variable.
project_path="nelsnelson/$(basename $(pwd))"
curl --silent --show-error --location "https://gitlab.com/api/v4/projects" --header "PRIVATE-TOKEN: ${GITLAB_COM_API_PRIVATE_TOKEN}" | jq '.[0]["id"]'
project=$(curl --silent --show-error --location "https://gitlab.com/api/v4/search?scope=projects&search=${project_path}" --header "PRIVATE-TOKEN: ${GITLAB_COM_API_PRIVATE_TOKEN}" | jq --arg project_path "${project_path}" '.[] | select(.path_with_namespace == $project_path)')
project_id=$(curl --silent --show-error --location "https://gitlab.com/api/v4/search?scope=projects&search=${project_path}" --header "PRIVATE-TOKEN: ${GITLAB_COM_API_PRIVATE_TOKEN}" | jq --arg project_path "${project_path}" '.[] | select(.path_with_namespace == $project_path) | .id')
curl --silent --show-error --location --request POST "https://gitlab.com/api/v4/projects/${project_id}/variables" --header "PRIVATE-TOKEN: ${GITLAB_COM_API_PRIVATE_TOKEN}" --form "key=SSH_PRIVATE_KEY" --form "value=$(cat ./deploy_key_ed25519)" --form "protected=true" | jq
Use the Deploy keys API to add a the public deploy key as a deploy key for the project.
curl --silent --show-error --location --request POST "https://gitlab.com/api/v4/projects/${project_id}/deploy_keys" --header "PRIVATE-TOKEN: ${GITLAB_COM_API_PRIVATE_TOKEN}" --form "title=deploy_key" --form "key=$(cat ./deploy_key_ed25519.pub)" --form "can_push=true" | jq