1 ポイント 投稿者 GN⁺ 2024-04-21 | 1件のコメント | WhatsAppで共有
  • 企業・教育機関で広く使われている Microsoft Exchange を、Thunderbird が 2024年7月の ESR からネイティブサポートする予定であり、最初の対象範囲はメールに限定される
  • 今回の作業は Exchange Web Services(EWS) サポートを超えて、20年以上続くメールプロトコルアーキテクチャと古い C++ コードの限界を段階的に整理する契機となる
  • 実装言語には Rust が選ばれ、メモリ安全性・ネイティブ性能・モジュール性・Firefox と共有する CI および XPCOM 相互運用性が主な理由である
  • EWS 統合の過程で xpcom_asyncmoz_httpxml_structews といったクレートが作られ、XPCOM ベースの HTTP 呼び出しと XML シリアライズを Rust フレンドリーにラップしている
  • EWS は Exchange Online で 2026年10月以降利用不可になるが、オンプレミスの Exchange Server 利用者が多いため、Thunderbird には依然として必要なサポートである

2024年7月 ESR における Exchange サポート範囲

  • Thunderbird は次の ESR(Extended Support) リリース である 2024年7月に、Exchange サポートをネイティブ提供する予定である
  • 初期範囲は メール に限定される
    • カレンダーとアドレス帳のサポートは今後追加される予定である
    • 最近まで Exchange 機能はアドオン経由でしか利用できなかった
  • 実装対象は Microsoft の Exchange Web Services(EWS) API である
    • EWS は HTTP 上で動作する
    • リクエストおよびレスポンス本文には XML を使用する

20年以上前のメールアーキテクチャの負担

  • Thunderbird の現在のメールプロトコルアーキテクチャは、Thunderbird より古いコードに基づいている
    • 20年以上前に Netscape Communicator の一部として開発された
    • 2012年に Mozilla が Thunderbird の所有権をコミュニティへ移し、2017年に Mozilla Foundation に再合流するまで有償メンテナンスがなかった
  • 大きなアーキテクチャ方針のないまま暫定的な変更が積み重なり、最新標準を使っていない C++ コード が多く残っている
  • Thunderbird プロジェクトの20年間で、新しいメールプロトコルのサポートが追加されたことはなかった
    • メールプロトコルが現代的な利用パターンに合わせて変化する一方で、関連構造は更新されなかった
    • 多くの制度的知識も失われた状態である
  • Exchange サポートは、Thunderbird アーキテクチャの限界を理解し、段階的に解決しようとする最初の 組織主導 の取り組みである

Rust を選んだ理由

  • Rust は Thunderbird の新しいプロトコルサポートの実装言語として選ばれた
  • 選定の背景には、一般的な Rust の利点と Thunderbird 固有の条件があわせてある
    • メモリ安全性: Thunderbird はメールを送信できる誰からでも入力を受け取るため、セキュリティバグを減らすことが重要である
    • 性能: Rust はネイティブコードとして実行される
    • モジュール性とエコシステム: Rust のモジュール構造とメール関連のエコシステムを活用できる
  • Thunderbird は Firefox のコード上に構築されているため、Rust 導入の条件がすでに整っている
    • Firefox と共有する CI インフラが Rust をサポートしている
    • Firefox の XPCOM(Cross-Platform Component Object Model) 相互運用レイヤーを通じて、Rust・C++・JavaScript 間の呼び出しが可能である
  • Rust の型とツールは、誤用しにくい API を作るのに役立つ
    • 循環参照を避けたり、意味のない値で呼び出せない関数を作ったりできる
    • ドキュメント化ツールが言語に標準搭載されており、小規模チームに有用である
  • モジュール型クレートとして作れば、Thunderbird for Android/K-9 Mail のような他プロジェクトでも再利用できる

ビルドシステムと XPCOM の制約

  • Thunderbird 内で最初の Rust コンポーネントを実行する際、ビルドシステム が最初の障害となった
  • Thunderbird は Firefox コードの一般的な依存関係のように取り付けられる構造ではない
    • ビルド時に Firefox コードを取得する
    • Thunderbird コードを Firefox のサブツリーとして取り込む
    • ビルド設定ファイルでそのサブツリーを指す
  • Firefox はツリー全体の Cargo 依存グラフを作るため、個別クレートを1つの Cargo ワークスペースにまとめている
    • Thunderbird にも独自の Cargo ワークスペースが必要だったが、Cargo はネストしたワークスペースを許可しない
    • 解決策として Thunderbird 独自のワークスペースを定義し、上位ビルドツール mach が Firefox ワークスペースの代わりにそれをビルドするよう設定した
    • 新しい mach サブコマンドで依存関係と lockfile を上位と同期し、結果の superset を vendoring する
  • XPCOM は C++ 中心に設計されており、Rust 開発体験はスムーズではない
    • XPCOM インターフェースの実装と利用には多くのボイラープレートが必要である
    • rust-analyzer のようなツールを十分に活用しにくい
    • Firefox は XPCOM 依存をかなり減らしてきたが、Thunderbird はメンテナンス空白期間に同様の整理作業ができなかった
  • 新しいメールプロトコルサポートには、XPCOM で定義された数百の関数実装が必要である
    • 既存プロトコル実装は共有動作を提供する C++ クラスを継承して負担を減らしている
    • Rust ではこれを直接行えないため、プロトコルごとのロジックを Rust に実装している
    • C++ ブリッジクラスが内部クレート ews_xpcom と既存の共有動作コードを接続する
  • Thunderbird で Rust コンポーネントを作る方法は ドキュメント にまとめられている

