2014-01-20 2 views
5

때때로 Meteor.call을 writeMeLater에 대기 시켜서 동 기적으로 실행해야합니다 (동일한 클라이언트의 writeMeLater에 대한 다른 호출을 차단).Meteor.methods 동기 및 비동기 확인

다른 번에 writeMeLater에 대한 호출은 현재 대기중인 모든 호출 뒤에 대기열없이 가능한 빨리 실행되어야합니다.

다음은 매개 변수가 true 인 경우 this.unblock()을 사용하여 시도한 것입니다. 케이스 1과 2는 잘 작동합니다. 그러나 사례 3의 경우 async=true이 포함 된 통화가 async=false과 통화 대기 중입니다. async=true으로 전화를 걸려면 어떻게해야합니까? 이

모든 Meteor.call()

은 클라이언트에서 만든 첫 번째 클라이언트에서 호출 후 대기하지 않는 두 번째 클라이언트에서 호출하는 방법과 유사합니다

사례 1 (정확하게 동기) :

Meteor.call('writeMeLater', 's', false) 
Meteor.call('writeMeLater', 's', false) 
Meteor.call('writeMeLater', 's', false) 

케이스 2 (정확하게 비동기)

Meteor.call('writeMeLater', 'a', true) 
Meteor.call('writeMeLater', 'a', true) 
Meteor.call('writeMeLater', 'a', true) 
,174,

사례 3 (하지 원하는 동작)

Meteor.call('writeMeLater', 's', false) 
Meteor.call('writeMeLater', 's', false) 
Meteor.call('writeMeLater', 's', false) 

Meteor.call('writeMeLater', 'a', true) 
Meteor.call('writeMeLater', 'a', true) 
Meteor.call('writeMeLater', 'a', true) 

서버/main.js

writeMeLater = function(data, callback) { 
    console.log('writeMeLater: ', data) 

    // simulate taking 3 second to complete 
    Meteor.setTimeout(function() { 
     Logs.insert({data: data, timestamp: new Date().getTime()}) 
     console.log('Log.insert: ', data) 
     callback(null, 'done') 
    }, 3 * 1000) 
} 



writeMeLaterSync = Meteor._wrapAsync(writeMeLater) 



Meteor.methods({ 

    writeMeLater: function(data, async) { 
     if(async) 
      this.unblock() 

     writeMeLaterSync(data) 
    } 

}) 
+0

무엇을 기대합니까? – imslavko

+0

@imslavko 다른 클라이언트의 메서드 호출이 첫 클라이언트의 호출 뒤에 대기열에 넣지 않는 것과 비슷하게 일부 메서드 호출을 대기열에 넣지 않고 즉시 실행할 수 있습니까 – Nyxynyx

+0

정확히 this.unblock() 'call will do - 이전 연결이 완료되기 전에 * start *에 대한 현재 연결을 다른 메서드 호출로 허용합니다. 그것이 내가 본 결과입니다 : http://pastebin.com/gtdgLTGf 그리고 나에게 맞는 것 같습니다. 3 회의 동기 호출의 경우 호출이 완료되기 전에 3 초의 지연이 있습니다. 두 번째 일괄 처리를 위해 - 그들은 모두 같은 시간에 시작하여 3 초 후에 끝납니다. – imslavko

답변

2

내 첫번째 생각은 왜 안 실제로 는 큐를 생성한다? 대기열로 JavaScript 이벤트 루프를 사용하는 대신. 다음과 같이 해당 대기열에 문서를 삽입 :

WritesQueue = new Meteor.Collection("WritesQueue"); 
WritesQueue.insert({data: 'a', prioritize: true, inserted: new Date()}); 

그리고 어쩌면 때마다 당신은 우선 순위가 높은 쓰기를 삽입 첫째가는 우선 순위 (비 비동기) 사람과 큐를 처리 Meteor.call("write")을, 트리거 :

Meteor.methods({ 
    write: function() { 
    WritesQueue.find({prioritize: true}, {sort: {inserted: 1}}) 
    .forEach(function (doc) { 
     console.log(doc.data); 
     WritesQueue.remove(doc._id); 
    }); 
    WritesQueue.find({prioritize: false}, {sort: {inserted: 1}}) 
    .forEach(function (doc) { 
     console.log(doc.data); 
     WritesQueue.remove(doc._id); 
    }); 
    } 
}); 

높은 우선 순위 또는 낮은 우선 순위의 쓰기를 삽입 할 때마다 큐를 처리하려면 write 메서드를 호출하거나 insert 메서드를 write 메서드 내부에 배치하십시오. 쓰기는 여전히 클라이언트 당 동 기적으로 처리되지만 이것은 헤드 - 오브 - 더 - 줄 문제에 대한 해결을 해결합니다.

단일 클라이언트에 대해 병렬 처리를 수행하려는 경우 @imslavko (위의 질문에 대한 설명에 있음)는 정확합니다. 클라이언트가 여러 DDP 연결을 설정하는 한 가지 방법입니다.

정의, 서버 측 경로 Iron Router를 설치하고 서버 코드 :

Router.map(function() { 
    this.route('writeMeLater', { 
    where: 'server', 
    action: function() { 
     Meteor.call('writeMeLater', 
     this.request.query.data, this.request.query.async); 
    } 
    }); 
}); 

위의 this.request.query을 대상으로이되는 할 수있는 상대적으로 해키이기는하지만, 간단하고 비의 유성, 방법이 요청과 함께 제출 한 키 - 값 쌍입니다.예를 들어 그것은 새로운 섬유 (즉, 나사)에서 처리 될 수 있도록

HTTP.post("http://yoursite.com/writeMeLater", 
    {params: {data: 'a', async: true}}); 

는 멀리 서버가 알고있는 바와 같이,이 요청은 새로운 클라이언트로부터오고있다. writeMeLater 메서드가 대기하지 않는 경우 많은 인스턴스가 동시에 실행될 수 있습니다. 이제 HTTP POST 요청이 반드시 서버와 동일한 순서로 서버에 도착하지 않을 수 있기 때문에 서버에서의 실행 순서가 클라이언트에서와 동일하다는 것이 중요하다면 문제는 순서대로 유지됩니다. 보냈습니다. 그러나이를 처리하는 다양한 방법이 있습니다 (일괄 처리로 보내거나 카운터를 포함하고 순서가 잘못된 요청을 발견하면 서버가 몇 초 동안 기다리게하십시오).