Closed6

Cloudflare WorkersからTiDB Serverlessに接続できない (解決済み)

bohnenbohnen

突然WorkersからTiDB Serverlessに接続できなくなったというコメントを発見。

確かに、手元にあったWorkers + TiDB Serverless Driverのサンプルも同じエラーが接続できなくなっている。元Postの方からServerless Driverのgithubにissueも立てていただいておりありがとうございます。

https://github.com/tidbcloud/serverless-js/issues/63

開発チームに連携しつつ、なぜこれが発生したのか考えてみる。

bohnenbohnen

Serverless Driverでno-store を指定しているのは下記の箇所

https://github.com/tidbcloud/serverless-js/blob/efc89f151920219d138befcfde56cca0cb2df527/src/serverless.ts#L5

ただこの後にWorkersではこの指定がサポートされていないことがコメントで記載されており、
実際にダミーURLでRequestを作っていて、Exceptionが出たらCatchしているようだが...?

RequestはただのClassなので、newするだけでは例外にならないんじゃないだろうか。

bohnenbohnen

仮説を確認するために、WorkersのHelloWorldを修正して試してみる。

  • fetchをコメントアウトした状態(TiDB Serverless Driverで使われている判定)だと、正常に終了してHello Worldが返る。
  • fetchを実行すると、例外が発生して Error が返る。

例外処理がうまく働いていないようだ。いままでなんで動いていたのかは謎だが、Request作成時にエラーになっていたか、fetchでcacheオプションを無視していたかのどちらかだろう。cacheが効かないことは元々想定していたようなので、前者だろうか。

export default {
	async fetch(request: Request, env: Env, ctx: ExecutionContext): Promise<Response> {
		try{
			const req = new Request('x:', {
				method: 'POST',
				body: JSON.stringify({
					"test": "test"
				}),
				headers: {
					'Content-Type': 'application/json',
				},
				cache: 'no-store'
			});
			// const response = await fetch(req);
		}catch(e){
			console.log(e);
			return new Response('Error');
		}
		return new Response('Hello World!');
	},
};
bohnenbohnen

ここまでで

  • Workersはcacheをサポートしていない
  • Serverless Driverでcacheが使えない判定を行っている箇所が正しく動いていない
    ということが分かった。 Issueに追加して、丁度開発チームからACKもきたので開発チームのアクションを待つことにする。
bohnenbohnen

途中でちょっと寄り道をしてcacheオプションとは何なのかについて調べてみた。フロントエンドエンジニアではないので、普段はこのあたり全然使っておらず、地理感がない。

https://developer.mozilla.org/en-US/docs/Web/API/Request/cache

https://zenn.dev/yumemi_inc/articles/670970a573c31c

cacheプロパティは(主にブラウザの)キャッシュコントロールに利用するプロパティのようだ。クライアントがfetch()を利用するときのキャッシュの利用について指定する。
cacheの指定はdefaultでいいのではとおもったが、defaultの挙動はキャッシュが新しければ利用するようになっている。DBサーバ側ではcacheしないようにレスポンスを返すと思うが、確実を期すためキャッシュを利用しない no-store を使っているのだろうと思った。

TiDB Serverless Driver自体はWorkersのようなサーバサイドからだけではなく、ブラウザのようなクライアントサイドからもTiDBを呼び出せるように考えられている。実際のところ認証が必要なのでクライアントから使われることは無いと思うが、APIは共通なのでキャッシュを使わないような指定にしておくのは正しいと思う。

一方でWorkersのようなサーバサイドでは、fetch()のcacheプロパティをそもそも使えないようにしておくのも理にかなっている。CloudFlareのcacheの指定の仕方は固有のものがあり、cacheが必要なケースではそちらを使うことになるのだろうと思われる。
https://developers.cloudflare.com/workers/examples/cache-using-fetch/

bohnenbohnen

Cloudflareに以下のIssueが登録され、そこでの議論により今回の変更は巻き戻された。サンプルコードを再度実行し、Requestの作成時に例外が出るようになっていることを確認した。

https://github.com/cloudflare/workerd/issues/2116

Kentonさんの

Just to be clear, it is always our fault if code in production breaks as a result of a change we made, not the application's fault. I apologize for the breakage here.

という発言はプラットフォーマーとして模範的な姿勢だと思います。関係者の皆様、ありがとうございました。

このスクラップは2024/05/13にクローズされました