🤔

キャンセル処理を実装するのは難しい

に公開

「キャンセル処理を実装するのは難しい」
のですが、多くの人はこの難しさを分かってないのではないでしょうか。
組み込み開発出身の視点なのですが一筆失礼します。

キャンセル実装するときは、本実装と同じかそれ以上に考えてほしい。

キャンセル処理がなぜ必要か

処理のかかる時間を実行するとき、
キャンセルが無ければ終わるまで待つしかないです。
終わらない場合・待てない場合はキャンセルが必要です。

テレビなどの家電で、番組検索が1分かかるようなものをイメージしてください。
キャンセルしたくなりますよね??

キャンセル処理がなぜ難しいか

「キャンセルなんておまけでしょ?本実装してから考えるわー」
を止めたいです。順に流れる実装より、キャンセルの方が難しい。

「単純に制御戻せばいいじゃん」って考えるのでしょう。
Workerみたいなものを思い浮かべればいいと思います。
「メインとは別のスレッドに移し、バックグラウンドでの実行を可能にする仕組み」

考えなければいけないポイント
・ロールバック、途中までやってしまった処理を戻す
・キリの良いところで中断、即座に止められない処理もある
・後片付け、メモリの開放とかロックの開放とか
・(次の処理をするために)キャンセルの完了を待つ必要があるか

基本的には、オブザーバーで状態を監視して、キャンセル通知はフラグ立てて、
Workerで動く処理はフラグ見て処理を中断すればよいです。

例題。実装できますか?

あるサラリーマンは、以下のような行動をします。
(0)サラリーマンは商談先のリストをもつ。単純に目的地の配列。
(1)電車で目的地に向かう
(2)目的地で商談をする
(3)次の目的地があれば(1)、なければ(4)
(4)本社に戻る

キャンセルの実装は、
電話したらそのサラリーマンを本社に戻ってくるようにしたい。

(1)のとき、どうします?
電車で電話にでますか?即座に電車から飛び降りますか?
次の駅で折り返しの電話して戻ってくるんじゃないでしょうか??

(2)のとき、どうします?
普通は電話に出ない方がいいですけどね。
なので、(2)が終わって、(3)のタイミングで折り返せばいいんじゃないでしょうか。

といった感じで、即座に片づけられない例を出してみました。
これが、本社に戻ってこなくて良くて、いつも行ったっきりで良いなら、
もう仕事辞めていいよ、っていうだけで済みますね。
(そういうのが許される設計にするのは一つの解かもしれません)

でも、巡回するサラリーマンが本社から大事なアイテムを持ち出している場合は、
最終的に本社に返してほしいですよね?なので、戻ってくるように設計が必要と。

キリの良いところで中断、後片付けまでする。を最初から意識できれば、
変なプログラムを作らないと思っています。

まとめ

月1は記事書くぞーということで、今回はこんなテーマにしましたm(_)m
20年前の実装だとこういうことが良く起きてました、今ではどうでしょうか?

エラー処理は、キリが良い分、キャンセルよりは簡単です。
なので、あえてキャンセル処理としました。

キューイング+ワーカーの実装をしている方、
状態遷移設計とエラー・キャンセルの設計くらいはちゃんと考えてくださいね!!
キューイング+ワーカーの実装なんて大した仕事じゃないので。

Discussion