Skip to content

Commit

Permalink
Initial TPC-C Demo App (#112)
Browse files Browse the repository at this point in the history
This PR creates a TPC-C demo app. It was originally written by @devhawk
for our debugger prototype.

The README shows how to run TPC-C end-to-end on a local machine.
Especially, we use
[go-tpc](https://github.com/pingcap/go-tpc/tree/master) to populate
TPC-C data.
  • Loading branch information
qianl15 authored Feb 16, 2024
1 parent 53ec536 commit 914c2c5
Show file tree
Hide file tree
Showing 20 changed files with 8,588 additions and 5 deletions.
1 change: 0 additions & 1 deletion .github/workflows/hello-prisma.yml
Original file line number Diff line number Diff line change
Expand Up @@ -63,4 +63,3 @@ jobs:
npm run test
env:
PGPASSWORD: dbos
NPM_AUTH_TOKEN: ${{secrets.GITHUB_TOKEN}}
1 change: 0 additions & 1 deletion .github/workflows/hello-typeorm.yml
Original file line number Diff line number Diff line change
Expand Up @@ -62,4 +62,3 @@ jobs:
npm run test
env:
PGPASSWORD: dbos
NPM_AUTH_TOKEN: ${{secrets.GITHUB_TOKEN}}
1 change: 0 additions & 1 deletion .github/workflows/hello-world.yml
Original file line number Diff line number Diff line change
Expand Up @@ -63,4 +63,3 @@ jobs:
npm run test
env:
PGPASSWORD: dbos
NPM_AUTH_TOKEN: ${{secrets.GITHUB_TOKEN}}
70 changes: 70 additions & 0 deletions .github/workflows/tpcc.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
name: CI for TPC-C

on:
push:
branches: [ "main" ]
paths:
- 'tpcc/**'
- '.github/workflows/tpcc.yml'
pull_request:
types:
- ready_for_review
- opened
- reopened
- synchronize
paths:
- 'tpcc/**'
- '.github/workflows/tpcc.yml'
workflow_dispatch:

jobs:
build:
runs-on: ubuntu-latest

# Service container for Postgres
services:
# Label used to access the service container.
postgres:
image: postgres:16
env:
# Specify the password for Postgres superuser.
POSTGRES_PASSWORD: dbos
# Set health checks to wait until postgres has started
options: >-
--name postgres
--health-cmd pg_isready
--health-interval 10s
--health-timeout 5s
--health-retries 5
ports:
# Maps tcp port 5432 on service container to the host
- 5432:5432

steps:
- name: Setup Postgres
run: docker exec postgres psql -U postgres -c "CREATE DATABASE tpcc;"
env:
PGPASSWORD: dbos
- name: Install go-tpc
run: curl --proto '=https' --tlsv1.2 -sSf https://raw.githubusercontent.com/pingcap/go-tpc/master/install.sh | sh
- name: Load TPC-C Data
run: $HOME/.go-tpc/bin/go-tpc tpcc prepare --no-check -d postgres -U postgres -p ${PGPASSWORD} -D tpcc -P 5432 --conn-params sslmode=disable --warehouses 1
env:
PGPASSWORD: dbos
- name: Checkout demo app
uses: actions/checkout@v3
with:
path: dbos-demo-apps
- name: Use Node.js 20
uses: actions/setup-node@v3
with:
node-version: 20
- name: Compile and Test TPC-C
working-directory: dbos-demo-apps/tpcc
run: |
npm install
npm run build
npm run lint
npm run test
env:
PGPASSWORD: dbos
4 changes: 2 additions & 2 deletions .github/workflows/yky-social.yml
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
name: CI for YKY-Social

on:
push:
branches: [ "main" ]
Expand Down Expand Up @@ -48,8 +50,6 @@ jobs:
run: |
cd ./dbos-demo-apps/yky-social
npm ci --no-audit
env:
NPM_AUTH_TOKEN: ${{secrets.GITHUB_TOKEN}}
- name: Create new PG DB and User
run: |
cd ./dbos-demo-apps/yky-social
Expand Down
5 changes: 5 additions & 0 deletions tpcc/.eslintignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
dist
*.test.ts
jest.config.js
migrations
knexfile.js
19 changes: 19 additions & 0 deletions tpcc/.eslintrc
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
{
"root": true,
"extends": [
"plugin:@dbos-inc/dbosRecommendedConfig"
],
"plugins": [
"@dbos-inc"
],
"env": {
"node": true,
"es6": true
},
"rules": {
},
"parser": "@typescript-eslint/parser",
"parserOptions": {
"project": "./tsconfig.json"
}
}
66 changes: 66 additions & 0 deletions tpcc/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
# TPC-C Benchmark Using DBOS SDK

This is a TPC-C TypeScript + Knex.js implementation written with [DBOS SDK](https://docs.dbos.dev/).

## Running Locally

First, start the database.
DBOS workflow works with any Postgres database, but to make things easier, we've provided a nifty script that starts Postgres locally in a Docker container and creates a database:

```bash
export PGPASSWORD=dbos
./start_postgres_docker.sh
```

Then, create some database tables.
In this quickstart, we use [knex.js](https://knexjs.org/) to manage database migrations.
Run our provided migration to create a database table:

```bash
npx knex migrate:latest
```

To load TPC-C data, we use [go-tpc](https://github.com/pingcap/go-tpc/tree/master).
You can install it using the following script:
```bash
./install_go_tpc.sh
```

After installation, the script would prompt the installation path and instruction to run it. For example, you may need to open a new terminal, or source your shell profile to use it.
An example output from the script:
```
Detected shell: bash
Shell profile: /home/ubuntu/.bashrc
/home/ubuntu/.bashrc has been modified to to add go-tpc to PATH
open a new terminal or source /home/ubuntu/.bashrc to use it
Installed path: /home/ubuntu/.go-tpc/bin/go-tpc
```

Then load the TPC-C data:
```bash
npm run load
```
We load a single warehouse of data, but you can modify the `load` script in `package.json` for larger-scale data.

Next, build and run the app:

```bash
npm run build
npx dbos-sdk start
```

Finally, curl the server to see that it's working! You can modify the last parameter (we use `1` here for one warehouse) to the number of warehouses you loaded:

```bash
# Trigger the Payment transaction
curl http://localhost:3000/payment/1

# Trigger the NewOrder transaction
curl http://localhost:3000/neworder/1
```

> [!NOTE]
> We deliberately make 1% of the NewOrder transaction fails, so it's normal to see `Error new order: I_ID=-12345 not found!` occasionally.
## Deploying to DBOS Cloud
Coming soon...
15 changes: 15 additions & 0 deletions tpcc/dbos-config.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
# To enable auto-completion and validation for this file in VSCode, install the RedHat YAML extension
# https://marketplace.visualstudio.com/items?itemName=redhat.vscode-yaml

# yaml-language-server: $schema=https://raw.githubusercontent.com/dbos-inc/dbos-sdk/main/dbos-config.schema.json

database:
hostname: 'localhost'
port: 5432
username: 'postgres'
password: ${PGPASSWORD}
user_database: 'tpcc'
connectionTimeoutMillis: 3000
user_dbclient: 'knex'
migrate: ['migrate:latest']
rollback: ['migrate:rollback']
73 changes: 73 additions & 0 deletions tpcc/install_go_tpc.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
#!/bin/sh

version=1.0.9

case $(uname -s) in
Linux|linux) os=linux ;;
Darwin|darwin) os=darwin ;;
*) os= ;;
esac

if [ -z "$os" ]; then
echo "OS $(uname -s) not supported." >&2
exit 1
fi

binary_url="https://github.com/pingcap/go-tpc/releases/download/v${version}/go-tpc_${version}_${os}_amd64.tar.gz"

case $(uname -m) in
amd64|x86_64) arch=amd64 ;;
arm64|aarch64) arch=arm64 ;;
*) arch= ;;
esac

