非同期処理の悩みどころ

「UI向上のために非同期をしなければいけないんだ!!!!!!!」が界隈世間一般の語彙になって10年ぐらいだろうか、今初めてUIで簡単な非同期処理を実装してみてマルチスレッドは難しい問題を身に染みている。

タスクの取り消しは正常系

検索をかけた、でも結果が返ってこない。おそらくユーザーはキャンセルするだろう。 その挙動は、キャンセル可能であれば望ましい。

夜間に更新して日中は一切更新しないデータベースを参照するだけのアプリであれば何も考えずThreadにabort要求を投げて、また新しく検索しなおせば同じ結果になるが、 更新と参照が入り乱れる業務アプリや、動的にキャッシュを作成してやりくりする涙ぐましいリソースの切り盛りをしている基盤は、abortできる処理とできない処理を切り分けないといけないし、恐らくそれは、心地の良いUIを作るうえで障害となる。

ぱっと考えた対策

1. トランザクションのACID特性の強化

更新処理は、abortできるものにする。 例えば「法人を消したら、それに紐づく顧客情報すべても無効とする」という少なくも2テーブルを更新する処理をする際、 処理が中途半端にabortしたら「法人はつぶしたけど、顧客は生きている」などの更新不整合が発生しないようにする。

HTTP <-> client なアプリでは導入しやすいが、WindowsアプリやJavaScriptなメモリを書き換える環境では、グローバルな参照オブジェクトへのCommitタイミングを意図的に調整する工夫がいる。

2. 関連する処理を直列キューにする

顧客情報を更新・参照する処理は顧客情報関連の直列キューなど、処理の順序を保証する。 サバクラだと性能が死ぬが、クライアント内で実装する分には、GUIのロックを下げるだけの効果はある。(どうせ処理待ちは発生するので、ユーザーの自由度を少しでも上げる)