Debounce google cloud function using Google Cloud tasks queue

131 Views Asked by At

I am trying to update lastMessage on a chatRoom, So every time a message is created in the subcollection of the chat room it sets it as lastMessage on the chatRoom.

In order to avoid unnecessary writes on Firestore I want to use Google tasks with a handler.

Google tasks queues can delete existing tasks, so I thought to assign the room ID to the task and if you write 15 messages in 1 minute only the last one will have the update.

The problem

When I have executed a task with the chatRoomId, this task block any other creation despite of delete(id) is successful even hours later

things I tried

  • adding a prefix to the chatRoomId for the task works for the first message
  • I have checked the task console and no task to delete is there, but the error on .upsert remains on Exception from a finished function: Error: A task with ID abcde1234 already exists

My approach

import { onTaskDispatched } from "firebase-functions/v2/tasks";
import { TaskOptions, getFunctions } from "firebase-admin/functions";

export const taskHandler = onTaskDispatched(
  {
    retryConfig: {
      maxAttempts: 3,
      minBackoffSeconds: 60,
    },
    rateLimits: {
      maxConcurrentDispatches: 6,
    },
  },
  async (req) => {
    const lastMessage = req.data;
    // the second message doesn't arrive here
    console.log("lastMessage", lastMessage);
  }
);

// A function to import to use admin the queue
// To be used

export function tasks() {
  const queue = getFunctions().taskQueue("taskHandler");

  async function create(args) {
    const { id, seconds: scheduleDelaySeconds, data } = args;
    const options: TaskOptions = {
      id,
      scheduleDelaySeconds,
    };

    queue.enqueue(data, options);
  }

  async function upsert(args) {
    const { id = "" } = args;
    if (!id) return create(args);

    await queue.delete(id);
    await create(args);
  }

  return { upsert, create };
}



// usage example
// firestore triggers a function on create message
const exampleMessage = { text: "hello", created: Date.now() };
tasks().upsert({
  id: "chatRoomId",
  seconds: 60,
  data: exampleMessage,
});

0

There are 0 best solutions below