Nodejs concurrency readers / writers

Here is some simple code demonstrating what I'm trying to do

myVar = 1
reader = () ->
    getDataFromServer1().then ->
        # uses myVar and does stuff according to its value
    # returns promise
writer = () ->
    getDataFromServer2().then ->
        # assigns to myVar
    # returns promise

Q.all([reader(), reader(), reader(), writer(), writer(), writer()]).done ->
    console.log 'done'

So, I have several threads working at the same time. some of them change meaning myVar, and some read and rely on meaning. And I do not want the writer to write when another writer wrote, or the reader is reading. Readers can read at the same time. This is similar to the Reader / Writer issue .

I tried to solve this problem by defining a function sharedResourceas follows

sharedResource = (initialValue) ->
    readLock = Q.fcall ->
    writeLock = Q.fcall ->

    value: initialValue
    read: (action) ->
        newPromise = writeLock.then action
        readLock = Q.all([newPromise, readLock]).then -> null
        newPromise
    write: (action) ->
        newPromise = Q.all([readLock, writeLock]).then action
        writeLock = Q.all([newPromise, writeLock]).then -> null
        newPromise

and then changed my code to use it

myVar = sharedResource 1
reader = () ->
    myVar.read ->
        # noone is writing to myVar while doing this request:
        getDataFromServer1().then (data) -> 
            # read myVar.value instead of myVar, e.g.
            expect(data == myVar.value)
writer = () ->
    myVar.write ->
        # noone reads or writes myVar while doing this request:
        getDataFromServer2().then (data) ->
            # change myVar.value instead of myVar, e.g.
            myVar.value = data

Q.all([reader(), reader(), reader(), writer(), writer(), writer()]).done ->
    console.log 'done'

This worked perfectly when I only had one sharedResource. Here where the problem arises

myVar1 = sharedResource 1
myVar2 = sharedResource 2
action1 = () ->
    myVar1.read ->
        myVar2.write ->
            getDataFromServer1().then (data) ->
                myVar2.value = data + myVar1.value
action2 = () ->
    myVar2.read ->
        myvar1.write ->
            getDataFromServer2().then (data) ->
                myVar1.value = data + myVar2.value

Q.all([action1(), action1(), action1(), action2(), action2(), action2()]).done ->
    console.log 'done'

deadlock. . , .

Edit

:

. , , . , , , action1 , , . (, ) , , . , action2 , , assert , .

, , , action2 .

, .

+4

All Articles