2019年9月2日 星期一

Javascrip 應用 Promise 實現一個簡單的 mutex

通常登入帳戶後, context 不能被切換, 萬一執行非同步工作(async function)時, 有可能切換到其它帳戶, 造成 contex 大亂, 解決方式是實現一個 mutual exclusion 機制, 保護 context 順利進行:
// mutexLogin.js
class   Guest {
    constructor(id=0) { this.user = "anonymous" + id  }
}
class   Field {
    constructor(value=false) { this.field = value }
    set  value(v) { this.field = v      }
    get  value( ) { return this.field   }
}
class   Mutex   extends   Field {
    constructor( ) { super();   this.full = false;  }
    get  isLock ( ) { return this.value   } // alias getter
    get  lock   ( ) { this.value = true   } // getter, to set field
    get  unlock ( ) { this.resolve && this.resolve(true) } // getter, to resolver with true
    get  waitUnlock( ) { // getter, to return null when full, or a promise if available.
        if (this.full)  return  null;
        this.full = true; // one promise only, to skip the others.
        return  new Promise( (fullfill, x) => { // a promise
            this.resolve = (value) => { // to define resolver
                this.full  = false;
                this.value = false;
                fullfill(value) ; // to fullfill the promise
            } // end of this.resolve
        }); // end of Promise
    } // end of waitUnlock
} // end of class Mutex
const mutex = new Mutex( );
async   function   anonymousLogin(id) {
    if (mutex.isLock) {
        const  promise = mutex.waitUnlock;
        if (promise == null)   console.log("    -> skip contex for id=" + id);
        else  promise.then( (_) => {
                console.log("Wait so long: "+_);
                anonymousLogin(id); // function recursive to restart again
        });   
    } else {
        const guest = new Guest(id);
        mutex.lock;    // contex to protect
            console.log(guest.user+":");
            await doSomething(); // do some aync task
        mutex.unlock;  // end of contex
    }
}
async   function   doSomething( ) { // async task
    console.log("I am working ...");
    console.log("Done");
}
for(i =0; i<10; i++)   anonymousLogin(i);
執行  js   mutexLogin.js  看結果:
anonymous0:
I am working ...
Done
    -> skip contex for id=2
    -> skip contex for id=3
    -> skip contex for id=4
    -> skip contex for id=5
    -> skip contex for id=6
    -> skip contex for id=7
    -> skip contex for id=8
    -> skip contex for id=9
Wait so long: true
anonymous1:
I am working ...
Done

沒有留言:

張貼留言

使用 pcie 轉接器連接 nvme SSD

之前 AM4 主機板使用 pcie ssd, 但主機板故障了沒辦法上網, 只好翻出以前買的 FM2 舊主機板, 想辦法讓老主機復活, 但舊主機板沒有 nvme 的界面, 因此上網買了 pcie 轉接器用來連接 nvme ssd, 遺憾的是 grub2 bootloader 無法識...