Skip to content

Refactor functions-delete #3110

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

Merged
merged 6 commits into from
Feb 9, 2021
Merged

Conversation

joehan
Copy link
Contributor

@joehan joehan commented Feb 5, 2021

Description

Refactoring functions-delete to use the same patterns as the rest of functions deployment. This lets us clean up a bunch of the old operation polling code, too.

Scenarios Tested

Delete a non-scheduled function that exists in 2 regions:
Screen Shot 2021-02-05 at 2 09 40 PM

Delete a scheduled function:
Screen Shot 2021-02-05 at 2 09 40 PM

@joehan joehan requested a review from inlined February 5, 2021 22:15
@google-cla google-cla bot added the cla: yes Manual indication that this has passed CLA. label Feb 5, 2021
@joehan joehan requested review from taeold and huangjeff5 February 5, 2021 22:15
import { DeploymentTimer } from "./deploy/functions/deploymentTimer";
import { ErrorHandler } from "./deploy/functions/errorHandler";

export async function deleteFunctions(
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In the future, I'd like to reuse this code during the normal functions deployment process too - I'm keeping it separate for now to avoid an ugly merge conflict with #3107

@@ -0,0 +1,88 @@
"use strict";

import * as _ from "lodash";
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Unused import

import { requirePermissions } from "../requirePermissions";
import * as utils from "../utils";

module.exports = new Command("functions:delete [filters...]")
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How pervasive is module.exports =? It seems strange that we're mixing coding styles (e.g. getProjectId is an exports = but the other imports in this file aren't). It's been a while, but I thought that this style was generally considered outdated and bad, especially when making exports a non-map type.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is definitely the wrong style - switched it over to our preferred export default new Command(....

const filterChunks = filters.map((filter: string) => {
return filter.split(".");
});
const config = await functionsConfig.getFirebaseConfig(options);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Totally not the point of this code review, but why is getFirebaseConfig part of functionsConfig? Is this a functions-specific portion of the firebase config?

import * as clc from "cli-color";
import * as cloudfunctions from "../gcp/cloudfunctions";
import * as functionsConfig from "../functionsConfig";
import { deleteFunctions } from "../functionsDelete";
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

TBF I can't honestly guess what the difference is between functionsDelete.js and functions-delete.ts

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good point, its super unclear and there probably isn't a good reason to keep the old names.

FWIW:
functions-delete follows the pattern we use for files defining the different firebase commands - firebase functions:delete is defined by the file functions-delete.ts, firebase database:get is defined by the file database-get, etc.
functionsDelete is just a file that contains code to delete functions - my guess is that whoever originally wrote the file named it as such so that it would show up in their IDE next to all of the other functions* files like functionsConfig, functionsDeployHelper, etc.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If I had a time machine I'd put functions-delete.ts in commands/functions/delete.ts but the ship has sailed.

return filter.split(".");
});
const config = await functionsConfig.getFirebaseConfig(options);
const appEngineLocation = functionsConfig.getAppEngineLocation(config);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

AFAICT, the GAE location is only used for scheduler locations. I miiiiiight consider having the local variable be schedulerRegion. Then it might read better as "oooh, I need the location because it's for scheudles and apparently the scheduler region is the GAE region". I might even add a comment for such because it's not obvious to a reader unless they're versed with the history of scheudler as a feature of GAE.

