Skip to content

Latest commit

 

History

History
170 lines (112 loc) · 5.06 KB

CONTRIBUTING.md

File metadata and controls

170 lines (112 loc) · 5.06 KB

CONTRIBUTION GUIDE

TO BE UPDATED

TODO : Add part to describe the role of each folder

Service Contribution

Target folders :

Foreword

Definition

A service is a combination of a language, a web framework, dao/orm lib (optional) and a webserver (optional).

Name convention

[ecosytem-]language-framework[-dao][-webserver]

Example :

  • go-pgx (go as the language, pgx as the dao lib)
  • jvm-kotlin-spring (jvm as the ecosytem, kotlin as the language, spring as the framework)
  • php-symfony-apache2 (php as the language, symfony as the framework, apache2 as the webserver).

Implementation Spirit

Remember that is not a benchmark to make language competition. But an eco benchmark to identify which design choice got impact on web application footprint on our planet. Design should represent practices from the communities.

Degraded use case

In order to compare other design choice than framework and language, there is a list of predefined use case documented. See use case documentation Each use case got a design difference (and only one).

Design rules

Each service must respect :

  • an API contract,
  • a predefined set of SQL requests by API to respect.
  • for some service, algorithm to respect.

Reference implementation is the golang implementation.

Acceptance criteria

Service should pass the conformity tests - For help to execute test go here : https://github.com/karatelabs/karate

Service's docker should have 2 environment variables :

  • DATABASE_URL : Example of value injected: postgres://postgres:mysecretpassword@database:5432/postgres - url signature can be change for each service
  • DATABASE_POOL_MAX : setup to 20 by default

API Contract

API Contract must respect the following API Definition documentation.

SQL requests

Each API endpoint must respect the following SQL request.


NOTE

Due to ORM behavior you may have small difference in the real generated SQL. Please just check if there is no major differences and document the minor differences.


POST /api/accounts

INSERT INTO account(id, login, creation_date) values ($1, $2, $3);

POST /api/accounts/:account/lists

INSERT INTO list(id, account_id, name, creation_date) values ($1, $2, $3, $4);

POST /api/lists/:list/tasks

INSERT INTO task(id, list_id, name, description, creation_date) values ($1, $2, $3, $4, $5);

GET /api/accounts/:account/lists?page=n

SELECT l.id, l.name, l.creation_date, l.account_id, t.id AS task_id, t.name AS task_name, t.description, t.creation_date AS task_creation_date FROM list l LEFT JOIN task t ON l.id = t.list_id WHERE l.account_id = $1 AND l.id IN (SELECT id FROM list WHERE account_id = $1 LIMIT $2 OFFSET $3)

GET /api/stats

select id, login, count(list_id) as nb_list, round(avg(nb_tasks),2) as avg_tasks from (select account.id, account.login, list.id list_id, count(task.id) nb_tasks from account inner join list on (list.account_id=account.id) left join task on (task.list_id=list.id) group by account.id, account.login, list.id) t group by id, login

Algorithm

GET /api/stats

Please follow the following example :

for rowsList.Next() {
		var rawAccountId string
		var accountLogin sql.NullString
		var listCount int64
		var taskAvg float64
		err = rowsList.Scan(&rawAccountId, &accountLogin, &listCount, &taskAvg)
		if err != nil {
			return nil, errors.Wrap(err, "failed to scan the SQL result")
		}
		accountId, err := uuid.FromString(rawAccountId)
		if err != nil {
			return nil, errors.Wrapf(err, "the account has wrong id: %s", rawAccountId)
		}
		stat := get_stats.GetStatsByAccountsResponse{
			AccountId:    accountId,
			AccountLogin: accountLogin.String,
			ListCount:    listCount,
			TaskAvg:      taskAvg,
		}
		stats = append(stats, stat)
	}
	return stats, nil

Result analysis contribution

Target folders :

Not available yet

Runner contribution

Target folders :

Not available yet

To be Sorted

Workflow

The complete workflow is based on docker images. Every image should be named as <org>/service-<service_name>:<use_case>.

Each image can be built using the following command.

# oRG=jdrouet is used by default but can be changed by exporting a different variable.
./builder/service.sh <name_of_your_service> <use_case>

Starting the database

Postgres

to run the migrations when starting the database

--volume $(pwd)/migrations:/docker-entrypoint-initdb:ro \

today, the 30th of april 2022, this is the latest release

postgres:14.2-bullseye

docker run -d \
  --name eco-benchmark-database \
  # to run the migrations when starting the database
  --volume $(pwd)/migrations:/docker-entrypoint-initdb.d:ro \
  --port 5432:5432 \
  -e POSTGRES_PASSWORD=mysecretpassword \
  postgres:14.2-bullseye

export DATABASE_URL=postgresql://postgres:[email protected]:5432/postgres