homura Docs App | Posts About Login
Ctrl+K

Auto-Await

Phase 17.5 で導入された Auto-Await は、Cloudflare binding 由来の async chain を自動的に検出して .__await__ を挿入する仕組みです。

Before / After

Before(手動 await):

# await: get, put, execute, fetch, send, decode, ...

post '/users' do
  db = Sequel.connect(adapter: :d1, d1: env['cloudflare.env'].DB)
  result = db[:users].insert(name: 'foo').__await__
  Cloudflare::Email.new(env.SEND_EMAIL).send(
    to: '...', subject: '...', text: '...'
  ).__await__
  'ok'
end

After(Auto-Await):

post '/users' do
  db = Sequel.connect(adapter: :d1, d1: env['cloudflare.env'].DB)
  result = db[:users].insert(name: 'foo')
  Cloudflare::Email.new(env.SEND_EMAIL).send(
    to: '...', subject: '...', text: '...'
  )
  'ok'
end

多くのケースで、ファイル先頭の # await: magic comment やユーザー定義のメソッド名リストは不要になりました。ただし、推論不能なケース(metaprogramming、Hash 動的アクセスなど)では、従来の .__await__# await: によるフォールバックが依然として必要です。

AsyncRegistry

gem 側で「これは async source」を宣言します:

CloudflareWorkers::AsyncRegistry.register_async_source do
  async_class 'Cloudflare::D1Database'
  async_class 'Cloudflare::KVNamespace'
  async_class 'Cloudflare::Email'

  async_accessor :env, :DB, 'Cloudflare::D1Database'
  async_accessor :env, :SEND_EMAIL, 'Cloudflare::Email'

  taint_return 'Sequel', :connect, 'Sequel::D1::Database'
  async_method 'Sequel::Dataset', :all
end

各 gem(homura-runtimesinatra-homurasequel-d1)が自身の async source を登録します。プロジェクト固有の登録は lib/homura_async_sources.rb に集約できます。

診断モード

build 時にどの call に await を入れたかを確認できます:

CLOUDFLARE_WORKERS_AUTO_AWAIT_DEBUG=1 bundle exec cloudflare-workers-build

制限とフォールバック

ケース挙動
静的に型が決まる receiver自動 await
同名 sync メソッド(String#sub 等)誤検知なし(origin class で区別)
metaprogramming(env.send(binding_name)推論不能 → 手動 .__await__ でフォールバック
Hash 動的アクセス(ctx[:mail].send(...)推論不能 → 手動 .__await__ でフォールバック

推論不能なケースでは従来の .__await__ または # await: magic comment が引き続き有効です。