New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[Assistants] trending feature #938
Conversation
b12de57
to
9ee5861
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
A few comments:
- You can use a dedicated collection for assistant analytics, with a unique key on
date
(truncated to the hour) + assistant's_id
await collections.assistantStats.updateOne({
// or `"date.at": startOfHour(new Date()) - with `date-fns`
"date.at": {$dateTrunc: {date: new Date(), unit: "hour"}},
assistantId: ...
}, {
$inc: {count: 1}
}, {upsert: true});
This will be more robust
And periodically you can run a $merge
aggregation query:
await collections.assistantStats.aggregate([..., {$merge: {into: "assistants"}})
await collections.assistants.updateMany({
"last24HoursCount.count": {$gt: 0},
"last24HoursCount.updatedAt": ...
}, {$set: {"last24HoursCount.count": 0}});
- The "cron" shouldn't be in "migrations.ts". There should maybe be an env var to enable it. And you can reuse the
collections
exported fromsrc/lib/server/database.ts
, no need to create a separate DB connection.
eg
setInterval(refreshAssistantsStats, 3600_000)
async function refreshAssistantsStats() {
if (!cantLockDb()) {
return;
}
// run DB queries
}
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ok for the UI
f59003f
to
be1766e
Compare
const migration: Migration = { | ||
_id: new ObjectId("65f7ff14298f30c5060eb6ac"), | ||
name: "Refresh assistants count for last 24 hours", | ||
// eslint-disable-next-line no-shadow | ||
up: async (client) => { | ||
const { assistantStats } = getCollections(client); | ||
const currentDate = new Date(); | ||
const twentyFourHoursAgo = new Date(); | ||
twentyFourHoursAgo.setDate(twentyFourHoursAgo.getDate() - 1); // subtract 24 hours (i.e. 1 day) | ||
|
||
assistantStats.aggregate([ | ||
{ $match: { dateDay: { $gte: twentyFourHoursAgo, $lt: currentDate } } }, | ||
{ | ||
$group: { | ||
_id: { _id: "$_id", dateWithHour: "$dateWithHour" }, | ||
totalCount: { $sum: "$count" }, | ||
}, | ||
}, | ||
{ | ||
$merge: { | ||
into: "assistants", | ||
on: "_id", | ||
whenMatched: [ | ||
{ | ||
$set: { | ||
"last24HoursCount.count": "$$ROOT.totalCount", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't think you need to put it in a Migration
anymore?
Just to be clear, let's not mix up cron jobs & migrations in the migrations
collection
I don't think we need to store cron job results in DB, but if we do, probably a separate collection
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I was in assumption that multiple machines are running chat-ui (and the call below might be called my multiple machines within a same period). therefore, we would need to use Migration & locks. No ?
Line 26 in 58f3eac
refreshAssistantsCounts(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
locks yes, but no need for Migration
We can create a lock on refresh-assistant-counts
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
handled in 0803740
- Removed usage of
Migration
- Also set those lines below to make sure that different machines will try to run the refresh "cron" job at the same time (i.e. synced even if the machines start at different times)
chat-ui/src/lib/assistantStats/refresh-assistants-counts.ts
Lines 70 to 79 in 0803740
const now = new Date(); | |
const nextHour = startOfHour(addHours(now, 1)); | |
const delay = nextHour.getTime() - now.getTime(); | |
const ONE_HOUR_MS = 3_600_000; | |
// wait until the next hour to start the hourly interval | |
setTimeout(() => { | |
refreshAssistantsCountsHelper(); | |
setInterval(refreshAssistantsCountsHelper, ONE_HOUR_MS); |
based on #938 (review), I've committed 93c9ebc Description:
|
Did several backend changes
Maybe the lock mechanism ( |
@nsarrazin wdyt ? |
Nice! Doing one last pass |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks good to me! If I can help with the deployment let me know 😁
checking one more time from my end & will ping you on deployment |
as written in the dscription
I've hidden the UI 4dd7e65 Ready to merge & deploy @nsarrazin |
Description
There is a new field
assistant.last24HoursCount
that will be used to sort assistants intrending
manner.The trick is: we created a 24-hour window rolling counter for assistants by running the function below every hour:
using semaphore/lock/migration helpers from #897 to make sure that this periodic function runs correctly & runs only on one instance (no double running)
Screenshots
Deployment plan