복붙노트

[REDIS] NodeJS 비동기 행동 다루기

REDIS

NodeJS 비동기 행동 다루기

MongoDB를 + 몽구스와 NodeJS를 사용.

우선, 나는 코드를 비 차단 비동기의 장점을 알고있다. 내가 콜백 처리 않습니다 그래서. 그러나 결국 나는 다음과 같은 문제에 직면했다.

나는 언제든지 사용자가 호출 할 수있는 기능을 갖고 있다고 할 수 있습니다. 그리고 그것은 가능한 거의 같은 시간에 두 번 슈퍼 "번개 속도"사용자 호출을 그.

function do_something_with_user(user_id){
    User.findOne({_id:user_id}).exec(function(err,user){ // FIND QUERY
        // Do a lot of different stuff with user
        // I just cannot update user with a single query
        // I might need here to execute any other MongoDB queries
        // So this code is a set of queries-callbacks
        user.save() // SAVE QUERY
    })
}

물론이 같은 실행 : FIND 쿼리, QUERY, SAVE QUERY, SAVE QUERY 찾기

이것은 완전히 응용 프로그램의 논리를 (QUERY, SAVE QUERY 찾기, QUERY, SAVE QUERY를 찾아야한다) 나누기. 나는 (기능 코드는 비동기 여전히 그렇게 내에서) 특정 사용자에 대한 전체 기능을 "잠금"에 의해 비동기 동작을 방지하기로 결정 그래서.

var lock_function_for_user = {}

function do_something_with_user(user_id){
    if(!lock_function_for_user[user_id]){
        lock_function_for_user[user_id] = true
        User.findOne({_id:user_id}).exec(function(err,user){
            // Same code as above
            user.save(function(){
                lock_function_for_user[user_id] = false
            })
        })
    } else {
        setTimeout(function(){
            do_something_with_user(user_id)
        },100) // assuming that average function execution time is 100ms in average
    }
}

그래서, 내 질문은 : 그것은 좋은 연습, 좋은 해킹, 나쁜 해킹? 이 나쁜 해킹의 경우, 다른 솔루션을 제공하십시오. 특히, 우리가 하나 개 이상의 NodeJS 프로세스를 확장하고 시작할 때이 솔루션이 작동합니다 의심한다.

해결법

  1. ==============================

    1.이것은 코드의 흐름을 제어하는 ​​타이머를 사용해서는 안됩니다, 아주 나쁜 방법입니다.

    이것은 코드의 흐름을 제어하는 ​​타이머를 사용해서는 안됩니다, 아주 나쁜 방법입니다.

    문제는 여기에 자성이라고합니다. 당신이 찾을-저장, 발견이-저장해야 할 경우에 당신은 어떻게 든 이러한 작업을 팩 (거래) 할 필요가있다. 그것은 당신이 사용하는 소프트웨어에 따라 달라집니다. 레디 스에서는 멀티 간부 인 명령이 있습니다. MongoDB를 당신이 findAndModify이 (). 또 다른 해결책은 인덱스를 사용하는 것입니다. 같은 필드를 저장하려고하면 두 번 당신이 오류가 발생합니다. 몽구스의 schemaType에서 :와 "진정한 독특한", "진정한 인덱스"속성을 사용하여

    var schema = mongoose.Schema ({
        myField: { type: String, index: true, unique: true, required: true },
    });
    

    이것은 당신이 필요로하는 무엇을 : MongoDB를 - 작업의 분리 순서 - 두 단계 커밋을 수행합니다. 그러나 당신이 거래를 많이 할 필요가있는 경우 MongoDB를가 최선의 선택이 될 수 없다는 것을 고려.

  2. ==============================

    2.당신은 너무 대체, RAM을 낭비하고 싶지 않아

    당신은 너무 대체, RAM을 낭비하고 싶지 않아

    lock_function_for_user[user_id] = false
    

    delete lock_function_for_user[user_id]
    

    그 외에도에서 : 충돌이 발생하는 경우 당신은 낙관적 재시도 될 수있다. 그냥 잠금을두고 DB 고지 물건 (그 경우와 재시도) 잘못되면 있는지 확인하십시오. 방법은 더 나은 같은 충돌이 실제로 발생하는 빈도에 따라 달라집니다 물론,의.

  3. from https://stackoverflow.com/questions/15692946/dealing-with-nodejs-asynchronous-behavior by cc-by-sa and MIT license