summaryrefslogtreecommitdiff
Commit message (Collapse)AuthorAgeFilesLines
* {config,ws}.go, cca.scfg.example: Add perf.course_update_intervalRunxi Yu13 days3-6/+14
| | | | | | This causes a drastic increase in performance. References: https://todo.sr.ht/~runxiyu/cca/7
* {courses,wsm}.go: Use in-memory structure to fetch cgroup, not SQLRunxi Yu13 days2-26/+18
|
* {config,ws}.go, cca.scfg.example: Remove chanPool/SendQRunxi Yu13 days3-59/+0
|
* ws.go: &usemT{} //exhaustruct:ignoreRunxi Yu13 days1-1/+1
|
* ws.go: Check error of populateUserCourseGroupsRunxi Yu13 days1-1/+4
|
* wsm.go: Omit comparison to bool constantRunxi Yu13 days1-1/+1
|
* wsm.go: Report error when course doesn't existRunxi Yu12 days1-0/+8
| | | | | Luckily we encounter a database error before we have the chance to dereference a null pointer. But it's still good practice to check.
* {courses,sem,ws,wsm}.go: Second step towards an efficient state propagatorRunxi Yu12 days4-16/+24
| | | | References: https://todo.sr.ht/~runxiyu/cca/7
* {courses,sem,ws}.go: First step towards an efficient state propagatorRunxi Yu12 days3-6/+110
| | | | References: https://todo.sr.ht/~runxiyu/cca/7
* go.sum: go mod tidy (removing old checksums)Runxi Yu12 days1-6/+0
|
* ws.go: Index chanPool by userID, rather than session cookieRunxi Yu12 days1-5/+2
|
* {main,utils,ws}.go: Initialize cancelPool directly tooRunxi Yu12 days3-25/+1
|
* Bump dependenciesRunxi Yu12 days2-3/+9
|
* {main,ws}.go: Initialize chanPool directly instead of setupChanPool()Runxi Yu12 days2-22/+1
| | | | | | It is possible to use var chanPool = make(map[string](*chan string)) directly during declaration, even if it's a global variable. There is no need to call a function to initialize it.
* courses.go: ReformatRunxi Yu12 days1-1/+1
|
* {courses,wsm}.go: Add getCourseByIDRunxi Yu12 days2-10/+8
| | | | This also deduplicates some code.
* {courses,wsm}.go: Add (*courseT).decrementSelectedAndPropagateRunxi Yu12 days2-24/+15
| | | | This is being done quite a few times, so let's make it a function.
* {courses,ws,wsm}.go: Update userCourseGroups during choose/unchooseRunxi Yu12 days3-12/+51
|
* config.go: Emit warning when fake auth is enabledRunxi Yu12 days1-0/+2
|
* bench.go: Don't close request bodyRunxi Yu12 days1-6/+0
| | | | | | The WebSocket library closes it for us (which is not behavior that I like, but fine). Closing it again causes segmentation faults as Body becomes a null pointer or something like that.
* {courses,ws}.go: Populate userCourseGroups in a separate functionRunxi Yu12 days2-32/+35
|
* {courses,ws}.go: Populate userCourseGroups for each connectionRunxi Yu13 days2-5/+63
| | | | | | | | | | | | | | | | | | It is way too expensive to query the database every time we need to check whether a user has chosen a course in a group. Since we can (hopefully) guarantee that there is only one usable connection for any given moment and user, we could store this data along with the connection as a local variable in handleConn, which would be eligible for garbage collection when handleConn exits. Here we create the data structures that globally represent courseTypes and courseGroups, and during the initial stages of handleConn, perform database queries to populate userCourseGroups with the groups that the user has already chosen. Note that the HELLO command handler does similar database queries, and as per the TODO listed in the comments, should be moved up here for efficiency. (HELLO also serves as some sort of an initial connection check; this should probably be replaced with WebSocket's native pings.)
* courses.go, schema.sql: Validate course{Type,Group} in server, not SQLRunxi Yu13 days4-30/+45
|
* *.sql: New schema with ctypes and cgroupsRunxi Yu13 days3-18/+39
|
* drop.sql: New SQL script to drop all tablesRunxi Yu13 days1-0/+3
|
* auth.go: Improve display of OAuth 2.0 errorsRunxi Yu13 days1-4/+17
| | | | Implements: https://todo.sr.ht/~runxiyu/cca/9
* config.go: Return errors instead of panicing on auth.fake issuesRunxi Yu13 days1-3/+11
|
* {config,main}.go, cca.scfg.example: Settable static pathRunxi Yu13 days3-13/+8
| | | | | | | | | Because of the poor performance of using NGINX as a reverse proxy, I've added native TLS in commit 4a1a7af76408e956ebc343bf28960fdd00c00c58. Serving static files was already supported, but it was expected that people use a static web server to do so, so we didn't support a configurable static path. Now since reverse proxy setups are discouraged, it makes more sense to be better at serving static files.
* staff.html: Initial staff pageRunxi Yu13 days1-0/+149
| | | | | It's currently a copy of the student page with a few words changed and no checkboxes
* student.html, *.js: {main->student}.jsRunxi Yu13 days2-1/+1
|
* student.html: {{ .user.Name }} instead of Home in titleRunxi Yu13 days1-1/+1
|
* bench.go, main.js: Use an HTTPS URLRunxi Yu13 days2-2/+2
| | | | | This URL should be configurable in the JS at least, but I'm not sure how I should be filling out JS templates. I'll leave it hardcoded for now.
* {config,main}.go, cca.scfg.example: Support TLSRunxi Yu13 days3-8/+65
|
* main.go, cca.scfg.example: Remove FastCGI supportRunxi Yu13 days2-9/+5
| | | | | | I would love to serve FastCGI but it is a huge pain to get WebSocket working, at least with NGINX. I don't think OpenBSD httpd would be better at this either.
* bench.go: Use more realistic connection numbers for nowRunxi Yu13 days1-4/+4
|
* postgres_shell.sh: Delete as unnecessaryRunxi Yu14 days1-3/+0
| | | | Just use "psql cca"
* bench: Add a bit more stress (30000 connections, 30s wait)v0.1.2Runxi Yu2024-10-031-2/+2
|
* README.md, iadocs/{cover*, crita*}: Update documentationRunxi Yu2024-10-033-39/+67
|
* cca.scfg.example: Listen on 127.0.0.1:5555 only by defaultRunxi Yu2024-10-031-3/+3
| | | | | | I would have used IPv6, i.e. [::1]:5555, but our school network only has IPv4 and it'd be easier to keep everything on the same protocol, though this probably wouldn't matter for standard reverse proxy setups.
* style.css: Update color schemeRunxi Yu2024-10-031-22/+20
|
* {config,ws}.go, cca.scfg.example: Allow same-user fake authRunxi Yu2024-10-033-15/+30
| | | | This is useful for testing whether connection collisions work well.
* ws.go: Don't log chanPool changesRunxi Yu2024-10-031-2/+0
|
* schema.sql: users.expr should be BIGINTRunxi Yu2024-10-031-1/+1
|
* {ws,wsm}.go: Handle context cancellationsRunxi Yu2024-10-032-5/+94
|
* student.html: Connection closed could be cause by a login elsewhereRunxi Yu2024-10-031-0/+3
|
* lint.sh: Disable nonamedreturnsRunxi Yu2024-10-031-1/+1
| | | | I used named returns to inspect return values (especially error values)
* ws.go: Fix memory leak introduced in last commitRunxi Yu2024-10-031-0/+7
| | | | | | The entry is deleted from cancelPool if and only if cancelPool's cancel function for the user is equal to &newCancel. This compare-and-delete works because of locking.
* ws.go: Fix first race condition in cancelPool managementRunxi Yu2024-10-031-13/+2
| | | | | | | | | | | | | | | Cancel occurs in async. When the cancelled function exits, it deletes the entry in cancelPool, and could replace the new routine's cancel function, which is of course undesirable. Therefore this commit causes handleConn to stop deleting from cancelPool entirely. Note that this introduces a memory leak at the size of context.CancelFunc per user, because we are never deleting from cancelPool. This does not actually solve the race condition documented in fc911928 where two new connections start sufficiently close to each other.
* {main,ws,wsm}.go: Attempt to cancel old sessionsRunxi Yu2024-10-033-23/+87
| | | | | | | | | | | | | | | | | | | When beginning to handle a WebSocket connection, we shall create a new context, with the request context as its parent. We use the new context for everything from now on, except for reporting error messages, which is handled by creating a reportError function in a closure in makeReportError and passing it along to command-handling functions. Note that if one user attempts to rapidly launch WebSocket connections, there might still be a race condition where the old connection hasn't been completely established yet (i.e. an entry hasn't been added to cancelPool) and the new connection isn't able to cancel the old connection. I'm a bit tired to think of a solution now but it could probably be solved by moving the cancellation registration and cancelling sooner during the initial handshake. Note that more parts of the event loop needs to select from ctx.Done (from newCtx) for this to work reliably.
* README.md, student.html: Correct spellingRunxi Yu2024-10-032-2/+2
|