Google云功能:反复触发相同的存储触发事件

时间:2017-10-13 14:51:30

标签: javascript firebase-storage google-cloud-functions

问题

在同一事件上反复触发云功能。 看起来当函数超时时,重试该函数 一遍又一遍?虽然选择"重试失败" gui中没有启用?

问题

你能保证一个函数只在同一个事件上被触发一次吗? 它可能与问题跟踪器中的这些事件有关?:

更多细节

我有一个云功能,可以在云存储桶中上传文件。该函数将音频文件转换为flac文件。

使用小文件全部按预期工作。有了更大的文件,事情变得非常奇怪。多次触发云功能反复对同一存储事件做出反应。我很困惑如何发生这种情况,因为我认为如果一个函数对事件做出反应,它将不再被触发。

该交易是当触发该功能时,该功能需要一段时间才能执行其转换。似乎在那个时候,创建了新的功能来对事件作出反应。

那么可以确保只触发一次云功能吗?

这是stackdriver的日志文件

小文件上传(全部好)

Small file upload

更大的文件(多次调用)

Larger file

这表明在第一次调用完成后,该函数在一分钟内被触发两次?

搜索该事件,我看到它一次又一次地回来:

Event coming back over and over again.

这是我对触发器作出反应的代码:

const functions = require("firebase-functions");
const path = require("path");
const fs = require("fs");
const os = require("os");

const gcs = require("@google-cloud/storage")();
const ffmpeg = require("fluent-ffmpeg");
const ffmpeg_static = require("ffmpeg-static");

const speech = require("@google-cloud/speech")();
const Promise = require("bluebird");

//Helper function for changing the ffmpeg command into a promise so that the function will properly wait for it to finish.
//Source: https://github.com/fluent-ffmpeg/node-fluent-ffmpeg/issues/710

function promisifyCommand(command) {
  return new Promise(cb => {
    command
      .on("end", () => {
        cb(null);
      })
      .on("error", error => {
        cb(error);
      })
      .run();
  });
}

exports.extractAudio = functions.storage
  .bucket("ulc-transcribe.appspot.com")
  .object()
  .onChange(event => {
    const object = event.data;
    const filePath = object.name;
    const fileName = path.basename(filePath);
    const fileBucket = object.bucket;
    const bucket = gcs.bucket(fileBucket);
    const audioBucket = gcs.bucket("ucl-flac-audio");
    const metageneration = object.metageneration; // Number of times metadata has been generated. New objects have a value of 1.

    console.log("event: ", event);
    console.log("path: ", filePath + " name: " + fileName);

    // Exit if the file is not an upload
    if (!filePath.startsWith("ucl-uploads")) {
      console.log("Only uploads need to be converted");
      return true;
    }

    // Exit if the audio is already converted.
    if (fileName.endsWith("_output.flac")) {
      console.log("Already a converted audio.");
      return true;
    }

    // Exit if this is a move or deletion event.
    if (object.resourceState === "not_exists") {
      console.log("This is a deletion event.");
      return true;
    }

    //   // Exit if file exists but is not new and is only being triggered
    // // because of a metadata change.
    // if (resourceState === 'exists' && metageneration > 1) {
    //   console.log('This is a metadata change event.');
    //   return;
    // }

    const tempFilePath = path.join(os.tmpdir(), fileName);
    const targetTempFileName =
      fileName.replace(/\.[^/.]+$/, "") + "_output.flac";
    const targetTempFilePath = path.join(os.tmpdir(), targetTempFileName);
    const targetStorageFilePath = path.join(targetTempFileName);

    console.log("downloading audio file...");
    console.log("Filename: " + fileName);
    console.log("tempFilePath", tempFilePath);

    // Step 1 - Start download
    return bucket
      .file(filePath)
      .download({
        destination: tempFilePath
      })
      .then(() => {
        console.log("Audio downloaded locally to", tempFilePath);
        //Step 2 - Convert file
        console.log("Start conversion:");

        command = ffmpeg(tempFilePath)
          .setFfmpegPath(ffmpeg_static.path)
          .audioChannels(1)
          .audioFrequency(16000)
          .format("flac")
          .output(targetTempFilePath);

        command = promisifyCommand(command);
        return command
          .then(() => {
            console.log("Output audio created at", targetTempFilePath);
            console.log("Upload file");
            return audioBucket
              .upload(targetTempFilePath, {
                destination: targetStorageFilePath
              })
              .then(() => {
                console.log("Output audio uploaded to", targetStorageFilePath);
                // return bucket.upload("/tmp/output.flac", {
                //   destination: "ucl-flac-audio/test.flac"
                // });

                //Step 4 - Cleanup fs
                console.log("cleanup filesystem");
                fs.unlinkSync(tempFilePath);
                fs.unlinkSync(targetTempFilePath);
              });
          })
          .catch(err => {
            console.log("Error ", +err);
          });
      });
  });

0 个答案:

没有答案