Closed atori74 closed 3 years ago
Semaphoreを導入して、大部分はトランザクションを分離できた
appendUserLog()がgetStorageとsetStorageに分かれていて、それぞれの中でmutexをロックしてるので合間にほかのタスクが入ってきてしまう
get log 1 get log 2 set log 1 set log 2 上記のそれぞれが排他制御にはなってるが、結局set1が反映されない get-setまでを1トランザクションとしなきゃいけない
notenoughneon/await-semaphore
node向けのライブラリを参考にsemaphoreを実装 一応MITライセンスのnoticeもソース内に書いといた
下記でmutexのロックができる
var mutex = new Semaphore(1);
async function niceFetch(url) {
var release = await mutex.acquire();
var result = await fetch(url);
release();
return result;
}
storageからデータをgetして、その内容に変更を加えてsetする という一連のトランザクションに対してロックをかける必要がある
なのでイメージとしては
const release = await sMutex.acquire();
〜 = getStorage(〜);
setStorage(〜);
release();
という感じ
appendUserLogやrerenderPopupといった関数は、内部でget -> setをやっているので 関数の中でmutexをロック、アンロックしている
なので、上記関数を呼び出す前にmutexをロックする必要はない ※むしろロックしてしまうと、デッドロックを起こすと思う
ログとかroomの情報とかを非同期にstorageに書き込む実装にしてたが、 初めて書き込みが競合して片方が反映されないという事象がおきた
トランザクションを導入しないといけない
Mutex変数をもって、排他制御をやる