Skip to content
/ wust2 Public

Graph-Based Realtime Collaboration System. Woost yourself.

License

Notifications You must be signed in to change notification settings

woost/wust2

Folders and files

NameName
Last commit message
Last commit date

Latest commit

80c20c5 · Aug 8, 2021
Oct 15, 2019
Dec 4, 2019
Jun 14, 2019
Aug 11, 2019
Dec 9, 2019
Aug 12, 2020
Jan 6, 2020
Aug 12, 2020
Dec 4, 2019
Dec 4, 2019
Jun 24, 2018
Jul 4, 2019
Jul 9, 2018
Jun 23, 2019
Jun 23, 2019
Aug 12, 2020
Aug 12, 2020
Jul 31, 2021
Aug 12, 2020
Jul 29, 2019
Aug 12, 2020
Jun 23, 2019
Aug 12, 2020
Jul 31, 2021
Jul 31, 2021
Mar 7, 2020
Nov 13, 2019
Aug 1, 2019
Jul 2, 2018
Aug 1, 2019
Jul 28, 2020
Aug 8, 2021
Mar 29, 2019
Jul 31, 2021
Aug 1, 2019
May 22, 2019
Jul 31, 2021
Aug 1, 2019
Jul 5, 2019
Oct 14, 2019
Jun 19, 2018
Sep 7, 2018
Aug 8, 2021
Feb 7, 2020
Mar 30, 2019

Repository files navigation

Woost

Build Status Join the chat at https://gitter.im/wust2/Lobby

A collaboration system with todo-list, kanban-board, chat and folders. Everything can be nested. For example a card in a kanban-board can contain a kanban-board itself.

Kanban Board

Rough Architecture

A directed graph stored in postgres accessed via rpc-calls over websockets and binary serialization, visualized using reactive programming and a force-directed graph layout.

Building blocks

  • scala/scala-js (scala for backend, scala-js is scala compiled to javascript for the webApp. Allows to share code between both.)
  • postgres (relational database with views and stored procedures for graph traversal)
  • flyway (database migrations)
  • quill (compile-time language integrated database queries for Scala)
  • akka (message passing in backend, websocket server)
  • sloth (type safe rpc calls for implementing webApp-to-backend api)
  • mycelium (request, response and events over websockets)
  • boopickle (fast and boilerplate-free binary serialization, similar to protobuf. Used for webApp/backend communication)
  • outwatch (UI-library for reactive programming bindings to DOM-Nodes)
  • d3 (visualization library, used for graph visualization and drag&drop)

Development

Requirements:

  • sbt
  • docker, docker-compose
  • node, yarn
  • phantomjs
  • gcc and make

Note: gcc/make is not a direct requierement of this project, but some npm packages requiere a C compiler. You will most probably notice that if you get a runtime exception from npm.

Starting all needed services in docker (e.g. postgres with initialization) and run sbt with corresponding environment variables:

$ ./start sbt

In the sbt prompt, you can then start watching sources and recompile while developing:

> dev

If you are only developing the webApp, you can also skip recompilation of the backend:

> devf

Access wust via http://localhost:12345

The start script is the central script for developers. From here, you can also run db migrations, access psql, run tests or start a production stack with test settings:

start < sbt [app], migrate [app], psql <options>, pgcli [app], pgdump, pgrestore <file>, pgclean, prod, prod.http, prod.slack, test, test.postgres, test.integration >

Developing database migrations

Test migration in transaction, then rollback.

begin;

alter table ...;
drop table ...;

\d+ yourtable;
\dt public.*;

rollback;

Run sql from vim:

:w !docker exec -i devcore_postgres_1 psql -h localhost -U wust -p 5432

Developing database tests

find dbMigration/core/{sql,tests} | entr -ncs 'sbt dbMigration/docker && ./start test.postgres'

Watching and running particular tests

~[project]/testOnly *[Suite or Pattern]* -- -z [name]

e.g.

~graphJVM/testOnly *GraphSpec* -- -z "topological before"

Database performance measurement

For more accurate measurements, set cpu to fixed frequency:

sudo cpupower frequency-set -g performance
sudo cpupower frequency-set -u 3GHz

and disable multithreading in postgres:

SET max_parallel_workers_per_gather = 0;

function stats (only activated in dev, requires track_functions=all)

select funcname, calls, total_time, total_time/calls as total_avg, self_time, self_time/calls as self_avg from pg_stat_user_functions order by self_time DESC;