@@ -24,8 +24,8 @@ const defaultPollerOptions = {

export interface TaskParams {
projectId: string;
runtime: string;
sourceUrl: string;
runtime?: string;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm always suspicious when we make a field optional. Why are we doing that here?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For deleteFunction tasks, there's no use for runtime, so it probably should have been optional (or moved out of this params type) to begin with

@@ -40,7 +40,7 @@ export function createFunctionTask(
utils.logBullet(
clc.bold.cyan("functions: ") +
"creating " +
getHumanFriendlyRuntimeName(params.runtime) +
getHumanFriendlyRuntimeName(params.runtime!) +
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

per the comment about optionality, if we're calling runtime! then it seems like the field isn't actually optional.

@@ -0,0 +1,41 @@
import * as helper from "./functionsDeployHelper";
import { Queue } from "./throttler/queue";
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

=/ Why isn't this called a ThrottlerQueue or something that makes it not a CompSci 101 data structure? I didn't realize the importance of this class until I looked up why there was a second type parameter.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not sure, but i agree that this isn't a very clear name. It will have a larger impact radius than i want for this PR since this structure is used across a bunch of code paths, but I think we ought to to rename Queue to ThrottlerQueue and Stack to ThrottlerStack once the functions refactor is fully merged in.

cloudFunctionsQueue.process();
schedulerQueue.process();

await Promise.all(queuePromises);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Isn't there a bug here where we could fail to delete a schedule but succeed in deleting a function? The next time the user tried to do a delete operation we wouldn't see the function so we wouldn't see its schedule and we wouldn't ever clean up the customer's project.

eventTrigger?: any;
httpsTrigger?: any;
};
error?: { code: number; message: string };
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm surprised there isn't already a type for a Google error. I'm also vaguely surprised that there isn't already an Operation type. E.g. this could roughly be

import {Operation} from '../cloud/basicTypes';
import {CloudFunction} from '../cloud/cloudFunctions';

interface CloudFunctionOperation = Operation | CloudFunction;

});
if (functionsToDelete.length === 0) {
return utils.reject(
"The specified filters do not match any existing functions in project " +
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: would string substitution be better here i.e. The specified filters do not match any existing functions in project ${clc.bold(projectId}. for readability? Then we could fit it in one line.

const appEngineLocation = functionsConfig.getAppEngineLocation(config);
const existingFns = await cloudfunctions.listAllFunctions(projectId);
const functionsToDelete = existingFns.filter((fn) => {
const regionMatches = options.region ? helper.getRegion(fn.name) === options.region : true;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit - this might be a simpler way to express this:
!options.region || helper.getRegion(fn.name) === options.region

It's only a bit shorter, but to me it's more comprehensible because I don't have to first mentally convert it to an if statement.

Base automatically changed from jh-execute-deployment-plans to jh-functions-refactor February 9, 2021 20:48
@joehan joehan merged commit 6d2260e into jh-functions-refactor Feb 9, 2021
@joehan joehan deleted the jh-refactor-functions-delete branch February 9, 2021 22:44
joehan added a commit that referenced this pull request Feb 16, 2021
* Adding onPoll option to operation-poller (#3046)

* Adds onPoll option

* format and remove only

* improved unit test

* Typescriptify functionsDeployHelper (#3059)

* Typescriptifying and adding CloudFunctionTrigger type

* Using funcName instead of func

* formats

* Typescriptifying gcp.cloudfunctions (#3060)

* Typescriptifying functionsConfig (#3063)

* Typescriptifying deploymentTool (#3061)

* Typescriptifying deploymentTool

* Update src/deploymentTool.ts

Co-authored-by: Michael Bleigh <[email protected]>

Co-authored-by: Michael Bleigh <[email protected]>

* Refactoring prepare stage of functions deploy (#3067)

* refactoring prepare setp of functions deploy to use typescript, check for failure policies, and parse function triggers

* refactoring prepare setp of functions deploy to use typescript, check for failure policies, and parse function triggers

* commenting out functionNamesAreValid

* formats

* refactoring release step of functions deploy to use typescript

* Adding logic to build regional deployments

* Implementing createDeploymentPlan

* First round of PR feedback, removing most usages of lodash

* moving function prompts into their own file

* seperating out a bunch of code from functionsDeployHelper

* Resolves merge conflicts

* refactoring release step of functions deploy to use typescript (#3071)

* Implements core logic of running function deploys

* Typescriptifying prepareFunctionsUpload (#3064)

* Typescriptifying prepareFunctionsUpload, and updating filesize package to get types

* fixing merge conflict

* Implementing createDeploymentPlan (#3081)

* refactoring release step of functions deploy to use typescript

* Adding logic to build regional deployments

* Implementing createDeploymentPlan

* First round of PR feedback, removing most usages of lodash

* moving function prompts into their own file

* seperating out a bunch of code from functionsDeployHelper

* round of pr fixes

* adresses more pr comments, and adds some todos

* cleaning up unused code

* Fixing some things that were broken while merging

* Fixing up the order of wait and close to ensure that queue promsies actually resolve

* Format and clean up typos

* refactoring error handling to be cleaner

* cleaning up extera newlines

* first round of pr fixes

* Readding some changes that I accidenttally wiped out during a merge

* Switching name to id where appropriate

* fixing another bug caused by functionName vs Id

* Refactor functions-delete  (#3110)

* Refactoring functions delete to use tasks, and cleaning up old polling code

* Refactoring functions delete to use tasks, and cleaning up old polling code

* refactoring to use new error handling

* cleanup unused imports

* small style fixes

* Cleaning up error reporting

* Implement validation for changing trigger types, and fixes from bug bash (#3131)

* Implement validation for changing trigger types, and fixes from bug bash

* more specifc error messages for different permutations of trigger types

* fixes package.json

Co-authored-by: Michael Bleigh <[email protected]>
devpeerapong pushed a commit to devpeerapong/firebase-tools that referenced this pull request Dec 14, 2021
* Adding onPoll option to operation-poller (firebase#3046)

* Adds onPoll option

* format and remove only

* improved unit test

* Typescriptify functionsDeployHelper (firebase#3059)

* Typescriptifying and adding CloudFunctionTrigger type

* Using funcName instead of func

* formats

* Typescriptifying gcp.cloudfunctions (firebase#3060)

* Typescriptifying functionsConfig (firebase#3063)

* Typescriptifying deploymentTool (firebase#3061)

* Typescriptifying deploymentTool

* Update src/deploymentTool.ts

Co-authored-by: Michael Bleigh <[email protected]>

Co-authored-by: Michael Bleigh <[email protected]>

* Refactoring prepare stage of functions deploy (firebase#3067)

* refactoring prepare setp of functions deploy to use typescript, check for failure policies, and parse function triggers

* refactoring prepare setp of functions deploy to use typescript, check for failure policies, and parse function triggers

* commenting out functionNamesAreValid

* formats

* refactoring release step of functions deploy to use typescript

* Adding logic to build regional deployments

* Implementing createDeploymentPlan

* First round of PR feedback, removing most usages of lodash

* moving function prompts into their own file

* seperating out a bunch of code from functionsDeployHelper

* Resolves merge conflicts

* refactoring release step of functions deploy to use typescript (firebase#3071)

* Implements core logic of running function deploys

* Typescriptifying prepareFunctionsUpload (firebase#3064)

* Typescriptifying prepareFunctionsUpload, and updating filesize package to get types

* fixing merge conflict

* Implementing createDeploymentPlan (firebase#3081)

* refactoring release step of functions deploy to use typescript

* Adding logic to build regional deployments

* Implementing createDeploymentPlan

* First round of PR feedback, removing most usages of lodash

* moving function prompts into their own file

* seperating out a bunch of code from functionsDeployHelper

* round of pr fixes

* adresses more pr comments, and adds some todos

* cleaning up unused code

* Fixing some things that were broken while merging

* Fixing up the order of wait and close to ensure that queue promsies actually resolve

* Format and clean up typos

* refactoring error handling to be cleaner

* cleaning up extera newlines

* first round of pr fixes

* Readding some changes that I accidenttally wiped out during a merge

* Switching name to id where appropriate

* fixing another bug caused by functionName vs Id

* Refactor functions-delete  (firebase#3110)

* Refactoring functions delete to use tasks, and cleaning up old polling code

* Refactoring functions delete to use tasks, and cleaning up old polling code

* refactoring to use new error handling

* cleanup unused imports

* small style fixes

* Cleaning up error reporting

* Implement validation for changing trigger types, and fixes from bug bash (firebase#3131)

* Implement validation for changing trigger types, and fixes from bug bash

* more specifc error messages for different permutations of trigger types

* fixes package.json

Co-authored-by: Michael Bleigh <[email protected]>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
cla: yes Manual indication that this has passed CLA.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants