Ecosyste.ms: Awesome

An open API service indexing awesome lists of open source software.

Awesome Lists | Featured Topics | Projects

https://github.com/simonneutert/Joda

JRuby + Roda == Joda ๐Ÿ––
https://github.com/simonneutert/Joda

api jdbc jruby jvm jvm-applications jvm-languages puma roda router ruby sequel

Last synced: about 1 month ago
JSON representation

JRuby + Roda == Joda ๐Ÿ––

Awesome Lists containing this project

README

        

# Joda ๐Ÿ–– == JRuby + Roda

And here it is ๐ŸŽ‰ My template for Ruby's notorious web router [Roda](https://roda.jeremyevans.net) - running on the JVM ([JRuby](https://www.jruby.org))! ๐ŸŒ‹

Start the server with `$ rackup`, then benchmark (see below) as unscientifically as possible (but easy as pie), using [HTTPie](https://httpie.io):

_๐Ÿคซ or for production sth like: `$ jruby --server -S bundle exec rackup -o 0 -E production`_

`$ time http :9292/jsondata >/dev/null`
sucks 25mb from your server ๐Ÿง›โ€โ™€๏ธ

Add [rodauth](https://github.com/jeremyevans/rodauth) to have a proper user account management ๐Ÿคฏ

## Why though?

I cannot really say why JRuby intriqued me, since I fell in love with Ruby.
But, JRuby never felt especially beginner friendly. ๐Ÿ˜ฌ
Something didn't work. Very tough to google. JDBC what?
Java docs?! Java ecosystem?! They do what? How on earth? Cheesus ... ๐Ÿคข

## This repository is aimed at

- curious Rubyists, struggling to find a use case of getting something up with [JRuby](https://www.jruby.org)
- those who want get hold of JRuby, without the suspicious feeling that Rails takes care of everything behind the curtains (it's why we love you, Rails, you know that! ๐Ÿ˜˜)
- People curious of [Roda](https://roda.jeremyevans.net)
- PORO lovers
- [Rack](https://github.com/rack/rack) fanboys
- [Sinatra](https://sinatrarb.com) / [Fastify](https://www.fastify.io) / [FastAPI](https://fastapi.tiangolo.com) / [Gin](https://github.com/gin-gonic/gin)
- Java people / JVM users โ˜•๏ธ
- those on a journey, they don't know, they are on: Ruby โžก JRuby โžก [Clojure](https://clojure.org/guides/getting_started) โ˜ฎ๏ธ

## Run

Your Java version should be pinned to `11.x` as this is what the CI is running on. MacOS checks for JRuby run on Java v8.

if one of you gets this going on another OS, please submit a PR with some handy notes โœŒ๏ธ

### Docker

- `$ docker build . -t joda`
- `$ docker run --rm -it -p9292:9292 joda`

#### with jemalloc

For aarch64 (e.g. Mac M1):

- `$ docker run -ti --env LD_PRELOAD=/usr/lib/aarch64-linux-gnu/libjemalloc.so.2 --rm -p9292:9292`

For x86_64:

- `$ docker run -ti --env LD_PRELOAD=/usr/lib/x86_64-linux-gnu/libjemalloc.so.2 --rm -p9292:9292`

#### Production

๐Ÿš€

- `$ docker run -ti --env LD_PRELOAD=/usr/lib/aarch64-linux-gnu/libjemalloc.so.2 --rm -p9292:9292 rackup -o 0 -E production`

### MacOS and asdf

please, see the docs of your [asdf-vm](https://asdf-vm.com) java plugin ([docs of the default java plugin ๐Ÿ“–](https://github.com/halcyon/asdf-java#java_home)). It's about JRuby having Java in it's PATH.

Then fire the following commands:

- `$ asdf install java microsoft-17.35.1`
- `$ asdf reshim`
- `$ asdf install ruby jruby-9.4.1.0`
- `$ bundle install -j4`
- `$ jruby -S rackup`

## Profiling JRuby

`$ jruby --profile.graph -S rackup`

## JVM Options

This is how you could use it for production:
`$ jruby -J-Xmx512m --server -S rackup -E production`

- minimum and maximum Java heap size to 512 MB
- optimization for server ON
- runs Rack in production mode

or:

`$ jruby -J-Xms2g -J-Xmx2g --server -J-Djruby.thread.pool.enabled=true -S rackup -E production`

## Benchmarks ๐Ÿฅผ๐Ÿงช๐Ÿ’ป

**FIRST OF ALL** the JVM had some requests before the benchs to warm up a little
**BUT** let's be honest the server wasn't fresh and had already other stuff to do
**AND** had just 2 cores (but 8 gigs of RAM ๐Ÿ˜…)
**AND** for sure I missed an opportunity for tweaking something
**BECAUSE** the JVM still is completely new to me at this point
**SO** this is worthless, but some just need to see some numbers

well, enough whining...

- [ab](https://httpd.apache.org/docs/2.4/programs/ab.html) (comes pre-installed on MacOS)
- [wrk](https://github.com/wg/wrk) (i.e. `$ brew install wrk`)

### Benchmarking with [ab](https://httpd.apache.org/docs/2.4/programs/ab.html):

`$ ab -n 1000 -c 10 -k -H "Accept-Encoding: gzip, deflate" "https://joda.test.test/hello/world"`

```bash
This is ApacheBench, Version 2.3 <$Revision: 1879490 $>
Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/
Licensed to The Apache Software Foundation, http://www.apache.org/

Benchmarking joda.test.test (be patient)
[...shortened...]

Server Software:
Server Hostname: joda.test.test
Server Port: 443
SSL/TLS Protocol: TLSv1.2,ECDHE-RSA-CHACHA20-POLY1305,4096,256
Server Temp Key: ECDH X25519 253 bits
TLS Server Name: joda.test.test

Document Path: /hello/world
Document Length: 38 bytes

Concurrency Level: 10
Time taken for tests: 11.268 seconds
Complete requests: 1000
Failed requests: 0
Keep-Alive requests: 0
Total transferred: 166000 bytes
HTML transferred: 38000 bytes
Requests per second: 88.74 [#/sec] (mean)
Time per request: 112.685 [ms] (mean)
Time per request: 11.268 [ms] (mean, across all concurrent requests)
Transfer rate: 14.39 [Kbytes/sec] received

Connection Times (ms)
min mean[+/-sd] median max
Connect: 49 78 14.4 77 137
Processing: 12 33 22.0 22 113
Waiting: 11 23 12.1 17 77
Total: 64 111 26.2 105 244

Percentage of the requests served within a certain time (ms)
50% 105
66% 117
75% 126
80% 131
90% 151
95% 164
98% 176
99% 186
100% 244 (longest request)
```

### Benchmarking with [wrk](https://github.com/wg/wrk):

`$ wrk -t10 -c10 -d30s "https://joda.test.test/hello/world"`

```bash
Running 30s test @ https://joda.test.test/hello/world
10 threads and 10 connections
Thread Stats Avg Stdev Max +/- Stdev
Latency 23.21ms 15.14ms 81.68ms 84.52%
Req/Sec 46.87 15.47 80.00 62.34%
14065 requests in 30.10s, 2.07MB read
Requests/sec: 467.21
Transfer/sec: 70.28KB
```

#### Device

| | |
| --------------------- | ----------------------------------- |
| Model Name | MacBook Pro |
| Model Identifier | MacBookPro18,1 |
| Chip | Apple M1 Pro |
| Total Number of Cores | 10 (8 performance and 2 efficiency) |
| Memory | 16 GB |

## Thought Section

Entering this fancy new rabbit hole, here's what didn't work, or may well be served with butter in the future

#### Database

when load testing `/jsondata/items` route:

- H2 database is run with `single_threaded: true` and seems to be able to handle higher loads nicely ๐Ÿ‘
https://sequel.jeremyevans.net/rdoc/files/doc/opening_databases_rdoc.html#label-General+connection+options

- H2 database may crash though, especially without `single_threaded` option, and throw horrifying errors, I propose you use Postgres/MySQL/AnyOtherProperDB for mimicking "real-life" server simulation

#### Roda

there's so much beauty in Roda, so it would be nice to showcase more of it.

I suggest you stumble through the following websites:

- [Roda's Website](https://roda.jeremyevans.net)
- Federico's and [Avdi](https://avdi.codes)'s Book: [Mastering Roda](https://fiachetti.gitlab.io/mastering-roda/)
- [Jeremy Evans' Code Lair](https://code.jeremyevans.net/ruby.html) (sequel, rodauth, and many more)

---

#### Credits

- large file json taken from:
https://github.com/json-iterator/test-data/blob/master/large-file.json

- Inspiration sparked the amazing [Ruby for all Podcast](https://www.rubyforall.com/) ๐Ÿ‘‹ You guys rock!

#### SEO Stuff ๐Ÿคญ

Tags/Keywords: Ruby, JRuby, Java, Roda, Sequel, JDBC, Puma, REST, API, JSON