0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

【Cloudflare Workers】最近困ったことのメモ

Posted at

Cloudflare Workersで個人用のちょっとしたワークロードを組んでいるのだが、開発中にちょっと困ったことがあったので、対応した内容をここにメモで載せる。

いくつかのパッケージがCloudflare Workers上で(nodejs_compatでも)使用できない

もともとLambdaで動かしていたワークロードをCloudflare Workersにそのまま移植したものがあったのだが、これの一部処理で使っていたパッケージが動作しなかった。

sharp

sharpはCloudflare Workerのランタイム上で使えないっぽい。「ぽい」というのは、実際にdeployして試したというよりローカルでwrangler dev実行してエラーになったことからそうだと判断した。もちろんwrangler.tomlnodejs_compatは設定済である。wrangler devすると以下のようなエラーが出て、wranglerが起動しない。

✘ [ERROR] service core:user:hogehoge: Uncaught Error: [unenv] process.report.getReport is not implemented yet!

    at null.<anonymous> (index.js:50:10) in createNotImplementedError
    at null.<anonymous> (index.js:54:11) in fn
    at null.<anonymous> (index.js:51387:36) in getReport
    at null.<anonymous> (index.js:51962:23) in familyFromReport
    at null.<anonymous> (index.js:52035:21) in familySync
    at null.<anonymous> (index.js:52045:73) in isNonGlibcLinuxSync
    at null.<anonymous> (index.js:53653:63) in runtimeLibc
    at null.<anonymous> (index.js:53654:82) in runtimePlatformArch
    at null.<anonymous> (index.js:53805:27) in node_modules/sharp/lib/sharp.js
    at null.<anonymous> (index.js:20:50) in __require2



✘ [ERROR] The Workers runtime failed to start. There is likely additional logging output above.

jsdom

これも↑と同じ。jsdomはCloudflare Workersでは使えない。こっちはワンチャンCloudflare Workers上だと動いたりしないかなと思って思い切ってDeployしてみたが、同じエラーでDeployに失敗した。なのでwranglerでダメなものはCloudflare Workersでもダメ、なんだと思う。

▲ [WARNING] Import "default" will always be undefined because there is no matching export in "node_modules/unenv/dist/runtime/npm/whatwg-url.mjs" [import-is-undefined]

    required-unenv-alias:whatwg-url:6:27:
      6 │         "default" in esm ? esm.default : {}
        ╵                                ~~~~~~~


[wrangler-UserWorker:wrn] Miniflare 3 does not currently trigger scheduled Workers automatically.
Use `--test-scheduled` to forward fetch triggers.
⎔ Starting local server...
✘ [ERROR] service core:user:hogehoge: Uncaught Error: [unenv] whatwg-url.parseURL is not implemented yet!

    at null.<anonymous> (index.js:59:10) in createNotImplementedError
    at null.<anonymous> (index.js:64:27) in fn
    at null.<anonymous> (index.js:130676:34) in DocumentImpl
    at null.<anonymous> (index.js:131400:16) in exports.setup
    at null.<anonymous> (index.js:131350:22) in exports.create
    at null.<anonymous> (index.js:131353:31) in exports.createImpl
    at null.<anonymous> (index.js:134911:24) in exports.createImpl
    at null.<anonymous> (index.js:134914:37) in exports.createWrapper
    at null.<anonymous> (index.js:188912:37) in installOwnProperties
    at null.<anonymous> (index.js:188826:7) in exports.createWindow



✘ [ERROR] The Workers runtime failed to start. There is likely additional logging output above.

scheduler云々のエラーが出ているのはこの処理がCronトリガーで呼び出されるものだったためである。

Cronトリガーでちょっとハマった

CloudflareのCronトリガーはWeekdayの部分の規定値が"1-7"になっており、一般的には(というか私の理解がそうだったというだけなのだが)"0-7"が規定値だと思い込んでいたので、ちょっとハマった。Weekdayに規定外の値、たとえばここで言うと"0"を含めてDeployすると、エラーになってDeployが失敗する。ちなみに以下のようなエラーが出てくる:

...
X [ERROR] A request to the Cloudflare API failed
  invalid cron string [code: 10100]
...

