Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
25 commits
Select commit Hold shift + click to select a range
8717527
feat: implement parallel operations
ddelgrosso1 Aug 15, 2022
22097df
add more parallel operations
ddelgrosso1 Sep 15, 2022
9a59f1f
add header to test file
ddelgrosso1 Sep 15, 2022
d2b241f
update import of fs/promises
ddelgrosso1 Sep 15, 2022
30b45d3
fix pathing on windows, fix mocking of fs promises
ddelgrosso1 Sep 16, 2022
16a5f05
add jsdoc headers to class and uploadMulti
ddelgrosso1 Sep 16, 2022
5a94aa7
add jsdoc comments to remaining functions
ddelgrosso1 Sep 30, 2022
1cc8bae
update comment wording
ddelgrosso1 Oct 24, 2022
face55f
add experimental jsdoc tags
ddelgrosso1 Oct 27, 2022
524a310
feat: add directory generator to performance test framework
ddelgrosso1 Nov 3, 2022
bac3ed8
clarify variable names and comments
ddelgrosso1 Nov 3, 2022
b4bc333
capitalization
ddelgrosso1 Nov 3, 2022
46687c6
wip: transfer manager performance tests
ddelgrosso1 Nov 10, 2022
721aab6
feat: merged in application performance tests (#2100)
shaffeeullah Nov 10, 2022
f5e8121
fix: fixed many bugs (#2102)
shaffeeullah Nov 15, 2022
886dc03
fix: more work on transfer manager perf metrics (#2103)
ddelgrosso1 Nov 15, 2022
94b1c02
fix: performance test refactoring, comments (#2104)
ddelgrosso1 Nov 16, 2022
9793cc6
refactor: refactor constants (#2105)
shaffeeullah Nov 16, 2022
89e8204
linter fixes, download to disk for performance test
ddelgrosso1 Nov 29, 2022
c153ab6
rename transfer manager functions
ddelgrosso1 Nov 29, 2022
4feb1c2
remove callbacks from transfer manager
ddelgrosso1 Nov 29, 2022
0780e50
add more experimental tags, update comments
ddelgrosso1 Nov 29, 2022
c47130b
change signature of downloadManyFiles to accept array of strings or a…
ddelgrosso1 Nov 30, 2022
4c2dda4
linter fix
ddelgrosso1 Nov 30, 2022
aad8f2b
add transfer manager samples and samples tests
ddelgrosso1 Dec 1, 2022
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
add transfer manager samples and samples tests
  • Loading branch information
ddelgrosso1 committed Dec 1, 2022
commit aad8f2bfd724ac3aa4ea7588b7e5cbaa15309aa2
77 changes: 77 additions & 0 deletions samples/downloadFileInChunksWithTransferManager.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
/**
* Copyright 2022 Google LLC
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* @experimental
*/

const path = require('path');
const cwd = path.join(__dirname, '..');

// sample-metadata:
// title: Download a File in Chunks Utilzing Transfer Manager
// description: Downloads a single file in in chunks in parallel utilizing transfer manager.
// usage: node downloadFileInChunksWithTransferManager.js <BUCKET_NAME> <FILE_NAME> <DESTINATION_FILE_NAME> <CHUNK_SIZE>

function main(
bucketName = 'my-bucket',
fileName = 'file1.txt',
destFileName = path.join(cwd, fileName),
chunkSize = 1024
) {
// [START storage_download_many_files_transfer_manager]
/**
* TODO(developer): Uncomment the following lines before running the sample.
*/
// The ID of your GCS bucket
// const bucketName = 'your-unique-bucket-name';

// The ID of the GCS file to download
// const fileName = 'your-file-name';

// The path to which the file should be downloaded
// const destFileName = '/local/path/to/file.txt';

// The size of each chunk to be downloaded
// const chunkSize = 1024;

// Imports the Google Cloud client library
const {Storage, TransferManager} = require('@google-cloud/storage');

// Creates a client
const storage = new Storage();

// Creates a transfer manager instance
const transferManager = new TransferManager(storage.bucket(bucketName));

async function downloadFileInChunksWithTransferManager() {
// Downloads the files
await transferManager.downloadFileInChunks(fileName, {
destination: destFileName,
chunkSizeBytes: chunkSize,
});

console.log(
`gs://${bucketName}/${fileName} downloaded to ${destFileName}.`
);
}

downloadFileInChunksWithTransferManager().catch(console.error);
// [END storage_download_many_files_transfer_manager]
}

process.on('unhandledRejection', err => {
console.error(err.message);
process.exitCode = 1;
});
main(...process.argv.slice(2));
67 changes: 67 additions & 0 deletions samples/downloadManyFilesWithTransferManager.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
/**
* Copyright 2022 Google LLC
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* @experimental
*/

// sample-metadata:
// title: Download Many Files With Transfer Manager
// description: Downloads many files in parallel utilizing transfer manager.
// usage: node downloadManyFilesWithTransferManager.js <BUCKET_NAME> <FIRST_FILE_NAME> <SECOND_FILE_NAME>

function main(
bucketName = 'my-bucket',
firstFileName = 'file1.txt',
secondFileName = 'file2.txt'
) {
// [START storage_download_many_files_transfer_manager]
/**
* TODO(developer): Uncomment the following lines before running the sample.
*/
// The ID of your GCS bucket
// const bucketName = 'your-unique-bucket-name';

// The ID of the first GCS file to download
// const firstFileName = 'your-first-file-name';

// The ID of the second GCS file to download
// const secondFileName = 'your-second-file-name;

// Imports the Google Cloud client library
const {Storage, TransferManager} = require('@google-cloud/storage');

// Creates a client
const storage = new Storage();

// Creates a transfer manager instance
const transferManager = new TransferManager(storage.bucket(bucketName));

async function downloadManyFilesWithTransferManager() {
// Downloads the files
await transferManager.downloadManyFiles([firstFileName, secondFileName]);

for (const fileName of [firstFileName, secondFileName]) {
console.log(`gs://${bucketName}/${fileName} downloaded to ${fileName}.`);
}
}

downloadManyFilesWithTransferManager().catch(console.error);
// [END storage_download_many_files_transfer_manager]
}

process.on('unhandledRejection', err => {
console.error(err.message);
process.exitCode = 1;
});
main(...process.argv.slice(2));
1 change: 1 addition & 0 deletions samples/downloaded.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Hello World!
1 change: 1 addition & 0 deletions samples/resources/test2.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Hello World 2!
85 changes: 85 additions & 0 deletions samples/system-test/transfer-manager.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
// Copyright 2022 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

'use strict';

const path = require('path');
const {Storage} = require('@google-cloud/storage');
const {before, after, it, describe} = require('mocha');
const uuid = require('uuid');
const cp = require('child_process');
const {assert} = require('chai');

const execSync = cmd => cp.execSync(cmd, {encoding: 'utf-8'});
const storage = new Storage();
const cwd = path.join(__dirname, '..');
const bucketName = generateName();
const bucket = storage.bucket(bucketName);
const firstFileName = 'test.txt';
const secondFileName = 'test2.txt';
const firstFilePath = path.join(cwd, 'resources', firstFileName);
const secondFilePath = path.join(cwd, 'resources', secondFileName);
const downloadFilePath = path.join(cwd, 'downloaded.txt');
const chunkSize = 1024;

describe('transfer manager', () => {
before(async () => {
await bucket.create();
});

after(async () => {
await bucket.deleteFiles({force: true}).catch(console.error);
await bucket.delete().catch(console.error);
});

it('should upload multiple files', async () => {
const output = execSync(
`node uploadManyFilesWithTransferManager.js ${bucketName} ${firstFilePath} ${secondFilePath}`
);
assert.match(
output,
new RegExp(
`${firstFilePath} uploaded to ${bucketName}.\n${secondFilePath} uploaded to ${bucketName}`
)
);
});

it('should download mulitple files', async () => {
const output = execSync(
`node downloadManyFilesWithTransferManager.js ${bucketName} ${firstFilePath} ${secondFilePath}`
);
assert.match(
output,
new RegExp(
`gs://${bucketName}/${firstFilePath} downloaded to ${firstFilePath}.\ngs://${bucketName}/${secondFilePath} downloaded to ${secondFilePath}.`
)
);
});

it('should download a file utilizing chunked download', async () => {
const output = execSync(
`node downloadFileInChunksWithTransferManager.js ${bucketName} ${firstFilePath} ${downloadFilePath} ${chunkSize}`
);
assert.match(
output,
new RegExp(
`gs://${bucketName}/${firstFilePath} downloaded to ${downloadFilePath}.`
)
);
});
});

function generateName() {
return `nodejs-storage-samples-${uuid.v4()}`;
}
67 changes: 67 additions & 0 deletions samples/uploadManyFilesWithTransferManager.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
/**
* Copyright 2022 Google LLC
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* @experimental
*/

// sample-metadata:
// title: Upload Many Files With Transfer Manager
// description: Uploads many files in parallel utilizing transfer manager.
// usage: node uploadManyFilesWithTransferManager.js <BUCKET_NAME> <FIRST_FILE_NAME> <SECOND_FILE_NAME>

function main(
bucketName = 'my-bucket',
firstFilePath = './local/path/to/file1.txt',
secondFilePath = './local/path/to/file2.txt'
) {
// [START storage_upload_many_files_transfer_manager]
/**
* TODO(developer): Uncomment the following lines before running the sample.
*/
// The ID of your GCS bucket
// const bucketName = 'your-unique-bucket-name';

// The ID of the first GCS file to download
// const firstFileName = 'your-first-file-name';

// The ID of the second GCS file to download
// const secondFileName = 'your-second-file-name;

// Imports the Google Cloud client library
const {Storage, TransferManager} = require('@google-cloud/storage');

// Creates a client
const storage = new Storage();

// Creates a transfer manager instance
const transferManager = new TransferManager(storage.bucket(bucketName));

async function uploadManyFilesWithTransferManager() {
// Uploads the files
await transferManager.uploadManyFiles([firstFilePath, secondFilePath]);

for (const filePath of [firstFilePath, secondFilePath]) {
console.log(`${filePath} uploaded to ${bucketName}.`);
}
}

uploadManyFilesWithTransferManager().catch(console.error);
// [END storage_upload_many_files_transfer_manager]
}

process.on('unhandledRejection', err => {
console.error(err.message);
process.exitCode = 1;
});
main(...process.argv.slice(2));
8 changes: 6 additions & 2 deletions src/transfer-manager.ts
Original file line number Diff line number Diff line change
Expand Up @@ -270,7 +270,7 @@ export class TransferManager {
* Download a large file in chunks utilizing parallel download operations. This is a convenience method
* that utilizes {@link File#download} to perform the download.
*
* @param {object} [file] {@link File} to download.
* @param {object} [file | string] {@link File} to download.
* @param {DownloadFileInChunksOptions} [options] Configuration options.
* @returns {Promise<DownloadResponse>}
*
Expand All @@ -291,7 +291,7 @@ export class TransferManager {
* @experimental
*/
async downloadFileInChunks(
file: File,
fileOrName: File | string,
options: DownloadFileInChunksOptions = {}
): Promise<void | DownloadResponse> {
let chunkSize =
Expand All @@ -300,6 +300,10 @@ export class TransferManager {
options.concurrencyLimit || DEFAULT_PARALLEL_CHUNKED_DOWNLOAD_LIMIT
);
const promises = [];
const file: File =
typeof fileOrName === 'string'
? this.bucket.file(fileOrName)
: fileOrName;

const fileInfo = await file.get();
const size = parseInt(fileInfo[0].metadata.size);
Expand Down