Skip to content
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

fix(firestore-bigquery-export): Add Backward Compatibility and New Event Types for Firestore BigQuery Export #2244

Open
wants to merge 1 commit into
base: next
Choose a base branch
from

Conversation

Gustolandia
Copy link
Contributor

#1981

Description (issue 1981):
This PR introduces backward-compatible event types while adding new naming conventions for Firestore BigQuery Export. The changes ensure robust event handling across multiple versions of the extension. The following updates have been made:

Key Changes:
1. New Event Types:
• Introduced new events using the updated naming convention:
• firebase.extensions.firestore-bigquery-export.v1.onStart
• firebase.extensions.firestore-bigquery-export.v1.onSuccess
• firebase.extensions.firestore-bigquery-export.v1.onError
• firebase.extensions.firestore-bigquery-export.v1.onCompletion
2. Backward Compatibility:
• Maintains the existing events under the old naming convention:
• firebase.extensions.firestore-counter.v1.*
• Both old and new event types are published for each operation to ensure smooth migration.
3. Refactored Event Publishing:
• Updated event publishing logic to dynamically handle both old and new event types.
• Functions now publish events using Promise.all for better concurrency.
4. Unit Tests:
• Enhanced unit tests to verify:
• Events for both old and new naming conventions are correctly published.
• Proper handling of CREATE, DELETE, and UPDATE scenarios.
• Mocked Eventarc interactions for improved testing reliability.
5. Code Improvements:
• Refactored events.ts to dynamically generate both old and new event types for reuse.
• Added extensive documentation to clarify the event publishing logic and backward compatibility strategy.

Testing:
1.	Unit Tests:
•	Added test cases for CREATE, DELETE, and UPDATE scenarios.
•	Verified that both old (firestore-counter) and new (firestore-bigquery-export) event types are published.
2.	Local Testing:
•	Tested event publishing with mocked Eventarc to ensure consistency.
•	Verified performance and reliability with simulated Firestore data changes.

Checklist:
•	Code refactored for event compatibility.
•	Tests updated and passed successfully.
•	Documentation updated for event naming conventions.
•	Verified performance under high-load scenarios.

Notes:
•	This PR ensures compatibility while transitioning to the new naming convention.
•	Developers can gradually update their consumers to listen for new events.
•	Legacy systems will remain unaffected by these changes.

