マンガ作成アシストツールを作ろう④O/Rマッパーの仕様についての思索

まだ、考えただけなんだからね
0
汝、翼を与える@ばってん先に翼ばくれんね イベント・・(parody) @ryunosinfx

さて、ORマッパーの安直なロジックを考えないと。レンジ指定が厄介かもしれない。うーん

2017-08-11 14:37:37
汝、翼を与える@ばってん先に翼ばくれんね イベント・・(parody) @ryunosinfx

まずはクラスを作る。jsはゲッターセッターが使えるので、そこでなにか出来るのか?値が変わったことを検知して、十分時間が立ったらdbに保存するとする。 そう言えばトランザクションも管理したいね

2017-08-11 14:42:33
汝、翼を与える@ばってん先に翼ばくれんね イベント・・(parody) @ryunosinfx

トランザクションは何とか頑張ればいいような気はする?jsには同期実行という概念がなかったような。無いということは、複数の部品からイベント発火したらアウトと言う事

2017-08-11 14:49:29
汝、翼を与える@ばってん先に翼ばくれんね イベント・・(parody) @ryunosinfx

じゃあ書き込み自体をキューに突っ込んで処理せざる得ないということか。読み込みは当然ファントムリードが横行する。リードコミティッドだもの

2017-08-11 14:53:46
汝、翼を与える@ばってん先に翼ばくれんね イベント・・(parody) @ryunosinfx

まあいい、ORマッパーだ。 何をしたいかというとセレクトだ。条件付きセレクトね。あと並び替え。リレーション貼った子Entityの同時読み込み。 結局、dbmsガチに作り込むわけではないので、事実上のオンメモリデータ格納でやりくりする。鍵はjsのArrayがどれだけ早く動けるかに

2017-08-11 14:58:49
汝、翼を与える@ばってん先に翼ばくれんね イベント・・(parody) @ryunosinfx

配列に入れたので、それを頑張って全件ペロペロ舐めて抽出するしかないか。 参照を貼られている場合は、どうしたら良い? Entity定義たるクラスに指定されたテーブルを漁って参照キーごとに配列にまとめてくっつけるイメージか

2017-08-11 15:20:55
汝、翼を与える@ばってん先に翼ばくれんね イベント・・(parody) @ryunosinfx

あとは物理層に確実に反映する。リードコミティッドだからいいか。問題はメモリの状態と同期するか。失敗した場合はどうやればリカバレルから

2017-08-11 15:36:27
汝、翼を与える@ばってん先に翼ばくれんね イベント・・(parody) @ryunosinfx

ブラウザクラッシュはまあいいけど、まあリードコミティッドか各トランザクションが読み込みまで保証したら良いのか。操作途中のオブジェクトの上書きだが、オンメモリdbのレコードデータと読み出したデータは確実に別インスタンスになるように全面ディープコピーするかリードオンリーにするしかない

2017-08-11 16:24:40
汝、翼を与える@ばってん先に翼ばくれんね イベント・・(parody) @ryunosinfx

ここでES2015のゲッターセッターを利用すれば良いと。ただし、継承挟んでも美しくコードが決まるかは微妙。内部的にはjsオブジェクトに持たせて、各プロパティはリードオンリーで構成されて、セッターで書き込む際に書き込みデータプロパティに値が設定されると。で書き込みカウンターをアップ

2017-08-11 16:29:42
汝、翼を与える@ばってん先に翼ばくれんね イベント・・(parody) @ryunosinfx

コミット時にコミットカウンターを同じ値にすると。書き込みイベントをセッター投入時に非同期でキックして、キューにいれてもらうと。イベントハンドラーが1トランザクションごとに処理をすると。トランザクション実行中は無視をして1トランザクションが終わればキューを覗いて有れば再度反映処理

2017-08-11 16:38:15
汝、翼を与える@ばってん先に翼ばくれんね イベント・・(parody) @ryunosinfx

もちろん反映処理にはオンメモリへの反映も含む。結構重い処理になりそう。読み込みまで待つので。

2017-08-11 16:42:00
汝、翼を与える@ばってん先に翼ばくれんね イベント・・(parody) @ryunosinfx

あんまり深く参照ツリーを構築やるとハイバネートの悪夢が蘇るな。友達の友達をみんな連れてメモリロードされるんだけど多すぎて時間はかかるは、最悪メモリ不足で死亡する。

2017-08-11 16:47:46
汝、翼を与える@ばってん先に翼ばくれんね イベント・・(parody) @ryunosinfx

あとは部分読み込み実施したときに、参照だけを入れ替えるかという話をするならエンティティの中で実データと分けるという構造にして本体の参照を持ったまま中身はすげ替えられるようにしないと辛いな。

2017-08-11 17:41:35
汝、翼を与える@ばってん先に翼ばくれんね イベント・・(parody) @ryunosinfx