HTTP リクエストを Rust らしく扱う

  • Firefox には necko ネットワーキングコンポーネントによる HTTP スタックがすでにある
  • necko は C++ で書かれ XPCOM として公開されているため、Rust から直接使うにはボイラープレートが多い
    • 単純な GET リクエストでも多くの XPCOM オブジェクト生成が必要である
    • XPCOM がポインタの寿命を管理するが、Rust コンパイラはそれを認識できないため unsafe ブロックが必要になる
    • 必要なインターフェースはコールバックベースである
  • Thunderbird の内部クレート xpcom_async は、XPCOM の非同期処理を Rust の async/await 構文へ変換する
    • コールバックで入ってくるデータをバッファリングする
    • Rust の Future trait を実装し、呼び出し側が await できるようにする
    • Rust の Future は JavaScript の Promise や Python コルーチンに似ている
  • 内部クレート moz_http は、reqwest に着想を得た HTTP クライアントを提供する
    • 必要な XPCOM オブジェクト生成を処理する
    • 標準的な XPCOM エラー処理より Rust らしいエラー処理を提供する

EWS の XML シリアライズと新しいクレート

  • EWS で最も難しい作業は、Thunderbird 内部データ構造と EWS が要求または提供する XML の間を変換することである
  • 既存の XML シリアライズ・デシリアライズ用クレートでは要件を満たせなかった
    • serde のデータモデルは XML と相性がよくなく、属性と要素を区別しにくい
    • EWS は XML 名前空間に敏感だが、これは serde では馴染みの薄い概念である
    • XML 向けの serde 系クレートでは、すべてのフィールドのシリアライズ方法を明示的に注釈しなければならない
    • EWS は数百の型と型ごとに数十のフィールドを定義しているため、ボイラープレートが現実的でない
  • 既存の serde ベース実装は、XML を Rust にデシリアライズするには十分だったが、満足できるシリアライズツールは見つからなかった
  • 新しいクレート xml_struct は、XML シリアライズ動作を定義する trait と手続き型 derive マクロを提供する
    • Rust データ構造向けの trait 実装を自動生成する
    • 既存の quick_xml クレート上に構築されている
    • XML と Rust の間でボイラープレートの少ないマッピングを目指している
    • Thunderbird/Firefox 内部には依存せず、初期開発段階にある
  • 新しいクレート ews は、EWS 操作用の型と XML シリアライズ・デシリアライズ API を定義する
    • xml_structserde をベースにしている
    • 初期開発段階で、GitHub に公開されている

テスト、エラー処理、UI 接続計画

  • 次の主要機能を入れる前に、自動テスト を強化しているところである
    • 単体テストだけでなく、統合テスト用の mock EWS サーバーも追加された
    • テスト強化の過程でいくつかのクラッシュや double-sync 問題が見つかり、修正された
    • 新機能をより容易にテストし検証できるようになった
  • EWS のエラー処理は改善中である
    • EWS のエラー動作は文書化が不十分な場合が多い
    • リクエスト全体が throttling や不正な構造によって失敗することがある
    • リクエストの一部は成功し、一部は不正な ID によって失敗することがある
    • 一部のエラーはプロトコルレベルで対処可能だが、ユーザー介入が必要なものや解決が難しいものもある
  • EWS プロトコルサポートは ews と内部 ews_xpcom クレートを通じて拡張されており、Thunderbird UI との接続も進んでいる
    • 最近のパッチにより、EWS アカウントを Thunderbird に追加できるようになった
    • リモートサーバーからアカウントのフォルダー階層を同期できる
    • 同期されたフォルダーを UI に表示できる
    • 現在このアルファ段階の機能は、ビルドフラグと設定値の背後に隠されている
  • 次の作業は、リモートサーバーからメッセージ一覧を取得する機能と、Thunderbird の送信メールサポートの一般化である
  • 保守のために、各構成要素がどのように結び付くか、既存の Thunderbird メールプロトコルアーキテクチャと今後の改善方向を文書化している

