Действия Apache OpenWhisk вызываются путем отправки HTTP-запросов POST в API платформы. Запросы на вызов имеют два разных режима: блокирующий и неблокирующий.

Блокировка вызовов означает, что платформа не будет отправлять HTTP-ответ, пока действие не завершится. Это позволяет включить результат действия в ответ. Блокирующие вызовы используются, когда вы хотите вызвать действие и дождаться результата.

$ wsk action invoke my_action --blocking
ok: invoked /_/my_action with id db70ef682fae4f8fb0ef682fae2f8fd5
{
    "activationId": "db70ef682fae4f8fb0ef682fae2f8fd5",
    ...
    "response": {
        "result": { ... },
        "status": "success",
        "success": true
    },
    ...
}

Неблокирующие вызовы возвращаются, как только платформа обрабатывает запрос на вызов. Это происходит до завершения действия. Ответы HTTP от неблокирующих вызовов включают только идентификаторы активации, поскольку результат действия недоступен.

$ wsk action invoke my_action
ok: invoked /_/my_action with id d2728aaa75394411b28aaa7539341195

HTTP-ответы от блокирующего вызова будут ждать только ограниченное время перед возвратом. По умолчанию это значение равно 65 секундам в файле конфигурации платформы. Если вызов действия не завершился до истечения этого тайм-аута, возвращается ответ состояния HTTP 5xx.

Хммм… 🤔

"Итак, как вы можете вызвать действие и дождаться результата, если действия занимают больше времени, чем это ограничение?"

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

решение

Когда опрос для активации является результатом неблокирующих вызовов, вы должны установить ограничение на максимально допустимое время опроса. Это связано с тем, что ошибки HTTP 404 могут возвращаться из-за других сценариев (например, из-за недопустимых идентификаторов активации). Применение ограничения по времени гарантирует, что в случае проблем в коде приложения или платформе цикл опроса в конечном итоге остановится!

Хорошим подходом является установка максимального времени опроса на время ожидания действия (плюс небольшое смещение).

Действие не может выполняться дольше его тайм-аута. Если запись активации недоступна по истечении этого времени (плюс небольшое смещение для обработки внутренних задержек платформы), что-то пошло не так. Продолжение опроса после этого момента рискует превратить операцию опроса в бесконечный цикл…

пример кода

В этом примере представлена ​​реализация этого подхода для Node.js с использованием JavaScript Client SDK.

"use strict";

const openwhisk = require('openwhisk')

const options = { apihost: <API_HOST>, api_key: <API_KEY> }
const ow = openwhisk(options)

// action duration limit (+ small offset)
const timeout_ms = 85000
// delay between polling requests
const polling_delay = 1000
// action to invoke
const action = 'delay'

const now = () => (new Date().getTime())
const max_polling_time = now() + timeout_ms

const delay = async ms => new Promise(resolve => setTimeout(resolve, ms))

const activation = await ow.actions.invoke({name: action})
console.log(`new activation id: ${activation.activationId}`)

let result = null

do {
  try {
    result = await ow.activations.get({ name: activation.activationId })
    console.log(`activation result (${activation.activationId}) now available!`)
  } catch (err) {
    if (err.statusCode !== 404) {
      throw err
    }
    console.log(`activation result (${activation.activationId}) not available yet`)
  }

  await delay(polling_delay)
} while (!result && now() < max_polling_time)

console.log(`activation result (${activation.activationId})`, result)

проверить это

Вот исходный код действия, которое не вернется, пока не пройдет 70 секунд. Блокировка вызовов, запускающих это действие, приведет к тайм-ауту HTTP перед возвратом ответа.

const delay = async ms => new Promise(resolve => setTimeout(resolve, ms))

function main() {
  return delay(70*1000)
}

Используя приведенный выше сценарий, результат действия будет получен из неблокирующего вызова.

  • Создайте действие из исходного файла в приведенном выше примере.
wsk action create delay delay.js --timeout 80000 --kind nodejs:10
  • Запустите скрипт Node.js, чтобы вызвать это действие и опросить результат активации.
node script.js

Если сценарий работает правильно, в сообщениях журнала будет отображаться статус опроса, а затем результат активации.

$ node script.js
new activation id: d4efc4641b544320afc4641b54132066
activation result (d4efc4641b544320afc4641b54132066) not available yet
activation result (d4efc4641b544320afc4641b54132066) not available yet
activation result (d4efc4641b544320afc4641b54132066) not available yet
...
activation result (d4efc4641b544320afc4641b54132066) now available!
activation result (d4efc4641b544320afc4641b54132066) { ... }

Первоначально опубликовано на http://jamesthom.as 14 мая 2019 г.