ここで話しているのは、あれね変数渡しをORマッパーからビジネスロジックにしたさいに、ビジネスロジックが読みだす値が同期を取った後の値にシームレスに切り替わる必要が合って、ビジネスロジック側で値の中の参照値を取得した際も同じ。ただ、流石にプリミティブな連中は無視していいと思う。

2017-08-12 23:51:44
汝、翼を与える@ばってん先に翼ばくれんね イベント・・(parody) @ryunosinfx

これはGetterで必ずEntityクラスのインスタンスを渡すことで解消できるのか?出来るのならビジネスロジックは一切気にしなくて良くなる。値を入れれば、必ずレイジーコミットでDBに入るし、今参照しているレコードも勝手に最新情報に切り替わっているし。

2017-08-12 23:56:07
汝、翼を与える@ばってん先に翼ばくれんね イベント・・(parody) @ryunosinfx

需要として、Entityがスレット1で更新予約がかかった直後に、スレッド2で同じレコードに更新予約がかかる状況で、更新した値を参照して後続の処理を行うというのはあるのだろうか。あるよなぁ・・・トランザクション区間内では更新値は別腹にして参照時にはそっち見るようにする必要があるか

2017-08-13 00:01:55
汝、翼を与える@ばってん先に翼ばくれんね イベント・・(parody) @ryunosinfx

トランザクション区間であるかはフラグで管理すれば良くて、問題はない。その間別腹から、更新前変更データから値を引っ張ってくれば良い。なのでさしたる問題ではない。

2017-08-13 13:26:08
汝、翼を与える@ばってん先に翼ばくれんね イベント・・(parody) @ryunosinfx

なのでトランザクション開始と終了の管理、もし一度でもトランザクション対象になったエンティティからトランザクション終了後に値を参照しようとしたら実行時例外を投げて不遜な使い方を戒める処理が必要ではあるね。もう一回問い合わせ投げろと。嫌ならトランザクション区間内で対象完了しろと。

2017-08-13 13:29:37
汝、翼を与える@ばってん先に翼ばくれんね イベント・・(parody) @ryunosinfx

じゃあ何を以てトランザクション区間とするか。トランザクションインスタンスを生成時に対象エンティティインスタンスを登録する方法を取るべきなのか?それともトランザクションインスタンスを通してエンティティを召喚したら良いのか?c#等では透過的に対象選定が可能だがjsはなぁ

2017-08-13 13:33:22
汝、翼を与える@ばってん先に翼ばくれんね イベント・・(parody) @ryunosinfx

仮に透過的に対象を決めるとして実際にselect処理を行うEntitymanagerはどうやってそのスレッドを特定する?毎回引数でトランザクションインスタンスを渡すのか?だったらトランザクションインスタンスがエンティティマネージャーのラッパーで同じ処理をできた方が合理的ではあるな

2017-08-13 13:39:08
汝、翼を与える@ばってん先に翼ばくれんね イベント・・(parody) @ryunosinfx

トランザクションインスタンスが書き込みを命じると同期的にdb反映が実施される。 まずキューにトランザクションが登録され、トランザクションは書き込み読み込み不可にされる。 それをdb反映者が登録し、オンメモリdbと同期まで行う。db反映者は必ず1スレッドで作動する。

2017-08-13 13:43:33
汝、翼を与える@ばってん先に翼ばくれんね イベント・・(parody) @ryunosinfx

まあjsで1スレッド制約は実行先インスタンスを生成タイミングで存在するかいなかでジャッジするしかないけ。先にキューに登録し存在したらそのまま抜ける、存在しなければ生成して実行をすると。じゃあ2個インスタンスが存在したら?条件によってはあり得るので考えないと。バージョンか?

2017-08-13 14:25:42
汝、翼を与える@ばってん先に翼ばくれんね イベント・・(parody) @ryunosinfx

シビアな状況で2個あった場合、実行前に自分の真名を書き込む。通常終了する場合、キューに何もない場合はこの真名を削除するとする。ミリ秒で見分けがつくのか?そのまま実行させて良い?レイテンンシーがミリ秒でつくならだいぶ楽になるがインスタンス生成まではjsの中である。

2017-08-13 14:37:00
汝、翼を与える@ばってん先に翼ばくれんね イベント・・(parody) @ryunosinfx

まあ既に先行スレッドの名前があれば自分は起動を諦めるというのは順当なのかもしれない。jsは関数呼び出しでコンテキストスイッチが走るので名前を確認した瞬間に終了ロジックが入る可能性がある。名前確認あれば、キュー確認、キューがあれば再度名前確認で名前がなければ実行という順か?

2017-08-13 17:08:30
汝、翼を与える@ばってん先に翼ばくれんね イベント・・(parody) @ryunosinfx

こうしたDBMSあちこちで使いまわしたいので、別モジュールで切り出すか。ライセンスはAGPLv3で。なんか特許踏んでそうな気がしないわけでもないし。

2017-08-13 17:11:26