fix(coderd): workspaceapps: update last_used_at when workspace app reports stats - #11603
Conversation
2d44bf4 to
5b799e8
Compare
There was a problem hiding this comment.
review: leaving this here to address in a follow-up. As this is now tied to stats collection, we bump whenever there are app usage stats for a workspace.
There was a problem hiding this comment.
review: I'm counting this as a successful and valid attempt to access a workspace.
There was a problem hiding this comment.
review: this is where all the race gremlins live:
- Bicopy does not appear to exit immediately so if we flush stats immediately we may not get a finished session.
- Even though a completed flush should mean that LastUsedAt has been bumped, I've observed some wiggle room (especially when wsproxy is involved).
There was a problem hiding this comment.
Why don't we try looping the flush until we either time out or have the stats we're looking for? Might make sense to have FlushStats take a context too, just to be sure.
There was a problem hiding this comment.
review: there should be no need to flush the stats on the primary here, as the proxy sends its stats directly to the primary endpoint which is wired up directly to the Reporter, which just inserts immediately.
There was a problem hiding this comment.
Correct me if I'm wrong, but without a flush, we can't ensure that Report() is being called (i.e. flushing the in-memory stats to coderd via post), right? So I think it may be needed here too, depending on what we're looking to achieve.
There was a problem hiding this comment.
From my reading, any POSTS to /app-stats go straight to api.WorkspaceAppsStatsCollectorOptions.Reporter, and the wsproxy app stats reporter just hits that endpoint on flush. The stats reporter for the primary goes straight to the DB as well as far as I can tell.
mtojek
left a comment
There was a problem hiding this comment.
I left few nit-picks, and I'm looking forward to follow-ups!
There was a problem hiding this comment.
nit: is it expected or is the linter impaired?
There was a problem hiding this comment.
This is fine, it's how these are usually grouped (coder/coder, cdr.dev, etc grouped together, separate from stdlib and 3rd party).
There was a problem hiding this comment.
This could be before the mutex lock, but it's such a minor perf change not sure it's worth changing.
There was a problem hiding this comment.
No need for err no rows here, an update never returns this unless RETURNING * is used.
There was a problem hiding this comment.
This is fine, it's how these are usually grouped (coder/coder, cdr.dev, etc grouped together, separate from stdlib and 3rd party).
There was a problem hiding this comment.
One could make a case for us trying to do the last used update even if this fails, wdyt?
There was a problem hiding this comment.
Inserting app stats is just doing a big insert into a single table (which IIRC is unlogged), so if we run into issues doing that my gut tells me that any further database queries might not be successful. Might not hurt to try, but I'm not sure how much the extra complexity would be worth it. Bear in mind that we will end up just trying to do this again in another 30 seconds!
There was a problem hiding this comment.
IMO, it's close enough. We could ensure we use max time from the stats if we want slightly more accuracy (still off for some workspaces, though).
There was a problem hiding this comment.
Correct me if I'm wrong, but without a flush, we can't ensure that Report() is being called (i.e. flushing the in-memory stats to coderd via post), right? So I think it may be needed here too, depending on what we're looking to achieve.
There was a problem hiding this comment.
Naming these stats specific might keep things more clear.
There was a problem hiding this comment.
Why don't we try looping the flush until we either time out or have the stats we're looking for? Might make sense to have FlushStats take a context too, just to be sure.
There was a problem hiding this comment.
Same here, looping flush seems better than waiting an arbitrary time?
There was a problem hiding this comment.
A loop-flush here would probably just execute after the first iteration.
bad5194 to
8573ba7
Compare
|
Filed #11643 for following up on unexpected stats inserts. |
Fixes #11509
BatchUpdateLastUsedAtBatchUpdateLastUsedAtin app stats handler upon flushThis is not the 'correct' solution, but it puts a decent enough bandage on the problem until we figure out a more unified solution to this issue of updating the "Last Used At" field of workspaces based on certain events. I'll be opening a follow-up PR for this.
Now when the workspace apps stats collector flushes a batch of stats, we bump
LastUsedAtfor all affected workspaces.Note: I'm just updating
LastUsedAtto the same value for all workspaces. I don't know if there's a good way to insert a whole bunch of distinct values for a number of rows in a single transaction, and I want to keep this to a single query if possible.I've verified that this works experimentally but this is the sort of thing that should be ossified in tests. I'm currently putting this into
TestWorkspaceAppsas it seems to be the place where all the testing of proxying flows happens.Also note: the tests are sadly a bit racy; I've done what I can for the moment but I may need to spend some follow-up time refactoring.