if [ -z "$GO_TPC_HOME" ]; then
GO_TPC_HOME=$HOME/.go-tpc
fi
bin_dir=$GO_TPC_HOME/bin
mkdir -p "$bin_dir"

install_binary() {
curl -L $binary_url -o "/tmp/go-tpc_${version}_${os}_amd64.tar.gz" || return 1
tar -zxf "/tmp/go-tpc_${version}_${os}_amd64.tar.gz" -C "$bin_dir" || return 1
rm "/tmp/go-tpc_${version}_${os}_amd64.tar.gz"
return 0
}

if ! install_binary; then
echo "Failed to download and/or extract go-tpc archive."
exit 1
fi

chmod 755 "$bin_dir/go-tpc"


bold=$(tput bold 2>/dev/null)
sgr0=$(tput sgr0 2>/dev/null)

# Refrence: https://stackoverflow.com/questions/14637979/how-to-permanently-set-path-on-linux-unix
shell=$(echo $SHELL | awk 'BEGIN {FS="/";} { print $NF }')
echo "Detected shell: ${bold}$shell${sgr0}"
if [ -f "${HOME}/.${shell}_profile" ]; then
PROFILE=${HOME}/.${shell}_profile
elif [ -f "${HOME}/.${shell}_login" ]; then
PROFILE=${HOME}/.${shell}_login
elif [ -f "${HOME}/.${shell}rc" ]; then
PROFILE=${HOME}/.${shell}rc
else
PROFILE=${HOME}/.profile
fi
echo "Shell profile: ${bold}$PROFILE${sgr0}"

case :$PATH: in
*:$bin_dir:*) : "PATH already contains $bin_dir" ;;
*) printf 'export PATH=%s:$PATH\n' "$bin_dir" >> "$PROFILE"
echo "$PROFILE has been modified to to add go-tpc to PATH"
echo "open a new terminal or ${bold}source ${PROFILE}${sgr0} to use it"
;;
esac

echo "Installed path: ${bold}$bin_dir/go-tpc${sgr0}"
echo "==============================================="
echo "Have a try: ${bold}go-tpc tpcc ${sgr0}"
echo "==============================================="
8 changes: 8 additions & 0 deletions tpcc/jest.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
/** @type {import('ts-jest').JestConfigWithTsJest} */
module.exports = {
preset: 'ts-jest',
testEnvironment: 'node',
testRegex: '((\\.|/)(test|spec))\\.ts?$',
moduleFileExtensions: ['ts', 'tsx', 'js', 'jsx', 'json', 'node'],
modulePaths: ["./"],
};
20 changes: 20 additions & 0 deletions tpcc/knexfile.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
const { parseConfigFile } = require('@dbos-inc/dbos-sdk/dist/src/dbos-runtime/config');
const { DBOSConfig } = require('@dbos-inc/dbos-sdk/dist/src/dbos-executor');

const [dbosConfig, ] = parseConfigFile();

const config = {
client: 'pg',
connection: {
host: dbosConfig.poolConfig.host,
user: dbosConfig.poolConfig.user,
password: dbosConfig.poolConfig.password,
database: dbosConfig.poolConfig.database,
ssl: dbosConfig.poolConfig.ssl,
},
migrations: {
directory: './migrations'
}
};

module.exports = config;
Loading

0 comments on commit 914c2c5

Please sign in to comment.