summaryrefslogtreecommitdiff
path: root/ws.go (follow)
Commit message (Collapse)AuthorAgeFilesLines
* {ws,wsm}.go: Split message handlers into their own functionsRunxi Yu4 days1-124/+5
|
* {auth,ws}.go: Remove unnecessary TODOsRunxi Yu4 days1-14/+2
|
* ws.go: Allow deselecting coursesRunxi Yu4 days1-0/+34
|
* ws.go: Fix logic error when reaffirming a course choiceRunxi Yu4 days1-2/+2
| | | | | | | | | | | | | | When a user has already chosen a course choice but sends a message to choose it again, a database error occurs as the uniqueness constraint is violated. In this case, we "reaffirm" the user's course choice, to hopefully get their client's state back in sync. However, we previously forgot to return back to the event loop after this reaffirmation, causing the control flow to fall into the course-increment and transaction-commit stage. The error is discovered at tx.Commit, where pgx raises a ErrTxCommitRollback, because in that case we're trying to commit a transaction that has already encountered an error.
* ws.go: protocolError instead of R on unexpected database errorsRunxi Yu4 days1-23/+7
| | | | | | | When an unknown database error is encoutered, the connection should be considered broken and the error should be reported as a fatal error to the end user. Rejecting the course choice unsets the checkbox and lets the page to be continued to be used, which is not intended.
* index.go, ws.go: Fix race condition surrounding coursesRunxi Yu4 days1-1/+5
| | | | | | handleIndex and handleConn used to access the courses map without RLock'ing coursesLock, which may cause issues if courses is being written to, by a function such as setupCourses.
* ws.go: Decrement course.Selected counter on commit failuresRunxi Yu4 days1-0/+6
|
* ws.go: Reaffirm course choice when duplicate is requestedRunxi Yu4 days1-5/+13
| | | | | | | | Laggy clients, extremely fast clicks, or other conditions could cause duplicate course choices to be sent, which would violate the uniqueness constraint. In this case the fact that the user has already chosen the course should be reaffirmed, rather than making it look like their choice was rejected.
* ws.go: propagateCouldFail -> propagateIgnoreFailuresRunxi Yu4 days1-2/+2
| | | | | | I think the new name better reflects the fact that it just ignores failures when propagating to each channel. The old name sounds like "this function itself could fail".
* ws.go, schema.sql: Enforce uniqueness of course choicesRunxi Yu4 days1-42/+64
| | | | References: https://todo.sr.ht/~runxiyu/cca/1
* ws.go, *.sql: Add course choices to the databaseRunxi Yu4 days1-1/+33
| | | | | | | | | | | | | | | | | | | | Note that this naive implementation currently allows users to submit multiple requests for the same course. See the TODO comment below: /* * TODO: Ensure that the user is not already enrolled in this course * and pay attention to relevant race conditions. It might be useful * to restructure this part, to begin a transaction that adds the user * to the database (and check the (currently not existing) uniqueness) * constraint at that exact moment, and abort the transaction if the * course limit is exceeded. * Or perhaps choices should be also stored in an internal data * structure, though that requires extra attention on consistency * issues between the internal data structure and the database. * (Sometime I should really go fix the LMDB bindings...) */ References: https://todo.sr.ht/~runxiyu/cca/1
* ws.go: propagate -> propagateCouldFailRunxi Yu4 days1-3/+8
|
* ws.go: propagate course number updates in another goroutineRunxi Yu4 days1-1/+1
|
* ws.go: Separate c.Write calls into writeText()Runxi Yu5 days1-25/+17
|
* ws.go, utils.go: Document some synchronization design choicesRunxi Yu5 days1-1/+18
| | | | Also use TryLock in setupChanPool, and fail when not successful.
* *: Change license to AGPL-3.0-or-laterRunxi Yu5 days1-21/+11
|
* {auth,index,ws}.go, schema.sql: Move session cookie into the user tableRunxi Yu5 days1-8/+8
| | | | | | | One user shall only have one session at a time. This reduces the possibility of strange race conditions and simplifies the code a lot. References: https://todo.sr.ht/~runxiyu/cca/4
* index.html, main.js, ws.go: Enhance course selection rejection messageRunxi Yu6 days1-1/+1
|
* ws.go, config.go, config.scfg.example: Attempt to fix deadlockRunxi Yu6 days1-4/+7
| | | | | | | When propagate tries to propagate a message to a connection that actually called propagate, it deadlocks because the it tries to send to that connection's send channel in the same goroutine. This is an attempt at a fix.
* ws.go: Attempt to propagate messagesRunxi Yu6 days1-1/+11
|
* ws.go: Implement course choice limitsRunxi Yu6 days1-0/+31
|
* ws.go: protocolError is now its own functionRunxi Yu6 days1-28/+15
|
* .ws.go: Close websocket on protocol errorsRunxi Yu6 days1-0/+12
|
* ws.go: Stub for commands "Y" and "N", currently only counting argumentsRunxi Yu6 days1-0/+14
|
* ws.go: chanPoolLock should be locked during setupChanPoolRunxi Yu9 days1-0/+2
|
* ws.go: chanPool should be a map tooRunxi Yu9 days1-19/+8
|
* *.go, cca.scfg.example: Expose performance optionsRunxi Yu10 days1-3/+3
|
* *.go: Wrap errorsRunxi Yu10 days1-3/+4
|
* {auth,index,ws}.go: Add contexts for database callsRunxi Yu10 days1-1/+1
|
* ws.go: ReformatRunxi Yu10 days1-1/+1
|
* ws.go: Document chanPoolLock's purposeRunxi Yu11 days1-0/+9
|
* *.go: LintingRunxi Yu11 days1-14/+20
|
* {index,utils,ws}.go: Handle write errorsRunxi Yu11 days1-8/+28
|
* {utils,auth,index,ws}.go: Handle errors in random number generationRunxi Yu12 days1-1/+1
|
* ws.go: Log userid and sessionid with channel pointerRunxi Yu12 days1-3/+4
|
* ws.go: chanPoolLock should be a RWMutex rather than a pointer to oneRunxi Yu12 days1-1/+1
| | | | | | | A pointer to one could always be obtained via &chanPoolLock; but if I declare it as a pointer globally, I would need to initialize it somewhere so I don't get a null pointer dereference. It's more convenient to just declare it as the value.
* ws.go: Add missing returns after authentication failureRunxi Yu12 days1-0/+2
|
* ws.go: Initial attempt to manage chanPoolRunxi Yu13 days1-13/+22
|
* auth.go, ws.go: Update commentsRunxi Yu13 days1-5/+5
|
* ws.go, main.js, index.html: Better WS documentation and structureRunxi Yu2024-09-161-19/+55
|
* ws.go: Fix previous commit's type inconsistenciesRunxi Yu2024-09-131-4/+5
|
* ws.go: Very basic channelsRunxi Yu2024-09-131-5/+17
|
* ws.go: Clarrify handleWs's purposeRunxi Yu2024-09-121-1/+2
|
* ws.go: Move the login logic to handleWs from handleConnRunxi Yu2024-09-121-19/+38
|
* ws.go: gofmtRunxi Yu2024-09-121-3/+2
|
* ws.go: Use channels to handle incoming messagesRunxi Yu2024-09-121-11/+30
|
* ws.go: Document the message formatRunxi Yu2024-09-121-0/+25
|
* ws.go: TODO: Select c.Read and a broadcast channelRunxi Yu2024-09-111-0/+1
| | | | | | | I'm not sure whether we need to spawn an entirely different goroutine, make a shared channel, and select between the channels. It certainlly doesn't seem like there's a trivial way to block from a synchronous function and a channel, but I might be wrong, being unfamiliar with Go's concurrency.
* *.go: Shorter line lengthsRunxi Yu2024-09-091-3/+15
|
* *.go: Add commentsRunxi Yu2024-09-091-1/+44
|