厄介なのは、ローカルでwrangler dev --test-scheduledで試している分には、このエラーは出てこないことだ。これでcurl "http://localhost:8787/__scheduled?cron=0+12+*+*+0"とかやってもこのエラーが起きず正常動作するので、何が原因なのか最初ちょっとよくわからなかった。つまりローカルで--test-scheduledつけて動かしたときの動作は、パラメータに渡した文字列をそのまま素通りでアプリに回してるだけで、Cron式のvalidationなんか一切していないんだと思われる。極論、cron=aaaとかでも動くんだろう(試してないけど)。ちなみにCloudflare WorkersのCron式のWeekdayは、"1"が日曜日、"2"が月曜日、…で"7"が土曜日である。"0"を許容するCron式の一般的な体系(?)では、"0"と"7"が日曜日で、"1"が月曜日、…、"6"が土曜日、となるので、一般的なCron式のWeekdayの体系とCloudflareのCron式は数値と曜日が1つずつズレていることになる。わかりづらい。なんで特殊な体系にしてしまったのだ?

指定したVersionのPrismaがインストールされない(のでDBに接続できずエラー)

これは(おそらく)Cloudflare WorkersとPrismaの複合的な問題(?)である。最初に発見したのは4/10 18:30JST頃のDeployだが、このときDeployのログに以下のメッセージを見つけた

npm warn exec The following package was not found and will be installed: prisma@6.6.0

このときpackage.jsonに指定していたPrisma関連のパッケージはおおむね6.4.1を指定していた

    "@prisma/adapter-pg-worker": "6.4.1",
    "@prisma/client": "6.4.1",
    "@prisma/pg-worker": "6.4.1",

で、どうも6.6.0からPrismaClientの生成方法が変わってるらしく、6.4.1までなら以下の実装でいけたんだが

import { Prisma, PrismaClient, } from "@prisma/client"
import { Pool, PoolConfig } from "@prisma/pg-worker";
import { PrismaPg } from "@prisma/adapter-pg-worker";
...
  const databaseUrl = String(process.env.DATABASE_URL);
  const schema = new URLSearchParams(new URL(databaseUrl).searchParams).get('schema');
  const pool = new Pool({
    connectionString: databaseUrl,
  });
  const adapter = new PrismaPg(pool, { schema: schema || 'public' });
  const prisma = new PrismaClient({
    adapter,
  });

6.6.0だとこれではコンパイルエラーになる(adapterの生成部分がエラーになる)ようで、以下に変更が必要になった

import { Prisma, PrismaClient, } from "@prisma/client"
import { Pool, PoolConfig } from "@prisma/pg-worker";
import { PrismaPg } from "@prisma/adapter-pg-worker";
...
  const databaseUrl = String(process.env.DATABASE_URL);
  const schema = new URLSearchParams(new URL(databaseUrl).searchParams).get('schema');
  const config:PoolConfig = {
    connectionString: databaseUrl,
  };
  const adapter = new PrismaPg(config, {schema: schema || 'public'});
  const prisma = new PrismaClient({
    adapter,
  });

要するにPrismaPgの第一引数にnew Pool({connectionString: hogehoge})を渡すか(~6.4.1)、{connectionString: hogehoge}を渡すか(6.6.0~)の違いである。この{connectionString: hogehoge}の部分がPoolConfigというnode-pgのInterfaceになっていて、いちいちPoolオブジェクト生成しなくてもよくなったということのようだ。が、こういうちょっとしたことでも破壊的変更はしないでほしかったというのが個人的にな正直な感想である。これのせいでDBにつながるワークロードはすべて全滅してしまい軽く阿鼻叫喚に陥った。

この件は、Prisma関連のパッケージのバージョンを6.4.1->6.6.0にアップデートして、コードを上記の内容に修正したうえでDeployし、とりあえず復旧させた。

一方、上のログメッセージの通りなら「6.4.1が見つからないから代わりに6.6.0インストールするね」ということらしいが、npm viewやっても以下の通りちゃんとバージョン返ってくるので、こんなこと言われる筋合いはないはずなのである

$ npm view @prisma/adapter-pg-worker@6.4.1 version
6.4.1

かつ、不思議なのは、このログメッセージは、Prisma関連のパッケージを6.6.0にアップデートした後でも出てくることである。もう6.4.1はpackage.jsonには存在してないのにも関わらず、である。キャッシュかな?Cloudflare WorkersのDISCORDを検索してみたが同じことに悩んでる人はいなかった。ので、特殊な事情なのかもしれない。Cloudflare Workersがビルドのときに個別のパッケージレジストリ使ってるとか、そういうことなんだろうか?

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?