mirror of
https://code.forgejo.org/actions/cache.git
synced 2024-12-04 04:11:07 -05:00
Add progress tracking for blob uploads
This commit is contained in:
parent
18fe6e3304
commit
2df79913f5
4 changed files with 424 additions and 36 deletions
115
dist/restore-only/index.js
vendored
115
dist/restore-only/index.js
vendored
|
@ -9734,26 +9734,123 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
Object.defineProperty(exports, "__esModule", ({ value: true }));
|
Object.defineProperty(exports, "__esModule", ({ value: true }));
|
||||||
exports.uploadCacheArchiveSDK = void 0;
|
exports.uploadCacheArchiveSDK = exports.UploadProgress = void 0;
|
||||||
const core = __importStar(__nccwpck_require__(4850));
|
const core = __importStar(__nccwpck_require__(4850));
|
||||||
const storage_blob_1 = __nccwpck_require__(3864);
|
const storage_blob_1 = __nccwpck_require__(3864);
|
||||||
const errors_1 = __nccwpck_require__(6333);
|
const errors_1 = __nccwpck_require__(6333);
|
||||||
|
/**
|
||||||
|
* Class for tracking the upload state and displaying stats.
|
||||||
|
*/
|
||||||
|
class UploadProgress {
|
||||||
|
constructor(contentLength) {
|
||||||
|
this.contentLength = contentLength;
|
||||||
|
this.sentBytes = 0;
|
||||||
|
this.displayedComplete = false;
|
||||||
|
this.startTime = Date.now();
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* Sets the number of bytes sent
|
||||||
|
*
|
||||||
|
* @param sentBytes the number of bytes sent
|
||||||
|
*/
|
||||||
|
setSentBytes(sentBytes) {
|
||||||
|
this.sentBytes = sentBytes;
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* Returns the total number of bytes transferred.
|
||||||
|
*/
|
||||||
|
getTransferredBytes() {
|
||||||
|
return this.sentBytes;
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* Returns true if the upload is complete.
|
||||||
|
*/
|
||||||
|
isDone() {
|
||||||
|
return this.getTransferredBytes() === this.contentLength;
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* Prints the current upload stats. Once the upload completes, this will print one
|
||||||
|
* last line and then stop.
|
||||||
|
*/
|
||||||
|
display() {
|
||||||
|
if (this.displayedComplete) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const transferredBytes = this.sentBytes;
|
||||||
|
const percentage = (100 * (transferredBytes / this.contentLength)).toFixed(1);
|
||||||
|
const elapsedTime = Date.now() - this.startTime;
|
||||||
|
const uploadSpeed = (transferredBytes /
|
||||||
|
(1024 * 1024) /
|
||||||
|
(elapsedTime / 1000)).toFixed(1);
|
||||||
|
core.info(`Sent ${transferredBytes} of ${this.contentLength} (${percentage}%), ${uploadSpeed} MBs/sec`);
|
||||||
|
if (this.isDone()) {
|
||||||
|
this.displayedComplete = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* Returns a function used to handle TransferProgressEvents.
|
||||||
|
*/
|
||||||
|
onProgress() {
|
||||||
|
return (progress) => {
|
||||||
|
this.setSentBytes(progress.loadedBytes);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* Starts the timer that displays the stats.
|
||||||
|
*
|
||||||
|
* @param delayInMs the delay between each write
|
||||||
|
*/
|
||||||
|
startDisplayTimer(delayInMs = 1000) {
|
||||||
|
const displayCallback = () => {
|
||||||
|
this.display();
|
||||||
|
if (!this.isDone()) {
|
||||||
|
this.timeoutHandle = setTimeout(displayCallback, delayInMs);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
this.timeoutHandle = setTimeout(displayCallback, delayInMs);
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* Stops the timer that displays the stats. As this typically indicates the upload
|
||||||
|
* is complete, this will display one last line, unless the last line has already
|
||||||
|
* been written.
|
||||||
|
*/
|
||||||
|
stopDisplayTimer() {
|
||||||
|
if (this.timeoutHandle) {
|
||||||
|
clearTimeout(this.timeoutHandle);
|
||||||
|
this.timeoutHandle = undefined;
|
||||||
|
}
|
||||||
|
this.display();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
exports.UploadProgress = UploadProgress;
|
||||||
function uploadCacheArchiveSDK(signedUploadURL, archivePath, options) {
|
function uploadCacheArchiveSDK(signedUploadURL, archivePath, options) {
|
||||||
|
var _a;
|
||||||
return __awaiter(this, void 0, void 0, function* () {
|
return __awaiter(this, void 0, void 0, function* () {
|
||||||
|
const blobClient = new storage_blob_1.BlobClient(signedUploadURL);
|
||||||
|
const blockBlobClient = blobClient.getBlockBlobClient();
|
||||||
|
const properties = yield blobClient.getProperties();
|
||||||
|
const contentLength = (_a = properties.contentLength) !== null && _a !== void 0 ? _a : -1;
|
||||||
|
const uploadProgress = new UploadProgress(contentLength);
|
||||||
// Specify data transfer options
|
// Specify data transfer options
|
||||||
const uploadOptions = {
|
const uploadOptions = {
|
||||||
blockSize: options === null || options === void 0 ? void 0 : options.uploadChunkSize,
|
blockSize: options === null || options === void 0 ? void 0 : options.uploadChunkSize,
|
||||||
concurrency: options === null || options === void 0 ? void 0 : options.uploadConcurrency,
|
concurrency: options === null || options === void 0 ? void 0 : options.uploadConcurrency,
|
||||||
maxSingleShotSize: 128 * 1024 * 1024 // 128 MiB initial transfer size
|
maxSingleShotSize: 128 * 1024 * 1024,
|
||||||
|
onProgress: uploadProgress.onProgress()
|
||||||
};
|
};
|
||||||
const blobClient = new storage_blob_1.BlobClient(signedUploadURL);
|
try {
|
||||||
const blockBlobClient = blobClient.getBlockBlobClient();
|
uploadProgress.startDisplayTimer();
|
||||||
core.debug(`BlobClient: ${blobClient.name}:${blobClient.accountName}:${blobClient.containerName}`);
|
core.debug(`BlobClient: ${blobClient.name}:${blobClient.accountName}:${blobClient.containerName}`);
|
||||||
const resp = yield blockBlobClient.uploadFile(archivePath, uploadOptions);
|
const response = yield blockBlobClient.uploadFile(archivePath, uploadOptions);
|
||||||
if (resp._response.status >= 400) {
|
// TODO: better management of non-retryable errors
|
||||||
throw new errors_1.InvalidResponseError(`Upload failed with status code ${resp._response.status}`);
|
if (response._response.status >= 400) {
|
||||||
|
throw new errors_1.InvalidResponseError(`Upload failed with status code ${response._response.status}`);
|
||||||
|
}
|
||||||
|
return response;
|
||||||
|
}
|
||||||
|
finally {
|
||||||
|
uploadProgress.stopDisplayTimer();
|
||||||
}
|
}
|
||||||
return resp;
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
exports.uploadCacheArchiveSDK = uploadCacheArchiveSDK;
|
exports.uploadCacheArchiveSDK = uploadCacheArchiveSDK;
|
||||||
|
|
115
dist/restore/index.js
vendored
115
dist/restore/index.js
vendored
|
@ -9734,26 +9734,123 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
Object.defineProperty(exports, "__esModule", ({ value: true }));
|
Object.defineProperty(exports, "__esModule", ({ value: true }));
|
||||||
exports.uploadCacheArchiveSDK = void 0;
|
exports.uploadCacheArchiveSDK = exports.UploadProgress = void 0;
|
||||||
const core = __importStar(__nccwpck_require__(4850));
|
const core = __importStar(__nccwpck_require__(4850));
|
||||||
const storage_blob_1 = __nccwpck_require__(3864);
|
const storage_blob_1 = __nccwpck_require__(3864);
|
||||||
const errors_1 = __nccwpck_require__(6333);
|
const errors_1 = __nccwpck_require__(6333);
|
||||||
|
/**
|
||||||
|
* Class for tracking the upload state and displaying stats.
|
||||||
|
*/
|
||||||
|
class UploadProgress {
|
||||||
|
constructor(contentLength) {
|
||||||
|
this.contentLength = contentLength;
|
||||||
|
this.sentBytes = 0;
|
||||||
|
this.displayedComplete = false;
|
||||||
|
this.startTime = Date.now();
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* Sets the number of bytes sent
|
||||||
|
*
|
||||||
|
* @param sentBytes the number of bytes sent
|
||||||
|
*/
|
||||||
|
setSentBytes(sentBytes) {
|
||||||
|
this.sentBytes = sentBytes;
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* Returns the total number of bytes transferred.
|
||||||
|
*/
|
||||||
|
getTransferredBytes() {
|
||||||
|
return this.sentBytes;
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* Returns true if the upload is complete.
|
||||||
|
*/
|
||||||
|
isDone() {
|
||||||
|
return this.getTransferredBytes() === this.contentLength;
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* Prints the current upload stats. Once the upload completes, this will print one
|
||||||
|
* last line and then stop.
|
||||||
|
*/
|
||||||
|
display() {
|
||||||
|
if (this.displayedComplete) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const transferredBytes = this.sentBytes;
|
||||||
|
const percentage = (100 * (transferredBytes / this.contentLength)).toFixed(1);
|
||||||
|
const elapsedTime = Date.now() - this.startTime;
|
||||||
|
const uploadSpeed = (transferredBytes /
|
||||||
|
(1024 * 1024) /
|
||||||
|
(elapsedTime / 1000)).toFixed(1);
|
||||||
|
core.info(`Sent ${transferredBytes} of ${this.contentLength} (${percentage}%), ${uploadSpeed} MBs/sec`);
|
||||||
|
if (this.isDone()) {
|
||||||
|
this.displayedComplete = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* Returns a function used to handle TransferProgressEvents.
|
||||||
|
*/
|
||||||
|
onProgress() {
|
||||||
|
return (progress) => {
|
||||||
|
this.setSentBytes(progress.loadedBytes);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* Starts the timer that displays the stats.
|
||||||
|
*
|
||||||
|
* @param delayInMs the delay between each write
|
||||||
|
*/
|
||||||
|
startDisplayTimer(delayInMs = 1000) {
|
||||||
|
const displayCallback = () => {
|
||||||
|
this.display();
|
||||||
|
if (!this.isDone()) {
|
||||||
|
this.timeoutHandle = setTimeout(displayCallback, delayInMs);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
this.timeoutHandle = setTimeout(displayCallback, delayInMs);
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* Stops the timer that displays the stats. As this typically indicates the upload
|
||||||
|
* is complete, this will display one last line, unless the last line has already
|
||||||
|
* been written.
|
||||||
|
*/
|
||||||
|
stopDisplayTimer() {
|
||||||
|
if (this.timeoutHandle) {
|
||||||
|
clearTimeout(this.timeoutHandle);
|
||||||
|
this.timeoutHandle = undefined;
|
||||||
|
}
|
||||||
|
this.display();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
exports.UploadProgress = UploadProgress;
|
||||||
function uploadCacheArchiveSDK(signedUploadURL, archivePath, options) {
|
function uploadCacheArchiveSDK(signedUploadURL, archivePath, options) {
|
||||||
|
var _a;
|
||||||
return __awaiter(this, void 0, void 0, function* () {
|
return __awaiter(this, void 0, void 0, function* () {
|
||||||
|
const blobClient = new storage_blob_1.BlobClient(signedUploadURL);
|
||||||
|
const blockBlobClient = blobClient.getBlockBlobClient();
|
||||||
|
const properties = yield blobClient.getProperties();
|
||||||
|
const contentLength = (_a = properties.contentLength) !== null && _a !== void 0 ? _a : -1;
|
||||||
|
const uploadProgress = new UploadProgress(contentLength);
|
||||||
// Specify data transfer options
|
// Specify data transfer options
|
||||||
const uploadOptions = {
|
const uploadOptions = {
|
||||||
blockSize: options === null || options === void 0 ? void 0 : options.uploadChunkSize,
|
blockSize: options === null || options === void 0 ? void 0 : options.uploadChunkSize,
|
||||||
concurrency: options === null || options === void 0 ? void 0 : options.uploadConcurrency,
|
concurrency: options === null || options === void 0 ? void 0 : options.uploadConcurrency,
|
||||||
maxSingleShotSize: 128 * 1024 * 1024 // 128 MiB initial transfer size
|
maxSingleShotSize: 128 * 1024 * 1024,
|
||||||
|
onProgress: uploadProgress.onProgress()
|
||||||
};
|
};
|
||||||
const blobClient = new storage_blob_1.BlobClient(signedUploadURL);
|
try {
|
||||||
const blockBlobClient = blobClient.getBlockBlobClient();
|
uploadProgress.startDisplayTimer();
|
||||||
core.debug(`BlobClient: ${blobClient.name}:${blobClient.accountName}:${blobClient.containerName}`);
|
core.debug(`BlobClient: ${blobClient.name}:${blobClient.accountName}:${blobClient.containerName}`);
|
||||||
const resp = yield blockBlobClient.uploadFile(archivePath, uploadOptions);
|
const response = yield blockBlobClient.uploadFile(archivePath, uploadOptions);
|
||||||
if (resp._response.status >= 400) {
|
// TODO: better management of non-retryable errors
|
||||||
throw new errors_1.InvalidResponseError(`Upload failed with status code ${resp._response.status}`);
|
if (response._response.status >= 400) {
|
||||||
|
throw new errors_1.InvalidResponseError(`Upload failed with status code ${response._response.status}`);
|
||||||
|
}
|
||||||
|
return response;
|
||||||
|
}
|
||||||
|
finally {
|
||||||
|
uploadProgress.stopDisplayTimer();
|
||||||
}
|
}
|
||||||
return resp;
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
exports.uploadCacheArchiveSDK = uploadCacheArchiveSDK;
|
exports.uploadCacheArchiveSDK = uploadCacheArchiveSDK;
|
||||||
|
|
115
dist/save-only/index.js
vendored
115
dist/save-only/index.js
vendored
|
@ -9734,26 +9734,123 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
Object.defineProperty(exports, "__esModule", ({ value: true }));
|
Object.defineProperty(exports, "__esModule", ({ value: true }));
|
||||||
exports.uploadCacheArchiveSDK = void 0;
|
exports.uploadCacheArchiveSDK = exports.UploadProgress = void 0;
|
||||||
const core = __importStar(__nccwpck_require__(4850));
|
const core = __importStar(__nccwpck_require__(4850));
|
||||||
const storage_blob_1 = __nccwpck_require__(3864);
|
const storage_blob_1 = __nccwpck_require__(3864);
|
||||||
const errors_1 = __nccwpck_require__(6333);
|
const errors_1 = __nccwpck_require__(6333);
|
||||||
|
/**
|
||||||
|
* Class for tracking the upload state and displaying stats.
|
||||||
|
*/
|
||||||
|
class UploadProgress {
|
||||||
|
constructor(contentLength) {
|
||||||
|
this.contentLength = contentLength;
|
||||||
|
this.sentBytes = 0;
|
||||||
|
this.displayedComplete = false;
|
||||||
|
this.startTime = Date.now();
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* Sets the number of bytes sent
|
||||||
|
*
|
||||||
|
* @param sentBytes the number of bytes sent
|
||||||
|
*/
|
||||||
|
setSentBytes(sentBytes) {
|
||||||
|
this.sentBytes = sentBytes;
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* Returns the total number of bytes transferred.
|
||||||
|
*/
|
||||||
|
getTransferredBytes() {
|
||||||
|
return this.sentBytes;
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* Returns true if the upload is complete.
|
||||||
|
*/
|
||||||
|
isDone() {
|
||||||
|
return this.getTransferredBytes() === this.contentLength;
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* Prints the current upload stats. Once the upload completes, this will print one
|
||||||
|
* last line and then stop.
|
||||||
|
*/
|
||||||
|
display() {
|
||||||
|
if (this.displayedComplete) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const transferredBytes = this.sentBytes;
|
||||||
|
const percentage = (100 * (transferredBytes / this.contentLength)).toFixed(1);
|
||||||
|
const elapsedTime = Date.now() - this.startTime;
|
||||||
|
const uploadSpeed = (transferredBytes /
|
||||||
|
(1024 * 1024) /
|
||||||
|
(elapsedTime / 1000)).toFixed(1);
|
||||||
|
core.info(`Sent ${transferredBytes} of ${this.contentLength} (${percentage}%), ${uploadSpeed} MBs/sec`);
|
||||||
|
if (this.isDone()) {
|
||||||
|
this.displayedComplete = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* Returns a function used to handle TransferProgressEvents.
|
||||||
|
*/
|
||||||
|
onProgress() {
|
||||||
|
return (progress) => {
|
||||||
|
this.setSentBytes(progress.loadedBytes);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* Starts the timer that displays the stats.
|
||||||
|
*
|
||||||
|
* @param delayInMs the delay between each write
|
||||||
|
*/
|
||||||
|
startDisplayTimer(delayInMs = 1000) {
|
||||||
|
const displayCallback = () => {
|
||||||
|
this.display();
|
||||||
|
if (!this.isDone()) {
|
||||||
|
this.timeoutHandle = setTimeout(displayCallback, delayInMs);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
this.timeoutHandle = setTimeout(displayCallback, delayInMs);
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* Stops the timer that displays the stats. As this typically indicates the upload
|
||||||
|
* is complete, this will display one last line, unless the last line has already
|
||||||
|
* been written.
|
||||||
|
*/
|
||||||
|
stopDisplayTimer() {
|
||||||
|
if (this.timeoutHandle) {
|
||||||
|
clearTimeout(this.timeoutHandle);
|
||||||
|
this.timeoutHandle = undefined;
|
||||||
|
}
|
||||||
|
this.display();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
exports.UploadProgress = UploadProgress;
|
||||||
function uploadCacheArchiveSDK(signedUploadURL, archivePath, options) {
|
function uploadCacheArchiveSDK(signedUploadURL, archivePath, options) {
|
||||||
|
var _a;
|
||||||
return __awaiter(this, void 0, void 0, function* () {
|
return __awaiter(this, void 0, void 0, function* () {
|
||||||
|
const blobClient = new storage_blob_1.BlobClient(signedUploadURL);
|
||||||
|
const blockBlobClient = blobClient.getBlockBlobClient();
|
||||||
|
const properties = yield blobClient.getProperties();
|
||||||
|
const contentLength = (_a = properties.contentLength) !== null && _a !== void 0 ? _a : -1;
|
||||||
|
const uploadProgress = new UploadProgress(contentLength);
|
||||||
// Specify data transfer options
|
// Specify data transfer options
|
||||||
const uploadOptions = {
|
const uploadOptions = {
|
||||||
blockSize: options === null || options === void 0 ? void 0 : options.uploadChunkSize,
|
blockSize: options === null || options === void 0 ? void 0 : options.uploadChunkSize,
|
||||||
concurrency: options === null || options === void 0 ? void 0 : options.uploadConcurrency,
|
concurrency: options === null || options === void 0 ? void 0 : options.uploadConcurrency,
|
||||||
maxSingleShotSize: 128 * 1024 * 1024 // 128 MiB initial transfer size
|
maxSingleShotSize: 128 * 1024 * 1024,
|
||||||
|
onProgress: uploadProgress.onProgress()
|
||||||
};
|
};
|
||||||
const blobClient = new storage_blob_1.BlobClient(signedUploadURL);
|
try {
|
||||||
const blockBlobClient = blobClient.getBlockBlobClient();
|
uploadProgress.startDisplayTimer();
|
||||||
core.debug(`BlobClient: ${blobClient.name}:${blobClient.accountName}:${blobClient.containerName}`);
|
core.debug(`BlobClient: ${blobClient.name}:${blobClient.accountName}:${blobClient.containerName}`);
|
||||||
const resp = yield blockBlobClient.uploadFile(archivePath, uploadOptions);
|
const response = yield blockBlobClient.uploadFile(archivePath, uploadOptions);
|
||||||
if (resp._response.status >= 400) {
|
// TODO: better management of non-retryable errors
|
||||||
throw new errors_1.InvalidResponseError(`Upload failed with status code ${resp._response.status}`);
|
if (response._response.status >= 400) {
|
||||||
|
throw new errors_1.InvalidResponseError(`Upload failed with status code ${response._response.status}`);
|
||||||
|
}
|
||||||
|
return response;
|
||||||
|
}
|
||||||
|
finally {
|
||||||
|
uploadProgress.stopDisplayTimer();
|
||||||
}
|
}
|
||||||
return resp;
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
exports.uploadCacheArchiveSDK = uploadCacheArchiveSDK;
|
exports.uploadCacheArchiveSDK = uploadCacheArchiveSDK;
|
||||||
|
|
115
dist/save/index.js
vendored
115
dist/save/index.js
vendored
|
@ -9734,26 +9734,123 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
Object.defineProperty(exports, "__esModule", ({ value: true }));
|
Object.defineProperty(exports, "__esModule", ({ value: true }));
|
||||||
exports.uploadCacheArchiveSDK = void 0;
|
exports.uploadCacheArchiveSDK = exports.UploadProgress = void 0;
|
||||||
const core = __importStar(__nccwpck_require__(4850));
|
const core = __importStar(__nccwpck_require__(4850));
|
||||||
const storage_blob_1 = __nccwpck_require__(3864);
|
const storage_blob_1 = __nccwpck_require__(3864);
|
||||||
const errors_1 = __nccwpck_require__(6333);
|
const errors_1 = __nccwpck_require__(6333);
|
||||||
|
/**
|
||||||
|
* Class for tracking the upload state and displaying stats.
|
||||||
|
*/
|
||||||
|
class UploadProgress {
|
||||||
|
constructor(contentLength) {
|
||||||
|
this.contentLength = contentLength;
|
||||||
|
this.sentBytes = 0;
|
||||||
|
this.displayedComplete = false;
|
||||||
|
this.startTime = Date.now();
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* Sets the number of bytes sent
|
||||||
|
*
|
||||||
|
* @param sentBytes the number of bytes sent
|
||||||
|
*/
|
||||||
|
setSentBytes(sentBytes) {
|
||||||
|
this.sentBytes = sentBytes;
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* Returns the total number of bytes transferred.
|
||||||
|
*/
|
||||||
|
getTransferredBytes() {
|
||||||
|
return this.sentBytes;
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* Returns true if the upload is complete.
|
||||||
|
*/
|
||||||
|
isDone() {
|
||||||
|
return this.getTransferredBytes() === this.contentLength;
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* Prints the current upload stats. Once the upload completes, this will print one
|
||||||
|
* last line and then stop.
|
||||||
|
*/
|
||||||
|
display() {
|
||||||
|
if (this.displayedComplete) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const transferredBytes = this.sentBytes;
|
||||||
|
const percentage = (100 * (transferredBytes / this.contentLength)).toFixed(1);
|
||||||
|
const elapsedTime = Date.now() - this.startTime;
|
||||||
|
const uploadSpeed = (transferredBytes /
|
||||||
|
(1024 * 1024) /
|
||||||
|
(elapsedTime / 1000)).toFixed(1);
|
||||||
|
core.info(`Sent ${transferredBytes} of ${this.contentLength} (${percentage}%), ${uploadSpeed} MBs/sec`);
|
||||||
|
if (this.isDone()) {
|
||||||
|
this.displayedComplete = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* Returns a function used to handle TransferProgressEvents.
|
||||||
|
*/
|
||||||
|
onProgress() {
|
||||||
|
return (progress) => {
|
||||||
|
this.setSentBytes(progress.loadedBytes);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* Starts the timer that displays the stats.
|
||||||
|
*
|
||||||
|
* @param delayInMs the delay between each write
|
||||||
|
*/
|
||||||
|
startDisplayTimer(delayInMs = 1000) {
|
||||||
|
const displayCallback = () => {
|
||||||
|
this.display();
|
||||||
|
if (!this.isDone()) {
|
||||||
|
this.timeoutHandle = setTimeout(displayCallback, delayInMs);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
this.timeoutHandle = setTimeout(displayCallback, delayInMs);
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* Stops the timer that displays the stats. As this typically indicates the upload
|
||||||
|
* is complete, this will display one last line, unless the last line has already
|
||||||
|
* been written.
|
||||||
|
*/
|
||||||
|
stopDisplayTimer() {
|
||||||
|
if (this.timeoutHandle) {
|
||||||
|
clearTimeout(this.timeoutHandle);
|
||||||
|
this.timeoutHandle = undefined;
|
||||||
|
}
|
||||||
|
this.display();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
exports.UploadProgress = UploadProgress;
|
||||||
function uploadCacheArchiveSDK(signedUploadURL, archivePath, options) {
|
function uploadCacheArchiveSDK(signedUploadURL, archivePath, options) {
|
||||||
|
var _a;
|
||||||
return __awaiter(this, void 0, void 0, function* () {
|
return __awaiter(this, void 0, void 0, function* () {
|
||||||
|
const blobClient = new storage_blob_1.BlobClient(signedUploadURL);
|
||||||
|
const blockBlobClient = blobClient.getBlockBlobClient();
|
||||||
|
const properties = yield blobClient.getProperties();
|
||||||
|
const contentLength = (_a = properties.contentLength) !== null && _a !== void 0 ? _a : -1;
|
||||||
|
const uploadProgress = new UploadProgress(contentLength);
|
||||||
// Specify data transfer options
|
// Specify data transfer options
|
||||||
const uploadOptions = {
|
const uploadOptions = {
|
||||||
blockSize: options === null || options === void 0 ? void 0 : options.uploadChunkSize,
|
blockSize: options === null || options === void 0 ? void 0 : options.uploadChunkSize,
|
||||||
concurrency: options === null || options === void 0 ? void 0 : options.uploadConcurrency,
|
concurrency: options === null || options === void 0 ? void 0 : options.uploadConcurrency,
|
||||||
maxSingleShotSize: 128 * 1024 * 1024 // 128 MiB initial transfer size
|
maxSingleShotSize: 128 * 1024 * 1024,
|
||||||
|
onProgress: uploadProgress.onProgress()
|
||||||
};
|
};
|
||||||
const blobClient = new storage_blob_1.BlobClient(signedUploadURL);
|
try {
|
||||||
const blockBlobClient = blobClient.getBlockBlobClient();
|
uploadProgress.startDisplayTimer();
|
||||||
core.debug(`BlobClient: ${blobClient.name}:${blobClient.accountName}:${blobClient.containerName}`);
|
core.debug(`BlobClient: ${blobClient.name}:${blobClient.accountName}:${blobClient.containerName}`);
|
||||||
const resp = yield blockBlobClient.uploadFile(archivePath, uploadOptions);
|
const response = yield blockBlobClient.uploadFile(archivePath, uploadOptions);
|
||||||
if (resp._response.status >= 400) {
|
// TODO: better management of non-retryable errors
|
||||||
throw new errors_1.InvalidResponseError(`Upload failed with status code ${resp._response.status}`);
|
if (response._response.status >= 400) {
|
||||||
|
throw new errors_1.InvalidResponseError(`Upload failed with status code ${response._response.status}`);
|
||||||
|
}
|
||||||
|
return response;
|
||||||
|
}
|
||||||
|
finally {
|
||||||
|
uploadProgress.stopDisplayTimer();
|
||||||
}
|
}
|
||||||
return resp;
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
exports.uploadCacheArchiveSDK = uploadCacheArchiveSDK;
|
exports.uploadCacheArchiveSDK = uploadCacheArchiveSDK;
|
||||||
|
|
Loading…
Reference in a new issue