admin管理员组文章数量:1386858
In my NestJS app, I am trying to work on something that could take anywhere between 10-20 minutes of completion. So, the user clicks on a button and an API is called which does some starts to do its processes that would take this amount of time.
To paint a better picture, think of it like this: There is a web app where there is one process that takes some time. You end up showing the user progress updates on the frontend. So the user could see "Generating summary of your document" and then "Doing some more relevant work", etc.
While this goes on, I would like it that the progress is saved as well so that if the user navigates away, the can still come back and pick up where the progress left off (i.e. the UI would be updated). And once it's all complete, it would move forward
I want that when the user calls that API, it does not hinder the process or gets blocked. I thought about using Server-Sent-Events (SSE) for this but, SSE would just get disconnected if the user navigates away. So, how would I go about doing this? In an API where I am generating a response from OpenAI, I am using SSE for a more responsive feel (this is a trimmed snippet of my code):
@Sse(':id/generate-answer')
async answerWithMagic(
@Param('id') id,
) {
const messages = this.aiService.resolvePrompt();
const stream = new Subject();
this.aiService
.generateCompletion({ messages, listenTokens: true, isJsonParsable: false })
.pipe(
takeWhile((data) => {
if (data.eventType === LLM_END_EVENT) {
stream.next({
eventType: data.eventType,
data: { token: data.token },
});
return false;
} else {
return true;
}
}),
)
.subscribe((data) => {
stream.next({ eventType: data.eventType, data: { token: data.token } });
});
return stream;
}
How do I save the progress here? Making repeated calls to the database would not be very efficient so I thought about using Redis where I store the progress there but I am not sure which direction to take here with this.
In my NestJS app, I am trying to work on something that could take anywhere between 10-20 minutes of completion. So, the user clicks on a button and an API is called which does some starts to do its processes that would take this amount of time.
To paint a better picture, think of it like this: There is a web app where there is one process that takes some time. You end up showing the user progress updates on the frontend. So the user could see "Generating summary of your document" and then "Doing some more relevant work", etc.
While this goes on, I would like it that the progress is saved as well so that if the user navigates away, the can still come back and pick up where the progress left off (i.e. the UI would be updated). And once it's all complete, it would move forward
I want that when the user calls that API, it does not hinder the process or gets blocked. I thought about using Server-Sent-Events (SSE) for this but, SSE would just get disconnected if the user navigates away. So, how would I go about doing this? In an API where I am generating a response from OpenAI, I am using SSE for a more responsive feel (this is a trimmed snippet of my code):
@Sse(':id/generate-answer')
async answerWithMagic(
@Param('id') id,
) {
const messages = this.aiService.resolvePrompt();
const stream = new Subject();
this.aiService
.generateCompletion({ messages, listenTokens: true, isJsonParsable: false })
.pipe(
takeWhile((data) => {
if (data.eventType === LLM_END_EVENT) {
stream.next({
eventType: data.eventType,
data: { token: data.token },
});
return false;
} else {
return true;
}
}),
)
.subscribe((data) => {
stream.next({ eventType: data.eventType, data: { token: data.token } });
});
return stream;
}
How do I save the progress here? Making repeated calls to the database would not be very efficient so I thought about using Redis where I store the progress there but I am not sure which direction to take here with this.
Share Improve this question edited Mar 17 at 10:09 VLAZ 29.1k9 gold badges63 silver badges84 bronze badges asked Mar 17 at 9:51 AnAverageDevAnAverageDev 1651 gold badge2 silver badges13 bronze badges 1- I think most easiest way to add a progress column. While adding new technology, be aware of the trade offs. My thinking is for only this purpose redis will be overkill. – Kazi Akib Javed Commented Mar 19 at 4:36
1 Answer
Reset to default 2I think that your approach is okay.
The idea is to run the long task on background and to use Redis to keep track of the progress. For the task computation you can use BullMQ (Redis-based queue) that is directly supported by NestJS: https://docs.nestjs/techniques/queues .
So, technically, you have to create a RedisService that will contains the methods to set and get the progress of the task:
@Injectable()
export class RedisService {
private redis: Redis;
constructor() {
this.redis = new Redis({
host: process.env.REDIS_HOST || 'localhost',
port: parseInt(process.env.REDIS_PORT, 10) || 6379,
});
}
async setProgress(taskId: string, progress: any) {
await this.redis.set(`progress:${taskId}`, JSON.stringify(progress), 'EX', 3600); // TTL 1 hour
}
async getProgress(taskId: string) {
const progress = await this.redis.get(`progress:${taskId}`);
return progress ? JSON.parse(progress) : null;
}
}
Then, you have to inject the RedisService into the service that handle the task to store the progresses.
After that, you just have to create another endpoint to retrieve the task updates:
@Post(':id/generate-answer')
async startTask(@Param('id') taskId: string) {
// Run task with BullMQ
}
@Get(':id/progress')
async getProgress(@Param('id') taskId: string) {
const progress = await this.redisService.getProgress(taskId);
return progress ?? { progress: 0, message: 'Not started' };
}
The Frontend can poll /tasks/:id/progress every few seconds (or reconnect SSE if they stay).
本文标签: nodejsSending API39s progress updates periodically and saving progressStack Overflow
版权声明:本文标题:node.js - Sending API's progress updates periodically and saving progress - Stack Overflow 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.betaflare.com/web/1744568905a2613220.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论