Skip to content
This repository has been archived by the owner on Apr 23, 2022. It is now read-only.

Fix foreach bug #925

Merged
merged 3 commits into from
Feb 24, 2020
Merged

Fix foreach bug #925

merged 3 commits into from
Feb 24, 2020

Conversation

dilin-MS
Copy link
Contributor

@dilin-MS dilin-MS commented Feb 20, 2020

In TypeScript, usage of foreach should be careful. If function inside foreach is asynchronous, foreach will not wait until all items are finished. (See Reference).

this PR:

  1. Fix foreach with async functions. Change to Promise.all(). Fix the bug.
  2. Change checkPrerequisite() function to return Promise<void> instead of Promise<boolean>. User will get error message when operation failed for not finding dependent extensions.

@@ -66,8 +66,8 @@ export abstract class ContainerDeviceBase implements Device {
return this.componentType;
}

async checkPrerequisites(): Promise<boolean> {
return true;
async checkPrerequisites(): Promise<void> {
Copy link
Member

Choose a reason for hiding this comment

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

Why not using the same signature as the other component? Then we can manage the checkPrerequisites as an interface.

E.g. in ArduinoDeviceBase.ts, the signature is async checkPrerequisites(operation: string): Promise<void>

Copy link
Contributor

Choose a reason for hiding this comment

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

I agree to have an interface like ExtensionDependent (you could find a proper name), which has methods "isExtensionAvailable" instead of "checkPrerequisities" and throw DependentExtensionNotFoundError.

In this way, any component which need installing dependent extension should implement this interface, such as

abstract class ContainerDeviceBase implement Device, ExtensionDependent {

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Currently checkPrerequisites(operation: string): Promise<void>; is the required method of interface Component.
Both ContainerDeviceBase and ArduinoDeviceBase needs to implement this method.
Is it necessary to move checkPrerequisite() to be another interface like ExtensionDependent?

For the different method signature:

  1. ts allows ignoring extra function parameters. More info see link. parameter operation: string does appears because they are not needed in the implementation of the function.
  2. eslint does not allow unused vars.

@@ -25,12 +25,10 @@ export class RemoteExtension {
return await checkExtensionAvailable(ExtensionName.Remote);
}

static async checkRemoteExtension(): Promise<void> {
static async checkRemoteExtension(operation: string): Promise<void> {
Copy link
Member

Choose a reason for hiding this comment

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

nit: can we manage the "operation" as enum type here?
It can provide us an overview of what kind of operations will need to check remote extension. Another benefit to use enum type here is improve the re-usability for the same operation used in multiple places.

Copy link
Contributor Author

@dilin-MS dilin-MS Feb 22, 2020

Choose a reason for hiding this comment

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

The Operation: string is used when in error message to help know what operation throws error. The value of operation varies a lot through the whole project. This is why I didn't set it as enum at the very beginning.

If we have a enum type for all operations, the list will be very large.
E.g. "create function application", "get credential from subscription id", "crete iot containerized project", "open project in remote", "configure project environment", "generate CRC", etc.
Really a big list since operations varies.

I agree that using a enum type to represent operation helps to maintain the code and improve the re-usability of operation string. Let's discuss further for a better implemention and we can set up a new PR to fix that avoid messing up this PR with too many changed files.

@@ -84,8 +85,11 @@ export abstract class ArduinoDeviceBase implements Device {
return await checkExtensionAvailable(ExtensionName.Arduino);
}

async checkPrerequisites(): Promise<boolean> {
return await ArduinoDeviceBase.isAvailable();
async checkPrerequisites(operation: string): Promise<void> {
Copy link
Member

Choose a reason for hiding this comment

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

Same here as I comment in the checkRemoteExtension api.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

See above.

@@ -76,7 +75,7 @@ export class IoTContainerizedProject extends IoTWorkbenchProjectBase {
openInNewWindow: boolean
): Promise<void> {
// Can only create project locally
await RemoteExtension.checkRemoteExtension();
await RemoteExtension.checkRemoteExtension("create iot containerized project");
Copy link
Member

Choose a reason for hiding this comment

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

The same operation string appears in many places.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

See above.

@dilin-MS dilin-MS merged commit 989d96f into develop Feb 24, 2020
@dilin-MS dilin-MS deleted the bug-fix-foreach branch February 24, 2020 01:43
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants