IBM Cloud Functions alarm package の cron 秒フィールドの注意点

# はじめに
IBM Cloud Functions で定期的にトリガーを起こしたくて alarm package を利用しました。
1分間に複数回発生するトリガーは強制的に停止されるので、注意してください。

# Alarm package ドキュメント/リポジトリ

- [Using alarms to schedule triggers - IBM Cloud Docs](https://console.bluemix.net/docs/openwhisk/openwhisk_alarms.html)
    - [ソース](https://github.com/IBM-Bluemix-Docs/openwhisk/blob/master/openwhisk_alarms.md)
- [apache/incubator-openwhisk-package-alarms - GitHub](https://github.com/apache/incubator-openwhisk-package-alarms)

# 3種類の feeds

OpenWhisk alarm package には、トリガーの `feed` が3種類あります。

* Interval (`/whisk.system/alarms/interval`)
    * 最短1分間隔。
    * `startDate`, `stopDate` オプション指定可能。
* Once (`/whisk.system/alarms/once`)
    * 指定の日時。
    * `deleteAfterFire` オプション指定可能。
* Alarm (`/whisk.system/alarms/alarm`)
    * `cron` 指定。「秒」フィールドの指定も可能。
        * IBM Cloud Docs には 6 fields 記法について言及ありませんが、使えました。
    * `startDate`, `stopDate` オプション指定可能。
    * `maxTriggers` オプションは deprecated で間もなく廃止。[デフォルトは `-1` （制限なし）](https://github.com/apache/incubator-openwhisk-package-alarms/commit/fcd3aea35db931e1e3877dbcfb72919295f61f1d#diff-4ea72a877044d151288ce0ad34e95a2f)
        * IBM Cloud Docs には maxTriggers についての記述は既に削除済み。

# `interval` を使うか `alarm` を使うか

定期的にトリガーを起こすのは `interval` と `alarm` feed がありますが、分間隔しか指定できない interval に対して、 cron で柔軟な指定ができて秒間隔も指定できてオプションもほとんど同じな alarm だけ使えば事足りるように見えます。

ただし `maxTriggers` オプション廃止後の動きは気になります。（制限なしの仕様が続くのかどうか）

# Alarm feed (cron) を使ってみた (*/20 * * * * *)

20秒間隔のトリガーを試しました。（1分間に3回発生）

## 手順

以下のサンプルから `maxTriggers` オプションを除いて実行しました。
最新の OpenWhisk の仕様によれば、 `maxTriggers` 省略時は最大実行回数制限なしです。

https://github.com/IBM/ibm-cloud-functions-action-trigger-rule

```shell
$ ibmcloud fn action create handler handler.js
$ ibmcloud fn trigger create every-20-seconds \
  --feed  /whisk.system/alarms/alarm \
  --param cron '*/20 * * * * *'
$ ibmcloud fn rule create \
  invoke-periodically \
  every-20-seconds \
  handler
```

## 結果

トリガーを作成したのは 2018-09-28 の 16:25 （日本時間）でした。

```shell
$ ibmcloud fn trigger get --summary every-20-seconds | jq .response.result.status
{
  "active": true,
  "dateChanged": 1538119522935,
  "dateChangedISO": "2018-09-28T07:25:22Z"
}
```

2018-09-29 の 05:45:20 （日本時間）を最後に終わってる…

![image.png](https://qiita-image-store.s3.amazonaws.com/0/204096/8c545dfe-4d0d-138b-b3b4-486cbe295523.png)

`ADMIN` より `Trigger frequency is not supported` との理由で無効化されておりました。

```shell
$ ibmcloud fn trigger get --summary every-20-seconds | jq .response.result.status
{
  "active": false,
  "dateChanged": 1538119522935,
  "dateChangedISO": "2018-09-28T07:25:22Z",
  "reason": {
    "kind": "ADMIN",
    "message": "Trigger frequency is not supported"
  }
}
```

# Alarm feed (cron) を使ってみた (20 * * * * *)

毎分20秒に発生するトリガーを試しました。（1分間に1回発生）

## 手順

トリガー名を `every-20-second` (secondsより変更）に変更し、 `cron` も `20 * * * * *` に修正しました。

```shell
$ ibmcloud fn action create handler handler.js
$ ibmcloud fn trigger create every-20-second \
  --feed  /whisk.system/alarms/alarm \
  --param cron '20 * * * * *'
$ ibmcloud fn rule create \
  invoke-periodically \
  every-20-second \
  handler
```

## 結果

トリガーを作成したのは 2018-09-29 の 23:30 （日本時間）でした。

```shell
$ ibmcloud fn trigger get --summary every-20-second | jq .response.result.status
{
  "active": true,
  "dateChanged": 1538231425486,
  "dateChangedISO": "2018-09-29T14:30:25Z"
}
```

2018-09-30 の 15:27:20 （日本時間）でもちゃんと動き続けています。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/204096/867f5a52-6965-d711-7880-e194313f92b6.png)

# 考察

OpenWhisk では1分間に複数回発生するトリガーも設定できる仕様ですが、 IBM Cloud Function では一時的には動作しますが、しばらくすると強制停止されてしまいます。
ただし、毎分特定の秒数にトリガーを起こすことはできる（ `cron` の秒フィールド自体はサポートされる）ので、同じ action を複数のトリガーと紐付ければ1分間に複数回発生させることは難しくなさそうです。
（例えば、毎分0秒、毎分20秒、毎分40秒のそれぞれのトリガーを作成しておく。）