atori74 / streamsync

Sync timing of streaming simultaneously viewed by host and clients
1 stars 0 forks source link

chrome.storageへの書き込みが競合する場合がある #42

Closed atori74 closed 3 years ago

atori74 commented 3 years ago

ログとかroomの情報とかを非同期にstorageに書き込む実装にしてたが、 初めて書き込みが競合して片方が反映されないという事象がおきた

トランザクションを導入しないといけない

Mutex変数をもって、排他制御をやる

atori74 commented 3 years ago

Semaphoreを導入して、大部分はトランザクションを分離できた

atori74 commented 3 years ago

appendUserLog()がgetStorageとsetStorageに分かれていて、それぞれの中でmutexをロックしてるので合間にほかのタスクが入ってきてしまう

get log 1 get log 2 set log 1 set log 2 上記のそれぞれが排他制御にはなってるが、結局set1が反映されない get-setまでを1トランザクションとしなきゃいけない

atori74 commented 3 years ago

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;
}
atori74 commented 3 years ago

storageからデータをgetして、その内容に変更を加えてsetする という一連のトランザクションに対してロックをかける必要がある

なのでイメージとしては

const release = await sMutex.acquire();
〜 = getStorage(〜);
setStorage(〜);
release();

という感じ

atori74 commented 3 years ago

appendUserLogやrerenderPopupといった関数は、内部でget -> setをやっているので 関数の中でmutexをロック、アンロックしている

なので、上記関数を呼び出す前にmutexをロックする必要はない ※むしろロックしてしまうと、デッドロックを起こすと思う