Skip to content

Commit

Permalink
Merge pull request #59 from obeliss-nlesc/56-persist-data-between-res…
Browse files Browse the repository at this point in the history
…tarts

merge main
  • Loading branch information
recap authored Apr 9, 2024
2 parents a233904 + 0f94127 commit 715c883
Show file tree
Hide file tree
Showing 9 changed files with 554 additions and 131 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
.env
*.pem
api.key
*.key

# Data folder
data/*
Expand Down
15 changes: 12 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -54,18 +54,27 @@ API_KEY="some other secret in quotes"
To start server on a default port 8060 localhost

```shell
npm run dev
node server.js --port 8080
```

Three test user URLs are printed on the command line that can be used to test the server.
A database is created by default in ./data/userdb.json which will save previous redirected urls. To reset the database
start the server with --reset-db flag.

## Generate test URLs

USe the encode-url.js helper script to generate test urls.

```shell
node encode-url.js -n 5 -h localhost:8080
```

## Starting the server using PM2

To manage the server with pm2, first install pm2

```shell
npm install pm2 -g
pm2 start server.js -- 8080
pm2 start server.js -- --port 8080
pm2 list
```

Expand Down
70 changes: 70 additions & 0 deletions UserDb.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
// Persisting the User Map to disk

const murmurhash = require("murmurhash")
const fs = require("fs").promises
const User = require("./user.js")

class UserDb extends Map {
constructor(file) {
super()
this.seed = 42
this.file = file
this.lastHash = 0
}
load() {
let data = []
return fs
.readFile(this.file)
.then((d) => {
data = JSON.parse(d)
data.forEach((u) => {
const user = new User(u.userId, u.experimentId)
user.redirectedUrl = u.redirectedUrl
user.oTreeId = u.oTreeId
user.tokenParams = u.tokenParams
user.state = u.redirectedUrl ? u.state : user.state
const compoundKey = `${user.userId}:${user.experimentId}`
this.set(compoundKey, user)
})
})
.catch((err) => {
console.error(
`[WARNING] UserDb file ${this.file} file not found will be recreated!`,
)
})
}
find(userId) {
return Array.from(this.values()).filter((u) => {
return u.userId == userId
})
}
dump() {
const data = []
this.forEach((v, k) => {
data.push(v.serialize())
})

return JSON.stringify(data)
}
save() {
const data = []
this.forEach((v, k) => {
data.push(v.serialize())
})

const dump = JSON.stringify(data)
const h = murmurhash(dump, this.seed)
console.log(`${h}:${this.lastHash}:${dump}`)
if (this.lastHash !== h) {
fs.writeFile(this.file, dump)
.then(() => {
this.lastHash = h
})
.catch((err) => {
console.error("[ERROR] Writing UserDb to file.")
})
}
}
}

module.exports = UserDb
4 changes: 2 additions & 2 deletions agreement.js
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
class Agreement {
constructor(agreementId, experimentId, users, urls, server) {
constructor(agreementId, experimentId, users, urls, server, timeout) {
this.agreementId = agreementId
this.experimentId = experimentId
this.users = users
this.agreedUsers = []
this.urls = urls
this.server = server
this.state = "new"
this.timeout = 30
this.timeout = timeout || 30
}

startTimeout(fn) {
Expand Down
23 changes: 20 additions & 3 deletions encode-url.js
Original file line number Diff line number Diff line change
@@ -1,9 +1,26 @@
const { program } = require("commander")
const CryptoJS = require("crypto-js")
require("dotenv").config()
const secretKey = process.env.SECRET_KEY
const experimentIds = ["public_goods_game", "DropOutTest"]
const users = [212035, 212036, 212037, 212038, 212039, 212040]
const hosts = ["lobby.lisspanel.nl", "localhost:8060"]
const config = require("./config.json")
program
.option("-n, --num-users <int>", "number of users")
.option("-h, --host <type>", "host to point to")

program.parse(process.argv)
const options = program.opts()
const experimentIds = config.experiments.map((e) => e.name)
const numUsers = options.numUsers || 3
let users = [212035, 212036, 212037]
if (options.numUsers) {
users = []
for (let i = 0; i < numUsers; i++) {
const id = Math.floor(Math.random() * 90000) + 10000
users.push(id)
}
}
const hosts = options.host ? [options.host] : ["localhost:8060"]

if (!secretKey) {
console.log("[ERROR] no secret key")
return
Expand Down
Loading

0 comments on commit 715c883

Please sign in to comment.