@Gustolandia Gustolandia added type: bug Something isn't working extension: firestore-bigquery-export Related to firestore-bigquery-export extension labels Dec 20, 2024
@Gustolandia Gustolandia self-assigned this Dec 20, 2024
@Gustolandia Gustolandia force-pushed the @invertase/Extensions/firestore-bigquery-export/1981 branch from aa614f5 to 925668e Compare December 20, 2024 18:23
@Gustolandia Gustolandia requested a review from CorieW December 20, 2024 18:34
@Gustolandia Gustolandia linked an issue Dec 20, 2024 that may be closed by this pull request
@cabljac cabljac changed the title fix(firestore-bigquery-export): @invertase: Add Backward Compatibility and New Event Types for Firestore BigQuery Export fix(firestore-bigquery-export): Add Backward Compatibility and New Event Types for Firestore BigQuery Export Dec 23, 2024
/**
* Generates both the OLD and NEW event types to maintain backward compatibility.
*
* Old Event Type: firebase.extensions.firestore-counter.v1.{eventName}
Copy link
Contributor

Choose a reason for hiding this comment

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

I'm not sure we should be publishing both, i think we probably want a breaking change here, @pr-Mais ?

Copy link
Member

Choose a reason for hiding this comment

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

probably yes, but should be documented well in the CHANGELOG

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I thought we had agreed in not having breaking changes. Can you explain what is the issue @cabljac @pr-Mais ?

@Gustolandia Gustolandia force-pushed the @invertase/Extensions/firestore-bigquery-export/1981 branch 3 times, most recently from 9ddae40 to 3fcac8e Compare December 28, 2024 01:08
Comment on lines +196 to +203
- param: EXT_INSTANCE_ID
label: Extension Instance ID
description: >-
What is the unique identifier for this instance of the extension? This ID
ensures that multiple instances do not interfere with one another. It is
set automatically by Firebase but can also be customized if required.
required: true

Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
- param: EXT_INSTANCE_ID
label: Extension Instance ID
description: >-
What is the unique identifier for this instance of the extension? This ID
ensures that multiple instances do not interfere with one another. It is
set automatically by Firebase but can also be customized if required.
required: true

Since other extensions don't use unique extension ID for the events, let's keep it consistent.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I added this based on your previous comments regarding several instances of the same extension.

Copy link
Member

Choose a reason for hiding this comment

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

Yeah, after second thought we agreed on keeping the behaviour consistent with other extensions

*/
const getEventTypes = (eventName: string) => [
`firebase.extensions.firestore-counter.v1.${eventName}`, // OLD Event Type for backward compatibility
`firebase.extensions.${EXTENSION_NAME}.v1.${eventName}`, // NEW Event Type following the updated convention
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
`firebase.extensions.${EXTENSION_NAME}.v1.${eventName}`, // NEW Event Type following the updated convention
`firebase.extensions.firestore-bigquery-export.v1.${eventName}`, // NEW Event Type following the updated convention

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Same as before: I added this based on your previous comments regarding several instances of the same extension.

export const recordStartEvent = async (data: string | object) => {
if (!eventChannel) return;
if (!eventChannel) return Promise.resolve(); // Explicitly return a resolved Promise
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
if (!eventChannel) return Promise.resolve(); // Explicitly return a resolved Promise
if (!eventChannel) return Promise.resolve();

Copy link
Contributor Author

Choose a reason for hiding this comment

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

But if there is no eventChannel?

Copy link
Member

Choose a reason for hiding this comment

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

What do you mean? I just removed the comment, not needed as the return is self-explanatory.

export const recordErrorEvent = async (err: Error, subject?: string) => {
if (!eventChannel) return;
if (!eventChannel) return Promise.resolve(); // Ensure consistent return type
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
if (!eventChannel) return Promise.resolve(); // Ensure consistent return type
if (!eventChannel) return Promise.resolve();

Copy link
Contributor Author

Choose a reason for hiding this comment

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

But if there is no eventChannel?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Sorry my bad.

export const recordSuccessEvent = async ({
subject,
data,
}: {
subject: string;
data: string | object;
}) => {
if (!eventChannel) return;
if (!eventChannel) return Promise.resolve(); // Explicitly return a resolved Promise
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
if (!eventChannel) return Promise.resolve(); // Explicitly return a resolved Promise
if (!eventChannel) return Promise.resolve();

Copy link
Contributor Author

Choose a reason for hiding this comment

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

But if there is no eventChannel?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Sorry my bad.

export const recordCompletionEvent = async (data: string | object) => {
if (!eventChannel) return;
if (!eventChannel) return Promise.resolve(); // Ensure consistent return type
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
if (!eventChannel) return Promise.resolve(); // Ensure consistent return type
if (!eventChannel) return Promise.resolve();

Copy link
Contributor Author

Choose a reason for hiding this comment

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

But if there is no eventChannel?

Copy link
Contributor

Choose a reason for hiding this comment

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

This suggested change is just to remove the unnecessary code comment

Copy link
Contributor

Choose a reason for hiding this comment

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

fyi - in an async function, return; is the same as return Promise.resolve() .

It's implied by the async keyword.

Copy link
Contributor

Choose a reason for hiding this comment

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

ts might complain about some difference between Promise<void> and Promise<undefined>

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Sorry my bad.

@Gustolandia Gustolandia requested a review from pr-Mais December 30, 2024 18:17
@cabljac cabljac requested a review from a team as a code owner January 6, 2025 11:21
@cabljac cabljac force-pushed the @invertase/Extensions/firestore-bigquery-export/1981 branch from 3fcac8e to 15cc2b0 Compare January 6, 2025 12:26
@cabljac cabljac force-pushed the @invertase/Extensions/firestore-bigquery-export/1981 branch from 15cc2b0 to 26951aa Compare January 6, 2025 12:26
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
extension: firestore-bigquery-export Related to firestore-bigquery-export extension type: bug Something isn't working
Projects
None yet
Development

Successfully merging this pull request may close these issues.

🐛 [firestore-bigquery-export] Fix eventArc event types
3 participants