diff --git a/README.md b/README.md new file mode 100644 index 0000000..ffe7b61 --- /dev/null +++ b/README.md @@ -0,0 +1,77 @@ +# Virtual threads experiences +## General information +This project aims to show what is the developer experience when the virtual threads are used, in comparison of the framework Reactor. + +Therefore, there is one spring boot application which uses "standard java code" with virtual threads, and another spring boot application which uses Reactor. + +## Spring boot applications +### Common concepts +Both applications are developed to serve same endpoints with same models. + + + +### Architecture +Both applications are architectured with a "light" version of the hexagonal architecture. + +Java packages represent the hexagonal architecture modules: +- domain (Business code) +- exposition (Rest API) +- infrastructure (JPA layer) + +#### Models +[](./doc/images/models.png) + +#### Exposed endpoints + - Catalogs + - GET /api/catalogs/{catalogId} + - Items + - GET /api/items + - POST /api/items + - Marketplace + - GET /api/marketplace + +### Virtual threads application +The application runs on port `51001`. + +```bash +./gradlew :virtual-threads-app:bootRun +``` + +### Reactor application +The application runs on port `52001`. + +To start the application, run this command: +```bash +./gradlew :reactor-app:bootRun +``` + +## Database +The database is a PostgreSQL database which runs inside a container. + +To start the database, just run this command inside the project root folder: +```bash +docker compose up --detach --file ./docker-compose.yml +``` + +Then, you will have to initialise the tables by executing scripts located [there](./src/main/sql/init_database.sql) into the container. + +You can connect to it with this "unix" command: +```bash +docker exec --interactive --tty virtual-threads-test-db /bin/bash +psql --host localhost --port 5432 --username virtual_threads_test_user virtual_threads_test_db +``` + +### Database files +There is a volumes for the database container, which points to this location: [local/postgresql](./local/postgresql). + +## Bruno http client collection +There is a collection of queries, usable with [bruno](https://www.usebruno.com/). It is located inside the [rest-client-collection](./rest-client-collection). + +## Load testing +Load tests use K6 framework. + +### Targeting the application to test +By default, tests are configured to load the `virtual-threads-app`. + +If you want to run them on the `reactor-app`, you have to edit the variable `TARGET_URL` inside the file [config.ts](./k6-load-tests/src/tests/config.ts). + diff --git a/doc/images/models.png b/doc/images/models.png new file mode 100644 index 0000000..55102c5 Binary files /dev/null and b/doc/images/models.png differ diff --git a/doc/sources_of_model_schema_built_with_umlet.uxf b/doc/sources_of_model_schema_built_with_umlet.uxf new file mode 100644 index 0000000..49a36a9 --- /dev/null +++ b/doc/sources_of_model_schema_built_with_umlet.uxf @@ -0,0 +1,37 @@ +10UMLClass7305009060Catalog +-- +id: UUID +name: StringUMLClass73058018080Item +-- +id: UUID +name: String +sharedDate: ZonedDateTimeUMLClass5904109050Marketplace +-- +Relation620450130100lt=- +m1=0..* +m2=0..*10;10;10;70;110;70Relation590450160180lt=- +m1=0..* +m2=0..*10;10;10;150;140;150UMLNote55034040030Domain +bg=blueUMLNote2034040030Exposition +bg=redUMLNote108034040030Infrastructure +bg=greenRelation90450130100lt=- +m1=0..* +m2=0..*10;10;10;70;110;70Relation60450160180lt=- +m1=0..* +m2=0..*10;10;10;150;140;150UMLClass2005009060CatalogDto +-- +id: UUID +name: StringUMLClass20058018080ItemDto +-- +id: UUID +name: String +isShared: BooleanUMLClass5041011050MarketplaceDto +-- +UMLClass112047013060CatalogJpaEntity +-- +id: UUID +name: StringUMLClass128046018080ItemJpaEntity +-- +id: UUID +name: String +sharedDate: ZonedDateTime \ No newline at end of file diff --git a/k6-load-tests/configuration.yml b/k6-load-tests/configuration.yml deleted file mode 100644 index 9118bdb..0000000 --- a/k6-load-tests/configuration.yml +++ /dev/null @@ -1,3 +0,0 @@ -target: - url: http://localhost - port: 51001 \ No newline at end of file diff --git a/k6-load-tests/package.json b/k6-load-tests/package.json index 522ddca..a1b9e6f 100644 --- a/k6-load-tests/package.json +++ b/k6-load-tests/package.json @@ -6,10 +6,7 @@ "type": "module", "scripts": { "build": "vite build", - "test:demo": "yarn build && k6 run dist/tests/load-tests.cjs", - "test:demo-stages": "yarn build && k6 run dist/tests/reqres-stages.cjs", - "test-with-monitoring:demo": "yarn build && docker run --platform linux/amd64 -it -p 5665:5665 -v $(pwd)/dist/:/src ghcr.io/grafana/xk6-dashboard:0.6.1 run --out 'dashboard=period=2s' /src/tests/reqres.cjs", - "test-with-monitoring:demo-stages": "yarn build && docker run --platform linux/amd64 -it -p 5665:5665 -v $(pwd)/dist/:/src ghcr.io/grafana/xk6-dashboard:0.6.1 run --out 'dashboard=period=2s' /src/tests/reqres-stages.cjs" + "start": "yarn build && k6 run dist/tests/load-tests.cjs" }, "devDependencies": { "@babel/core": "7.23.3", diff --git a/k6-load-tests/src/apis/marketplace-apis.ts b/k6-load-tests/src/apis/marketplace-apis.ts index 3ae3bbe..d455e09 100644 --- a/k6-load-tests/src/apis/marketplace-apis.ts +++ b/k6-load-tests/src/apis/marketplace-apis.ts @@ -4,6 +4,7 @@ import {logWaitingTime} from "../utils/logger"; import {Trend} from "k6/metrics"; import {check} from "k6"; import {Response} from "../data/common"; +import {TARGET_URL} from "../tests/config"; // Metrics that we want to track const metrics = { @@ -11,9 +12,7 @@ const metrics = { }; export const getMarketplace = (): Response => { - const serverUrl = `http://localhost:51001`; - - const urlToTest = `${serverUrl}/api/marketplace`; + const urlToTest = `${TARGET_URL}/api/marketplace`; const response = http.get(urlToTest); logWaitingTime({ diff --git a/k6-load-tests/src/tests/config.ts b/k6-load-tests/src/tests/config.ts index 267dcdc..8088f40 100644 --- a/k6-load-tests/src/tests/config.ts +++ b/k6-load-tests/src/tests/config.ts @@ -1 +1,6 @@ -export const VUs = 1 \ No newline at end of file +export const VUs = 1; +// @ts-ignore - if it is unused +const VIRTUAL_THREADS_APP_PORT = 51001; +// @ts-ignore - if it is unused +const REACTOR_APP_PORT = 52001; +export const TARGET_URL = `http://localhost:${VIRTUAL_THREADS_APP_PORT}`; \ No newline at end of file diff --git a/local/postgresql/.gitkeep b/local/postgresql/.gitkeep new file mode 100644 index 0000000..e69de29