无服务器Cron Job两次射击

时间:2018-05-17 16:22:00

标签: javascript cron webhooks serverless-framework serverless

我不知道为什么但是我的webhook在我的cron工作中被解雇了两次。因此,这个cron作业假设每15分钟运行一次,但它会发射两次。我将发布日志,处理程序和yml文件以帮助解决。

基本上我的cron作业会向salsify api发出一些请求,要求在mongodb中存储一个url。一旦该文件完成并在下次cron作业运行时构建,它应该触发netlify的webhook。然后这个过程重新开始。

在我的netlify中,我注意到构建正在运行两次并且已将引脚指向无服务器的cron作业。

编辑:我应该添加的内容是,即使我的cron作业运行了两次,如果MongoDB中有文件,仍然只能在技术上调用webhook一次。然而它仍然以某种方式调用它两次导致我的netlify构建失败,因为它需要该文件才能构建。

serverless.yml的功能部分:

functions:
  salsifyCron:
    handler: src/handler.salsifyCron
    events:
      - schedule: 
          rate: cron(*/15 * * * ? *)
          enabled: true

日志:

2018-05-17 10:00:41.121 (-05:00)    10d87735-59e3-11e8-be56-69e06899fa1f    Trigger Webhook
2018-05-17 10:01:45.941 (-05:00)    10d87735-59e3-11e8-be56-69e06899fa1f    Trigger Webhook

处理程序:

require('envdotjs').load();
import fetch from 'isomorphic-fetch';
import axios from 'axios';
import middy from 'middy';
import { jsonBodyParser, httpErrorHandler, cors } from 'middy/middlewares';

import { connectToDatabase } from '../utils/db';
import Sheet from '../models/Sheet';
import config from '../utils/config';

module.exports.salsifyCron = middy(async (event, context, callback) => {
  context.callbackWaitsForEmptyEventLoop = false;
  let sheetId;
  const options = {
    url: `https://app.salsify.com/api/orgs/${
      process.env.SALSIFY_ORG_ID
    }/export_runs`,
    headers: {
      Authorization: `Bearer ${process.env.SALSIFY_API_KEY}`,
      'Content-Type': 'application/json'
    }
  };
  await connectToDatabase();

  const storedData = await Sheet.find({});
  if (
    storedData.length > 0 &&
    storedData[0] &&
    storedData[0].status === 'completed' &&
    storedData[0].url !== null
  ) {
    console.log('Trigger WebHook');
    axios.post('https://api.netlify.com/build_hooks/*****************');
    process.exit(0);
    return;
  }
  if (storedData[0]) {
    sheetId = storedData[0].sheetId;
  }
  if (storedData.length === 0) {
    const res = await fetch(options.url, {
      method: 'POST',
      headers: options.headers,
      body: JSON.stringify(config)
    }).then(res => res.json());
    if (res.id && res.status) {
      await Sheet.create({
        sheetId: res.id,
        url: null,
        status: res.status
      });
      sheetId = res.id;
    } else {
      console.log(res);
      process.exit(1);
    }
  }

  const resWithId = await fetch(`${options.url}/${sheetId}`, {
    method: 'GET',
    headers: options.headers
  }).then(res => res.json());

  if (resWithId.status === 'running') {
    console.log('running cron job');
    console.log(resWithId.estimated_time_remaining);
  }
  if (resWithId.status === 'completed') {
    console.log('completed cron job');
    await Sheet.findByIdAndUpdate(
      storedData[0],
      { status: resWithId.status, url: resWithId.url },
      { new: true }
    );
  }
})
  .use(cors())
  .use(jsonBodyParser())
  .use(httpErrorHandler());

1 个答案:

答案 0 :(得分:0)

Lambda超时。对于您来说,这可能不是问题,但这是导致此结果的常见问题。

您的lambda不会同时执行,但会有些延迟。这是一个线索,它不仅仅是获得重复执行。

我想您的lambda首先会因错误而终止(例如超时-默认的lambda超时很小),并且lambda在失败后会重新运行。

我在超时方面遇到了这个问题,如果您没有注意到lambda超时,那将非常令人困惑。