to clean the stats:

select pg_stat_reset();

function explanation via auto explainer:

LOAD 'auto_explain';
SET auto_explain.log_min_duration = 0; -- if too many small queries are explained, raise this value
SET auto_explain.log_nested_statements = ON;
-- helpful for the visualizer
set auto_explain.log_format = json;
set auto_explain.log_verbose = true;
set auto_explain.log_buffers = true;

The explanations will appear in the log.

Explanation visualizer: https://dalibo.github.io/pev2

watching database content

watch 'echo "SELECT * from node; select * from edge;" | docker exec -i devcore_postgres_1 psql -h localhost -U wust -p 5432'

git bisect

docker-compose -p devcore -f core/docker-compose.yml -f core/docker-compose.dev.yml up -d db-migration; ./start pgclean; ./start migrate; SOURCEMAPS=true EXTRASBTARGS="webApp/clean dev" ./start nsbt

Fully automated bisect if the error can be reproduced by a command with an exit code:

git bisect start [bad-commit] [good-commit]
git bisect run [command]

Docker images

Build all docker images in project:

$ sbt docker

Access/debug devserver from android

build.sbt:

webpackDevServerExtraArgs := Seq("--public")

and open firewall port in configuration.nix:

networking.firewall.allowedTCPPorts = [ 12345 ];

Deployment

Requirements:

  • docker
  • docker-compose

All used docker services can be configured with the following environment variables:

  • POSTGRES_PASSWORD: a password for the postgres application user 'wust'
  • WUST_AUTH_SECRET: a secret for signing JWT tokens
  • WUST_EMAIL_ADDRESS: from address for sent email (optional)
  • WUST_SMTP_ENDPOINT: smtp endpoint (optional)
  • WUST_SMTP_USER: smtp username (optional)
  • WUST_SMTP_PASS: smtp password (optional)
  • WUST_WEB_PUSH_SUBJECT: subject (email) for sending push notifications to push service (optional)
  • WUST_WEB_PUSH_PUBLIC_KEY: vapid public key (optional)
  • WUST_WEB_PUSH_PRIVATE_KEY: vapid private key (optional)

The compose stack core/docker/docker-compose.yml is an example how to run wust in docker. Start the whole stack with docker-compose:

$ docker-compose --file core/docker/docker-compose.yml up

App and Favicons

Example Usage of json Api

login

$ curl localhost:8901/api/Auth/loginReturnToken -d '{"email":"a@a", "password": "hans"}'
"eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpc3MiOiJ3dXN0Iiwic3ViIjoiNVVEdVFjcERRQmk2YUVnOVFxdUxLTiIsImF1ZCI6WyJ3dXN0Il0sImV4cCI6MTU4NDU2NDU4MywibmJmIjoxNTUzMDI4NTgzLCJpYXQiOjE1NTMwMjg1ODMsInVzZXIiOnsiaWQiOiIyNDMxOTZhYS03ZDdlLTc2MDAtMmMyNi1lYzBmNjdjODQwZDUiLCJuYW1lIjoiaGFucyIsInJldmlzaW9uIjoxLCJ0eXBlIjoiUmVhbCJ9LCJ0eXBlIjoiVXNlckF1dGgifQ.M8I7LsfIITm-P4S3zhrdDe8qEzkKoCJzpmfhPMl9hho"
```bash

## getTasks
``` bash
$ curl -H "Authorization: eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpc3MiOiJ3dXN0Iiwic3ViIjoiNVVEdVFjcERRQmk2YUVnOVFxdUxLTiIsImF1ZCI6WyJ3dXN0Il0sImV4cCI6MTU4NDU2NDU4MywibmJmIjoxNTUzMDI4NTgzLCJpYXQiOjE1NTMwMjg1ODMsInVzZXIiOnsiaWQiOiIyNDMxOTZhYS03ZDdlLTc2MDAtMmMyNi1lYzBmNjdjODQwZDUiLCJuYW1lIjoiaGFucyIsInJldmlzaW9uIjoxLCJ0eXBlIjoiUmVhbCJ9LCJ0eXBlIjoiVXNlckF1dGgifQ.M8I7LsfIITm-P4S3zhrdDe8qEzkKoCJzpmfhPMl9hho" localhost:8901/api/Api/getTasks -d '{"parentId":"243196b9-f7dc-f101-40c6-8a827f5e7a7d"}'