Лазурные капли, как ждать создания блоба, прежде чем продолжить? - PullRequest
0 голосов
/ 06 февраля 2019

Я использую NodeJS и Azure Storage SDK, у меня проблема с тем, что файлы, которые я загружаю в мои большие двоичные объекты, создаются как файлы размером 0 КБ, если я не добавляю промежуточную функцию для ее задержки, чтобы создать большой двоичный объект дозагрузка происходит.Я получаю те же результаты при загрузке в виде потока или локального файла из хранилища Azure.

У меня есть следующая функция:

async function uploadToBlob(localFilePath) {


        //ACTIVATE CREDENTIALS AND CONTAINER
    const credentials = new SharedKeyCredential(STORAGE_ACCOUNT_NAME, ACCOUNT_ACCESS_KEY);
    const pipeline = StorageURL.newPipeline(credentials);
    const serviceURL = new ServiceURL(`https://${STORAGE_ACCOUNT_NAME}.blob.core.windows.net`, pipeline);
    const containerURL = ContainerURL.fromServiceURL(serviceURL, containerName);  
    const aborter = Aborter.timeout(30 * ONE_MINUTE);

    //UPLOAD IMAGE
    var blobName = localFilePath.substring(localFilePath.lastIndexOf('/') + 1 );
    var fullBlobName = category + "/" + subcategory + "/" + blobName;
    var blobURL = await BlockBlobURL.fromContainerURL(containerURL, fullBlobName);

    await uploadImage(aborter, containerURL, localFilePath, blobURL)


}

, где я получаю переменную blobURL с помощьювыполняет ожидание для BlockBlobURL.fromContainerURL и, как вы можете видеть, имеет ожидание, а также есть ожидание при вызове uploadImage.

Затем здесь вызывается функция, которая вызывает uploadFileToBlockBlob из лазуриsdk:

//UPLOAD IMAGE NO-STREAM
async function uploadImage(aborter, containerURL, filePath, blobURL, blobName) {
    try {
        filePath = path.resolve(filePath);

         //THIS LINE MAKES IT WORK
        await showBlobNames(aborter, containerURL);

        addToDB(blobName, blobURL.url);


        console.log("Calling uploadFileToBlockBlob with filePath: " + filePath + 
                    " and blobURL: "+ blobURL.url)
        return await uploadFileToBlockBlob(aborter, filePath, blobURL);
    }
    catch(err) {
        console.log(err)
    }
}

В этой последней функции я добавил

await showBlobNames(aborter, containerURL);

, и это заставило ее работать.

Похоже, что ранее файл загружался доБыл создан BLOB-объект, и изображения загружались с правильным именем и в BLOB-файл, но в виде файлов размером 0 КБ, и добавление этой функции задерживает его, чтобы можно было создать BLOB-объект.

Я не понимаю, почему предыдущийожидание не заставляет загрузку ждать, пока большой объект не будет создан.Я также попытался поместить вызов загрузки в функцию обратного вызова, но он был бы выполнен при создании большого двоичного объекта, но, кажется, не поддерживается (не вызывает функцию обратного вызова)

У меня это работает, добавляя вызов showBlobNamesно я чувствую, что мой код не должен полагаться на это, и я хочу узнать, почему ожидание не работает.

Спасибо

1 Ответ

0 голосов
/ 07 февраля 2019

Вот как я устанавливаю соединение и выполняю операцию CRUD

    await containerURL.create(aborter);
    console.log(`Container: "${containerName}" is created`);

    await blockBlobURL.upload(aborter, content, content.length);
    console.log(`Blob "${blobName}" is uploaded`);
    
    await uploadLocalFile(aborter, containerURL, localFilePath);
    console.log(`Local file "${localFilePath}" is uploaded`);

    await uploadStream(aborter, containerURL, localFilePath);
    console.log(`Local file "${localFilePath}" is uploaded as a stream`);

    console.log(`Blobs in "${containerName}" container:`);
    await showBlobNames(aborter, containerURL);

и вот реализация функции для того же.

async function showContainerNames(aborter, serviceURL) {

    let response;
    let marker;

    do {
        response = await serviceURL.listContainersSegment(aborter, marker);
        marker = response.marker;
        for(let container of response.containerItems) {
            console.log(` - ${ container.name }`);
        }
    } while (marker);
}

async function uploadLocalFile(aborter, containerURL, filePath) {

    filePath = path.resolve(filePath);

    const fileName = path.basename(filePath);
    const blockBlobURL = BlockBlobURL.fromContainerURL(containerURL, fileName);

    return await uploadFileToBlockBlob(aborter, filePath, blockBlobURL);
}

async function uploadStream(aborter, containerURL, filePath) {

    filePath = path.resolve(filePath);

    const fileName = path.basename(filePath).replace('.md', '-stream.md');
    const blockBlobURL = BlockBlobURL.fromContainerURL(containerURL, fileName);

    const stream = fs.createReadStream(filePath, {
      highWaterMark: FOUR_MEGABYTES,
    });

    const uploadOptions = {
        bufferSize: FOUR_MEGABYTES,
        maxBuffers: 5,
    };

    return await uploadStreamToBlockBlob(
                    aborter, 
                    stream, 
                    blockBlobURL, 
                    uploadOptions.bufferSize, 
                    uploadOptions.maxBuffers);
}

async function showBlobNames(aborter, containerURL) {

    let response;
    let marker;

    do {
        response = await containerURL.listBlobFlatSegment(aborter);
        marker = response.marker;
        for(let blob of response.segment.blobItems) {
            console.log(` - ${ blob.name }`);
        }
    } while (marker);
}

Я использовал javascript SDK 10 для лазурного хранения в моем примере, и он отлично работал для меня.Для исходного репо, пожалуйста, обращайтесь https://github.com/Azure-Samples/azure-storage-js-v10-quickstart

Надеюсь, это поможет.

MV

...