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

Enable download blob and zip within vscode for persicope uploaded logs to storage. #75

Closed

Conversation

Tatsinnit
Copy link
Member

@Tatsinnit Tatsinnit commented Jun 21, 2021

This PR caters need to handle the download and zip the dowloaded folder into the download folder location.

Good amount of detail here: #72

Currently, the download is achieved by user clicking on hyperlink which redirect user to the browser based experienced, but in the new way the experience the user will never need to leave the vscode eco-system.

These changes also are needed because the periscope clean-up PR which will result in clearing this *.zip file because it is not formed correctly and not needed. I've checked the az-cli implementation and essentially the az-cli also don't use the *.zip from periscope either, so this implementation makes more aligned to other tools as well.

This will also decouples the dependency on the *.zip link we generate which is uploaded by the periscope tool.

Along with various advantages we do have much better control over the zip structure and hierarchy.

Update: 22nd June:

Please refer more as to how thought process for this work evolved: #72

Introducing these changes in vscode is not that straight forward as it sounded: some key complications:

  • Poor Download U/X experience: The current downside to move away from the link to browser will be gone, and replaced with only message driven approach. ( this is something which seems inevitable)
  • Slower U/X experience: This will happen because the underlying code now deal with directly downloading the blob from storage and stream the download into the zip file and save it into the download folder all within vscode.
  • Maintenance of this code needs some guarantee and contract form the persicope tool that the blob folder structure will not change in future.
  • Breaking change: As a user-experience and tool related breaking change the vscode changes need to go first before any tool related changes to remove zip upload is removed. (This will take time to re-group with team - and is it worth it to break the tool to vscode contract effort.)

Copy link
Contributor

@itowlson itowlson left a comment

Choose a reason for hiding this comment

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

This is hard for me to review because I'm not sure what it's doing! I've left a few comments where I don't understand the code in itself; otherwise I trust you and the PMs to test it and make sure it does the right thing and is understandable to the users!

@@ -214,6 +216,105 @@ export async function generateDownloadableLinks(
}
}

export async function downloadableLinks(
Copy link
Contributor

Choose a reason for hiding this comment

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

This is a big function and the name and type don't really help me understand it. Does it return a list of links from which we will later download? Consider typing it as returning Promise<string[]> (and renaming it getDownloadLinks). Does it perform a download itself? Consider naming it downloadWhateverItDownloads (and returning Promise<void> or Promise<Errorable<null>>. Does it do something else? Find a name that expresses that, and consider what it is that it returns.

);

// Hide this all under single pupose funct which lik elike : getZipDir or get me dirname
const containerClient = blobServiceClient.getContainerClient(containerName);
Copy link
Contributor

Choose a reason for hiding this comment

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

The comment above this line is a good one. I don't think anything from this half of the function is used in the second half of the function. So move everything above here to its own function called e.g. getZipContainer or whatever expresses the intent.

if (item.kind === "prefix") {
listCurrentUploadedFolders.push(item.name);
}
}
Copy link
Contributor

Choose a reason for hiding this comment

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

You may be able to replace this loop with something like const currentFolders = (await containerClient.list(...)).filter(item => item.kind === prefix).map(item => item.name) but I am not sure if that enumeration is async - in that case filter and map may not be available.

}

// Sort and get the latest uploaded folder under the container used by periscope.
// const periscopeHtmlInterfaceList = [];
Copy link
Contributor

Choose a reason for hiding this comment

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

Tidy commented-out code here and throughout.


// Sort and get the latest uploaded folder under the container used by periscope.
// const periscopeHtmlInterfaceList = [];
// jszip for zipping
Copy link
Contributor

Choose a reason for hiding this comment

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

Does this comment add anything?

// and extract *.zip files which are individual node logs.
const latestBlobUploadedByPeriscope = blob.name.indexOf(listCurrentUploadedFolders.sort().reverse()[0]);

if (latestBlobUploadedByPeriscope !== -1 && path.extname(blob.name) !== '.zip' && blob.name.indexOf(nodeName) !== -1) {
Copy link
Contributor

Choose a reason for hiding this comment

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

Again consider includes instead of indexOf(...) === -1.

if (latestBlobUploadedByPeriscope !== -1 && path.extname(blob.name) !== '.zip' && blob.name.indexOf(nodeName) !== -1) {
// Get a block blob client
// https://docs.microsoft.com/en-us/azure/storage/blobs/storage-quickstart-blobs-nodejs-legacy#download-a-blob
const blockBlobClient = containerClient.getBlockBlobClient(blob.name);
Copy link
Contributor

Choose a reason for hiding this comment

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

Could everything from here to the bottom of the loop be a well-named helper function? It seems like a downloadBlobToFile kind of chunk.

Copy link
Contributor

Choose a reason for hiding this comment

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

Oh looking below maybe this isn't downloading the blob to a file.

// Get blob content from position 0 to the end
// In Node.js, get downloaded data by accessing downloadBlockBlobResponse.readableStreamBody
const downloadBlockBlobResponse = await blockBlobClient.download(0);
console.log('\nDownloaded blob content...');
Copy link
Contributor

Choose a reason for hiding this comment

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

Users won't see console.log. Consider using a progress notification if this is going to take a while.


function writeZipToDownloadLocation(nodeName: string, zip: JSZip) {
const downloadsFolder = require('downloads-folder');
console.log('\nDownloads folder is...');
Copy link
Contributor

Choose a reason for hiding this comment

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

Remove debugging code

if (message.command === "downloadLink") {
// Generate link mechanism is in place due to current behaviour of the aks-periscope tool. (which seems by design for now)
// more detail here: https://github.com/Azure/aks-periscope/issues/30
await longRunning(`Downloading ${message.text} logs in download location.`,
Copy link
Contributor

Choose a reason for hiding this comment

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

What happens when they are downloaded? Do you open the folder for the user?

@davidkydd
Copy link

Did you consider simply dropping support for zipping the outputs in VSCode? This is a convenience function that could be left up to user to do afterwards if they wished - and as you mention az-cli doesn't make use of the .zip, so there isn't a conventional periscope experience to uphold here or anything

@Tatsinnit
Copy link
Member Author

Tatsinnit commented Jun 22, 2021

Did you consider simply dropping support for zipping the outputs in VSCode? This is a convenience function that could be left up to user to do afterwards if they wished - and as you mention az-cli doesn't make use of the .zip, so there isn't a conventional periscope experience to uphold here or anything

Yep, we considered all options but as vscode user-experience the current U/X experience is the best solution for vscode ecosystem for the use of this tool.

For vscode ecosystem/audience the zip provides end-to-end experience with quick download and user-scenario for this is mostly to quickly run the tool and share the zip with CSS folks for diagnostics. Essentially if we drop zip then interesting quandary will be, what will the easy to use user experience? (the current behaviour was thought by the pms who work with end user and vscode audience)

The az-cli has its own different ecosystem which has its own usage, and since its pure command line they get away with bunch of text and asking user to download the storage-explorer and add the SAS Token to the container directly to the storage-explorer tool.

If we drop support for zip it will break the whole end-to-end experience for vscode which we designed this feature for.

@Tatsinnit
Copy link
Member Author

💡 Thank you so much for discussion, this is no longer necessary, further discussion and whole update reside here: #72 , periscope tool kept the zip as part of their output contract.

Thanks 🙏

@Tatsinnit Tatsinnit closed this Jun 30, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants