同步机制在本地计算机上运行良好,但会删除 Heroku 上的所有视频



我有一个在启动时运行的机制,它将删除任何孤立的数据。 它遍历 mongodb 视频集合并检查以确保它可以将数据库中的记录与磁盘上的相应文件匹配。 如果找到孤立记录,则会将其删除。 然后,它会翻转并遍历目录,以确保找到的所有文件在数据库中都有匹配的记录。

当我在本地机器上运行它时,它可以完美运行。 但是,每次我部署到heroku并且我的dyno重新启动时,整个"视频"集合都会被删除。

在 Heroku 中创建视频后,我做了一些基本的测试,它在数据库中并可供下载。 我的猜测是Heroku不喜欢fs.access的东西。

任何帮助或见解将不胜感激。

walkVideos: function() {
    // First let's lookup videos and make sure there is a directory for them.  If not, delete it from the db.
    Video.find().exec(function(err, result) {
      if (err) {
        console.log(err);
        return null;
      }
      if (result.length === 0) {
        console.log('No videos found in db');
        return null;
      }
      _.forEach(result, function(video)  {
      // make sure I can access the style file.
        fs.access(scormifyConfig.videoBasePath + video._id + '/dist/' + video._id + '_' + video.filename + '.zip', function(err) {
          if (err && err.code === 'ENOENT') {
            //Can't find the style file, i need to delete it
            Video.remove({_id: video._id}, function(err, result) {
              if (err) {
                console.log('Error removing video from the db');
              }
                if (result) {
                  console.log('Out of sync video pruned from the db');
                }
              });
            }
          });
        //  console.log('Matched video from DB to disk.   No action.');
      });
    });
    // let's walk the other way and make sure all videos found on disk have a match in the db at the folder level.
    fsp.traverseTreeSync(scormifyConfig.videoBasePath,  // walk through the content directory
       function(file) {
      },
    function(dir) {
      let _id = dir.replace('content\videos\', '');  // on dir, trim to just the id.  this can be matched to the DB _id field.
      Video.find({_id: _id}, function(err, result) {
        if (err) {
          console.log(err);
        }
        if (result.length === 0) {  // didn't find the video.
          console.log('video found on disk, but not in the db.   Removing from disk.');
          fs.removeSync(scormifyConfig.videoBasePath + _id, function(err) {
            if (err) {
              console.log(err);
            }
          });
        }
        //console.log('Video matched from disk to DB.   No action');
      });
    },
      function() {
    console.log('done checking videos.');
  });
  }

编辑

我做了一些额外的调试。 我仍然不确定为什么会发生这种情况,看起来它应该有效。

Jul 14 14:40:37 scormify app[web]  { [Error: ENOENT: no such file or directory, access './content/videos/5787f91a9332950300d85ad4/dist/5787f91a9332950300d85ad4_da-dka-dlk-lsk.zip']
Jul 14 14:40:37 scormify app[web]   errno: -2,
Jul 14 14:40:38 scormify app[web]  Out of sync video pruned from the db

Dynos拥有Heroku所谓的"短暂文件系统"。换句话说,它不会跨部署持久化。见 https://devcenter.heroku.com/articles/dynos#ephemeral-filesystem

因此,您所看到的是正常行为,尽管现在对您来说非常不方便。其背后的原因是,当您开始增加应用程序正在运行的测功机数量时,测功机本地的文件系统不会扩展。它还打破了测功机是一次性的原则。

推荐的替代方法是将视频等文件存储在为此目的而设计的另一种服务上,例如 Amazon S3。

最新更新