EWS と Microsoft Graph の関係

  • EWS は Exchange Online で 2026年10月以降使用できなくなる
  • プロジェクトの事前調査では、オンプレミス Exchange Server を引き続き使用するユーザーが相当数いることが分かった
    • 多くの企業や教育機関が自社ハードウェア上で Exchange Server を運用している
    • こうしたオンプレミス導入は概ね EWS をサポートしている
    • Azure ベースの Graph API はサポートできない
  • EWS サポートは、近い将来こうしたユーザーを支援する手段となる
  • Graph API には、まだ未解決の問題がいくつかある
    • Graph API はデスクトップアプリケーションではなく、Web ベースのサービスを想定して作られている
    • 先に EWS サポートを追加することで、Graph API サポートを作る前にそれらの問題の解決策を探す時間を確保できる
  • Rust と EWS の作業は、Thunderbird のターンアラウンドを短縮し、ソフトウェア中核部の回復力を高めるための、より大きな取り組みの一部である

1件のコメント

 
GN⁺ 2024-04-21
Hacker News のコメント
  • すでに EWS は廃止予定で、2年後に削除されるというのに、なぜ実装するのか分からない: https://techcommunity.microsoft.com/t5/exchange-team-blog/re...

    • EWS は Outlook 以外のクライアントが動作できる唯一現実的な方法で、MAPI は特にオープンな API でもない
      EWS が消えれば顧客もかなり離れるだろうし、最初は Microsoft の業績に打撃を与えるほどではないかもしれない
      そのうち結局、すべてのメールは等価だということが明らかになり、Exchange Online は歴史の脚注になるかもしれない。Microsoft がメールで大失敗したように見えるので外聞は悪いが、実際には必ずしもそうでもない
      メールシステムの運用は苦痛で、Microsoft が本当に欲しいのは、掘り出してほかのデータ中毒者たちに売れる データとメタデータだけだ。メールはストレージ基準ではたいてい静的で大きいが、個人間のやり取りからは金脈が掘れる可能性がある
      理想的には AWS や Google のようなところに苦労を押し付け、顧客には Outlook を使わせればよい。そして新しい Electron 版 Outlook のように認証情報を Microsoft クラウドに保存させ、その認証情報で他人のクラウド上にあるメールデータを掘り起こせば、保存コストは相手側持ちになる。実に素晴らしい
    • Sean Burke が関連する Bugzilla バグで述べているように、現時点では EWS が Exchange Online とオンプレミス環境の両方をサポートする最善の方法だ: https://bugzilla.mozilla.org/show_bug.cgi?id=1847846#c2
      Graph API も検討され、今後再び検討される可能性はあるが、現状では EWS よりサポート範囲が狭く、デスクトップアプリケーションに必要な機能の一部が不足している
      Exchange Online で EWS サポートが削除されるという発表があったとしても、短期的には幅広いユーザー層のアクセスを可能にし、長期的にはオンプレミス導入ユーザーを支援するうえで、なお価値がある
    • Exchange のようなものを相手にするなら、当面 現実的な他の選択肢がほとんどないからだ
    • Exchange Online を使っている人ばかりではない
  • 目標が単に Thunderbird ユーザーを増やすことなら、戦略的には筋が通るが、理念的には JMAP サポートのほうがはるかに良く見える

    • 今回成し遂げた作業の大半は、今後 JMAP サポートを追加するうえでも中核になると思う
  • 最近 Outlook の代わりに Thunderbird を使ってみたが、Quantum アップデート前の Firefox と同じ問題があった。遅すぎる
    数百〜数千通のメールがあるフォルダー間を切り替えると目に見える遅延があり、Outlook では実質的に即時に切り替わる

    • Windows を使っているなら、私の経験では Thunderbird のプロファイルを Windows Defender の例外に追加するまで、Thunderbird はほとんど使いものにならなかった
    • 私の経験はまったく逆だ。メールに Outlook を使うのはあまりにつらく、特に検索がまともに機能しない。Thunderbird では expressionsearchNG を使っている
      カレンダーは正反対で、今は両方を並べて動かしている。ひとつの問題は、会社で使わなければならない Outlook サーバーへの iCal ブリッジらしい
      今回の発表では、その点は残念ながら変わらない。しばらくは Ericsson が保守していた EWS アドオンを使っていた: https://github.com/Ericsson/exchangecalendar
      しかし Mozilla はインターフェースを急速に壊し、多くのプラグイン開発者を離れさせたように思う。今になって一部機能を再びコアに入れているが、それが良い戦略なのかは分からない。むしろ 安定したインターフェースに注力すべきだと思う
  • Exchange は嫌いだが、この作業は歓迎だ。これで Windows に縛られた状況でも Exchange でプレーンテキストメールを問題なく送れるようになるかもしれない

    • そうすると、技術的純粋主義や昔へのノスタルジーのせいで、いろいろなメールクライアントでメールの見栄えがずっと悪くなるかもしれない
      プレーンテキストメールが、等幅フォントでレンダリングされるのがどれほど一般的かを見ると、「HTML メールは忌まわしい」という理由だけでプレーンテキストを正当化するのは難しいと感じる
  • 「Thunderbird プロジェクトの20年の全歴史で、新しいメールプロトコル対応を追加した人はいなかった」という言い方は技術的には正しいが、大企業ごとに OAuth2 の帯域外認証実装やメールクライアントごとの特殊設定、つまり回避策が必要で、Thunderbird もそうしたものをかなり蓄積してきた
    これらは一般的なメールプロトコルではない。IMAP、POP3、SMTP ではなく、HTTPS 上で動作する
    「新しいメールプロトコルを追加したことがない」のは良いことであり、今回の変化は良くない。独自設定のサポートは実用的で理解はできるが、良いことではない
    メールが企業ごとの数十の亜種に分裂する問題を一時的に和らげるだけで、長期的には人々がそうした亜種を受け入れるよう後押ししてしまう

    • 従業員は会社のメールプロバイダーを選べず、99.99999% の人にとって、これは命を懸けて戦うような論点ではない
      一方で Thunderbird をクライアントとして使えるようになることは純粋な利益であり、実用的な選択だ
    • 大企業のどれかではなく、業務用メールで圧倒的に最も一般的に使われている Microsoft Exchange、特に Exchange Online のことだ
  • なぜタイトルが変わったのか分からない。この記事はRustプログラミングについての記事だ。
    “Bringing Exchange Support to Thunderbird” だと Thunderbird と Exchange 対応についての記事のように見えるが、その内容はこの記事からは分からない

    • 記事の最初の段落が言語よりも Exchange に焦点を当てているので、実装よりも機能そのもののほうが重要に見える。ほとんどのユーザーもそちらを気にする
    • 同じ記事をそのタイトルのままで以前投稿したが、注目を集めなかった: https://news.ycombinator.com/item?id=40095870
    • 何を言っているのか分からない。記事の後半全体がThunderbird の Exchange 対応についての内容だ
  • 独自仕様への対応が有用なのは分かるが、Mozilla にはメール送信サーバー(SMTP)の自動検出のような標準実装を優先してほしい。たとえば rfc6186 は 2011 年に出ている。
    現在はユーザーが SMTP サーバーのホスト名とポートを手入力しなければならず、このサイトにいる人たちには問題なくても、残り 99.9% の人類にはまったく親切ではない
    Exchange 全体を実装するのに必要な労力は、DNS/SRV による送信サーバー検出よりおそらく何桁も大きいはずだ。Mozilla の優先順位は本当に理解できない

    • Hotmail、Google、Yahoo のアカウントを Thunderbird に追加したときは、そういう情報を入力しなかった気がする。メールアドレスを書いただけだった
      これらは特別扱いされているのだろうか?
  • うわ、20 年くらい前に IT で働いていたころを思い出す。ほぼ完全な Microsoft 環境の中で、Linux を使っていたのは数人だけだった。
    Exchange はいつもまともなクライアントを見つけるのが難しいものの 1 つで、あのころこれがあったなら本当に飛び上がるほど嬉しかっただろう

    • 今でも飛び上がるほど嬉しい
      Linux で Microsoft 製品を使うのは本当につらいし、特に Edge を使わないと Teams の Web 版は切り捨てられる過程に入っているように見える :(
    • うちでも同じ問題があったが、別の道を選んだ。会社にExchange と SharePoint を捨てさせ、その後はずっと幸せになった
  • 「2012 年ごろに Mozilla が Thunderbird から手を引いてコミュニティに所有権を渡してから、2017 年に Thunderbird が Mozilla Foundation に再合流するまで有給メンテナーがいなかった」というのは本当にスキャンダルだった。
    Mozilla の狂った優先順位を示す代表例だ

    • 同意しない。世界はWeb / モバイルアプリベースのメールへ移った
      それが気に入らないのは分かるし、私も別に嬉しくはない。でもそれが現実で、Mozilla がお金を出す価値はなかった
  • Outlook の導入から離れようとしている人たちが、Outlook 自体を触らなくてもスムーズに移行できるように、PST ファイルのインポートを標準で含めてほしい
    PST ファイルを読めるフリープロジェクトはすでにあるのだから、製品群に統合するだけでいい

    • PowerShell 向け Exchange モジュールを使ったPST エクスポートは Exchange 2010 からあった。“New-MailboxExportRequest” を見ればよい: https://learn.microsoft.com/en-us/powershell/module/exchange...
      修正: あ、違った。オンプレミス専用だった。これは本当にばかげている