Skip to content

Commit 3a7e4d3

Browse files
committed
fix api call to use usersDB
1 parent 1afc6b6 commit 3a7e4d3

File tree

5 files changed

+95
-37
lines changed

5 files changed

+95
-37
lines changed

UserDb.js

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,19 @@ class UserDb extends Map {
3333
)
3434
})
3535
}
36+
find(userId) {
37+
return Array.from(this.values()).filter((u) => {
38+
return u.userId == userId
39+
})
40+
}
41+
dump() {
42+
const data = []
43+
this.forEach((v, k) => {
44+
data.push(v.serialize())
45+
})
46+
47+
return JSON.stringify(data)
48+
}
3649
save() {
3750
const data = []
3851
this.forEach((v, k) => {

agreement.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,13 @@
11
class Agreement {
2-
constructor(agreementId, experimentId, users, urls, server) {
2+
constructor(agreementId, experimentId, users, urls, server, timeout) {
33
this.agreementId = agreementId
44
this.experimentId = experimentId
55
this.users = users
66
this.agreedUsers = []
77
this.urls = urls
88
this.server = server
99
this.state = "new"
10-
this.timeout = 30
10+
this.timeout = timeout || 30
1111
}
1212

1313
startTimeout(fn) {

package-lock.json

Lines changed: 9 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,13 +5,15 @@
55
"main": "server.js",
66
"scripts": {
77
"test": "node --test",
8-
"dev": "node encode-url.js && node server.js 8060",
8+
"dev": "node set_env.js > .env && node server.js -p 8060",
9+
"dev-newDb": "node server.js -p 8060 --reset-db",
910
"start": "node server.js 80"
1011
},
1112
"author": "",
1213
"license": "ISC",
1314
"dependencies": {
1415
"axios": "^1.5.0",
16+
"commander": "^12.0.0",
1517
"crypto-js": "^4.2.0",
1618
"dotenv": "^16.3.1",
1719
"ejs": "^3.1.9",

server.js

Lines changed: 68 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
const { program } = require("commander")
12
const express = require("express")
23
const http = require("http")
34
const axios = require("axios")
@@ -27,8 +28,20 @@ const otreeRestKey = process.env.OTREE_REST_KEY
2728
const apiKey = process.env.API_KEY
2829
const secretKey = process.env.SECRET_KEY
2930
const keyWordArray = CryptoJS.enc.Base64.parse(apiKey)
30-
const port = process.argv[2] || "8060"
31-
const userDbFile = "./data/userdb.json"
31+
32+
program
33+
.option("-p, --port <int>", "server listen port")
34+
.option("--reset-db", "reset users database")
35+
.option("--db-file <type>", "user database file to use")
36+
37+
program.parse(process.argv)
38+
const options = program.opts()
39+
console.log(options.port)
40+
console.log(options.resetDb)
41+
console.log(options)
42+
43+
const port = options.port || "8060"
44+
const userDbFile = options.dbFile || "./data/userdb.json"
3245
//const publicKey = fs.readFileSync("./public-key.pem", "utf8")
3346
//
3447
process.on("SIGINT", function () {
@@ -280,13 +293,22 @@ function startReadyGames(experiments, agreementIds, usersDb) {
280293
agreement.urls,
281294
agreement.server,
282295
)
283-
agreedUsersIds.forEach((userId) => {
284-
const compoundKey = `${userId}:${agreement.experimentId}`
296+
297+
console.log(agreedUsersIds)
298+
console.log(nonAgreedUsersIds)
299+
300+
//agreedUsersIds.forEach((userId) => {
301+
agreedUsersIds.forEach((compoundKey) => {
302+
// const compoundKey = `${userId}:${agreement.experimentId}`
303+
console.log(`agree: ${compoundKey}`)
285304
const user = usersDb.get(compoundKey)
286305
user.changeState("queued")
287306
})
288-
nonAgreedUsersIds.forEach((userId) => {
289-
const compoundKey = `${userId}:${agreement.experimentId}`
307+
//nonAgreedUsersIds.forEach((userId) => {
308+
nonAgreedUsersIds.forEach((compoundKey) => {
309+
// usersDb.dump()
310+
// const compoundKey = `${userId}:${agreement.experimentId}`
311+
console.log(`Non agree: ${compoundKey}`)
290312
const user = usersDb.get(compoundKey)
291313
user.reset()
292314
})
@@ -301,7 +323,7 @@ function startReadyGames(experiments, agreementIds, usersDb) {
301323
conditionObject.waitForCount === 0 &&
302324
conditionObject.server === null
303325
) {
304-
console.warn(`[WARNING] experiment ${experimentId} ran out of slots!`)
326+
console.warn(`[WARNING] Experiment ${experimentId} ran out of slots!`)
305327
scheduler.resetQueue()
306328
conditionObject.users.forEach((user) => {
307329
user.reset()
@@ -314,14 +336,16 @@ function startReadyGames(experiments, agreementIds, usersDb) {
314336

315337
async function main() {
316338
const experiments = {}
339+
if (options.resetDb && fs.existsSync(userDbFile)) {
340+
console.log(`Deleting ${userDbFile} file!`)
341+
fs.unlinkSync(userDbFile)
342+
}
317343
/**
318344
*
319-
* @type {Map<string, User>}
345+
* @type {Map<`${userId}:${experimentId}`, User>}
320346
*/
321-
//const usersDb = new Map()
322347
const usersDb = new UserDb(userDbFile)
323348
await usersDb.load()
324-
const userMapping = {}
325349
const agreementIds = {}
326350
const expToEnable = config.experiments.map((e) => e.name)
327351
// Load schedulers from directory
@@ -406,21 +430,31 @@ async function main() {
406430
"/api/lissparticipants/:userId",
407431
validateSignature,
408432
async (req, res) => {
409-
const participantUrl = userMapping[req.params.userId]
410-
if (!participantUrl) {
411-
res.status(404).json({ message: `${req.params.userId} not found.` })
412-
return
433+
function flatten(arr) {
434+
return arr.reduce(function (flat, toFlatten) {
435+
return flat.concat(
436+
Array.isArray(toFlatten) ? flatten(toFlatten) : toFlatten,
437+
)
438+
}, [])
413439
}
414-
const parseUrl = url.parse(participantUrl)
415-
//const hostname = parseUrl.hostname
416-
const participantCode = lastElement(parseUrl.pathname.split("/"))
417-
const results = await db.parQuery(`SELECT *
418-
FROM otree_participant
419-
WHERE code = '${participantCode}'`)
420-
const result = results.filter((r) => {
421-
return r.length !== 0
422-
})
423-
res.status(201).json(result)
440+
const results = usersDb
441+
.find(req.params.userId)
442+
.map((u) => u.serialize())
443+
.filter((u) => u.redirectedUrl)
444+
.map(async (u) => {
445+
const participantUrl = u.redirectedUrl
446+
const parseUrl = url.parse(participantUrl)
447+
const participantCode = lastElement(parseUrl.pathname.split("/"))
448+
const sqlResults = await db.parQuery(`SELECT *
449+
FROM otree_participant
450+
WHERE code = '${participantCode}'`)
451+
const nonEmpty = sqlResults.filter((r) => {
452+
return r.length !== 0
453+
})
454+
return nonEmpty
455+
})
456+
const vals = await Promise.all(results)
457+
res.status(201).json(flatten(vals))
424458
},
425459
)
426460

@@ -616,7 +650,7 @@ async function main() {
616650
}
617651
usersDb.get(compoundKey).changeState("agreed")
618652
// If everyone agrees, start game
619-
if (agreement.agree(userId)) {
653+
if (agreement.agree(compoundKey)) {
620654
console.log("Start Game!")
621655
startGame(agreement.agreedUsers, agreement.urls, agreement.experimentId)
622656
}
@@ -638,23 +672,23 @@ async function main() {
638672
console.log(`Starting game with users: ${users} and urls ${urls}.`)
639673
for (let i = 0; i < users.length; i++) {
640674
const userId = users[i]
641-
const compoundKey = `${userId}:${experimentId}`
675+
// const compoundKey = `${userId}:${experimentId}`
676+
const compoundKey = userId
642677
const user = usersDb.get(compoundKey)
643678
user.changeState("redirected")
644679
const expUrl = new URL(urls[i])
645-
userMapping[userId] = expUrl
646680
// Set user variables on oTree server
647681
// Vars in oTree experiment template are accessed using
648682
// the syntax {{ player.participant.vars.age }} where age is a var
649-
const oTreeVars = user.tokenParams?.oTreeVars || {}
683+
// const oTreeVars = user.tokenParams?.oTreeVars || {}
650684
// First update user variables on oTree server
651685
// then redirect
652-
const config = {
653-
headers: {
654-
"otree-rest-key": otreeRestKey,
655-
},
656-
}
657-
const participantCode = expUrl.pathname.split("/").pop()
686+
// const config = {
687+
// headers: {
688+
// "otree-rest-key": otreeRestKey,
689+
// },
690+
// }
691+
//const participantCode = expUrl.pathname.split("/").pop()
658692
const sock = user.webSocket
659693
// Emit a custom event with the game room URL
660694
user.redirectedUrl = `${expUrl}?participant_label=${user.userId}`

0 commit comments

Comments
 (0)