Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/419.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 谷歌云功能:同一个存储触发事件被反复触发_Javascript_Firebase Storage_Google Cloud Functions - Fatal编程技术网

Javascript 谷歌云功能:同一个存储触发事件被反复触发

Javascript 谷歌云功能:同一个存储触发事件被反复触发,javascript,firebase-storage,google-cloud-functions,Javascript,Firebase Storage,Google Cloud Functions,问题 云函数在同一事件上被反复触发。 看起来,当函数超时时,函数将重试 一遍又一遍?尽管gui中未启用“失败时重试”选项 问题 你能保证一个函数在同一事件上只触发一次吗? 它可能与问题跟踪程序中的这些事件有关: 更多细节 我有一个云函数,它在上传云存储桶中的文件时做出反应。该函数用于将音频文件转换为flac文件 使用一个小文件,所有工作正常。有了更大的文件,事情变得非常奇怪。云功能被多次触发,对同一存储事件反复作出反应。我很困惑这是怎么发生的,因为我认为如果函数对事件做出反应,它将不再被

问题

云函数在同一事件上被反复触发。 看起来,当函数超时时,函数将重试 一遍又一遍?尽管gui中未启用“失败时重试”选项

问题

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

更多细节

我有一个云函数,它在上传云存储桶中的文件时做出反应。该函数用于将音频文件转换为flac文件

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

问题是,当函数被触发时,函数需要一段时间来执行其转换。似乎在那个时候,新的功能被创建来对事件做出反应

那么,是否可以确保云功能只触发一次

这是stackdriver中的日志文件

小文件上传(一切正常)

更大的文件(多次调用)

这表明函数在一分钟内被触发两次,而第一次调用尚未完成

搜索该事件时,我看到它一次又一次地出现:

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

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);
          });
      });
  });

是否将新文件保存回同一目录?如果是,则该事件将启动同一个云函数。不,它将以不同的名称保存在不同的bucket中。(只是看一下事件,它总是导致函数触发的完全相同的事件)它保存到audiobucket
const audiobucket=gcs.bucket(“ucl flac audio”);return audioBucket.upload(targetTempFilePath,{destination:targetStorageFilePath})
@Koen我刚刚为同样的问题创建了一个问题。在你报告这件事一年后,它仍然是最新的,而且GCF已经成为GA-(这仍然影响着你吗?