2015-12-20 58 views
2

我需要實現優先級隊列node.jsSQS。這是我第一次與SQS,所以我想聽聽你的意見。節點SQS優先級隊列

我有3個工作重點:p0,p1和p2,p0是最高的。 p2是最常見的,之後是p0,最後是p1。在數字我可以粗略地說,它是:

p2 ~= 5p0 
p0 >> p1 

他們都是獨立作業,以便執行它們的順序並不重要。

我想出了2個可能的解決方案(這些只是草圖,並不真正運行)。

共同

兩者

var _ = require('lodash'), 
    Promise = require('bluebird'), 
    sqs = require('some-sqs-module'); 

... 

module.exports.getJob = function() { 
    return getJobByQueuePriority(0); 
    // or... 
    return getJobByJobPriority(0); 
} 

溶液1

使用3個隊列,每個優先級之一。樣品從每個隊列1個工作的優先級進行

var Queues = [p0url, p1url, p2url], 
    currentQueueIndex = 0; 

function getJobByQueuePriority(priority) { 
    return new Promise(function(resolve, reject) { 

     var queueUrl = getNextQueue(priority); 

     if(!_.isEmpty(queueUrl)){ 
      sqs.pullOne(queueUrl) 
       .then(function (job) { 
        // recursive promises??? 
        return job ? resolve(job) : getJobByQueuePriority(priority + 1); 
       }) 
       .catch(function (err) { 
        reject(err); 
       }); 
     } 
    }); 
} 

function getNextQueue(index) { 
    return index >= Queues.length ? '' : Queues[index]; 
} 

解決方案2

使用1隊列,並從中收集k任務,然後選擇排名最高的工作。

var QUEUE_URL = 'some/sqs/url', 
    JOBS_TO_PULL = 10; 

function getJobByJobPriority (priority) { 
    return new Promise(function (resolve, reject) { 
     sqs.pullMultiple(QUEUE_URL, JOBS_TO_PULL) 
      .then(function (jobs) { 
       var job = getHighestPriorityJob(jobs); 
       resolve(job); 
      }) 
      .catch(function (err) { 
       reject(err); 
      }); 
    }); 
} 

function getHighestPriorityJob(jobs) { 
    var highest = jobs[0]; 

    _.each(jobs, function (job) { 
     if(job.priority < highest.priority){ 
      highest = job; 
     } 

     if(highest.priority == HIGHEST_PRIORITY) break; 
    }); 

    return highest; 
} 

,這裏是我想要的消費者

var pq = require('my-priority-queue'); 

function lookForWork() { 
    pq.getJob() 
     .then(function (job) { 
      job ? work(job) : rest(); 
     }); 
} 

function work(job) { 
    // do your work... 

    // search for more work 
    lookForWork(); 
} 

function rest() { 
    (setTimeout(function() { 
     lookForWork(); 
    }, TIME_TO_REST))(); 
} 

這一切都草圖所以從來不介意小故障,如果你看到他們。

回答

1

每個優先級的不同隊列是最好的方式去imo。它更具可擴展性(例如,如果您需要,您可以添加更多消費者,例如僅處理P2隊列)。

通過一個隊列,每次從隊列中取出消息並且不使用它們時,都會阻止另一個消費者看到它們,直到它們返回。

不確定你的卷是什麼,即使SQS很便宜,閱讀大量的消息,但不使用它們仍然會產生費用。