firebase-tools icon indicating copy to clipboard operation
firebase-tools copied to clipboard

Enabling functions triggers after `withFunctionTriggersDisabled` is slower in newer versions of `firebase-tools`

Open giacomoran opened this issue 2 years ago • 3 comments

[REQUIRED] Environment info

firebase-tools: 11.2.1

Platform: Ubuntu

[REQUIRED] Test case

Run an empty promise with a 500ms delay in @firebase/rules-unit-testing's withFunctionTriggersDisabled; record the time it takes for the emulator to re-enable function triggers after the task is complete.

[REQUIRED] Steps to reproduce

Prepare project

I have created a reproduction repo at https://github.com/GiacomoRandazzo/slow-enable-functions-triggers. I've followed the Get started guide for Firebase Functions and added the following script which runs an empty promise with a 500ms delay in @firebase/rules-unit-testing's withFunctionTriggersDisabled.

import { withFunctionTriggersDisabled } from "@firebase/rules-unit-testing";
import debug from "debug";

// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - //

const PROJECT_ID = "demo";
const log = debug(PROJECT_ID);

// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - //

log("outer: START");
await withFunctionTriggersDisabled(
  { host: "localhost", port: 4400 },
  async () => {
    log("inner: START");
    await new Promise((resolve) => setTimeout(resolve, 500));
    log("inner: STOP");
  }
);
log("outer: STOP");

Note that the elapsed time between the logs inner: STOP and outer: STOP corresponds to the amount of time the emulator takes to re-enable functions triggers in withFunctionTriggersDisabled. I rely on the debug package for tracking the elapsed time between logs.

Run

  • start the emulator (npm run dev in the reproduction repo)
  • run the script (npm run tools in the reproduction repo), take note of the elapsed time between the logs inner: STOP and outer: STOP
  • upgrade firebase-tools from version 9.23.3 to version 11.2.1
  • repeat the first two steps

[REQUIRED] Expected behavior

The amount of time it takes to re-enable functions triggers in withFunctionTriggersDisabled in version 11.2.1 should be as small as in version 9.23.3.

[REQUIRED] Actual behavior

We see a slowdown of an order of magnitude:

  • in version 9.23.3 it takes 219 ms to re-enable function triggers in version 9.23.3

  • in version 11.2.1 it takes 2 s to re-enable function triggers in version 11.2.1

Use case

This bug prevents us from using newer versions of firebase-tools. We rely extensively on withFunctionTriggersDisabled in our function tests:

  • we share the same emulator instance between tests
  • for each test, we reset Firestore and import the needed data with function triggers disabled
  • we then perform some action and check the state of Firestore after the tested function runs

In our actual repo, with firebase-tools 11.2.1, it takes >10 s to re-enable function triggers. Having to run many tests, this is unusably slow. I have researched the issue, but can't find the problem mentioned elsewhere. This surprised me, are we taking the wrong approach?

giacomoran avatar Jul 12 '22 15:07 giacomoran

This issue does not have all the information required by the template. Looks like you forgot to fill out some sections. Please update the issue with more information.

google-oss-bot avatar Jul 12 '22 15:07 google-oss-bot

Hey @GiacomoRandazzo sorry that you ran into this issue. Unfortunately, this behavior is due to an internal change that we made to the CLI and SDK a while back. In order to add more features to firebase functions, we had the change the way functions were discovered. We brought this behavior to the emulator since we wanted to replicate the actual deployment process. We'll discuss internally if we can speed up this process. Thanks

colerogers avatar Jul 26 '22 14:07 colerogers

Thank you for looking into this.

For now, we worked around the problem by sending HTTP requests to the emulator at the undocumented endpoints for enabling/disabling the Cloud Functions. It affords us a little more control.

For reference:

  • Enable Cloud Functions PUT http://${HOST_HUB}/functions/enableBackgroundTriggers
  • Disable Cloud Functions PUT http://${HOST_HUB}/functions/disableBackgroundTriggers

giacomoran avatar Jul 26 '22 15:07 giacomoran

Any progress here @colerogers? This heavily affects our team too

wmadden avatar Oct 19 '22 10:10 wmadden

@wmadden Unfortunately, we haven't had time to get to this feature yet. Is your team able to use the workaround that @GiacomoRandazzo posted?

colerogers avatar Oct 19 '22 13:10 colerogers

Yes, we're also using the HTTP endpoints directly (I see they're now documented 🙏🏻 )

wmadden avatar Oct 19 '22 14:10 wmadden