Class: Splib::PriorityQueue

Inherits:
Object
  • Object
show all
Defined in:
lib/splib/PriorityQueue.rb

Overview

This class provides some simple logic for item output. It is basically a priority based queue with some round robin thrown in to keep things interesting. This queue provides an easy way for many threads to populate it without drowning out each other. NOTE: Design help from the great Ryan “pizza_” Flynn

Instance Method Summary collapse

Constructor Details

#initialize(*args, &whocares) ⇒ PriorityQueue

args

config arguments

:raise_on_empty
whocares

lambda{|target| true||false}

Create a priority queue



17
18
19
20
21
22
23
# File 'lib/splib/PriorityQueue.rb', line 17

def initialize(*args, &whocares)
    @raise = args.include?(:raise_on_empty)
    @whocares = whocares
    @target_queues = {}
    @queues = {:PRIORITY => [], :NEW => [], :NORMAL => [], :WHOCARES => []}
    @lock = Mutex.new
end

Instance Method Details

#direct_queue(message) ⇒ Object

item

item to queue

This will add item to the PRIORITY queue which gets sent before all other items.



52
53
54
55
56
57
58
59
# File 'lib/splib/PriorityQueue.rb', line 52

def direct_queue(message)
    @lock.synchronize do
        @target_queues[:internal_prio] = [] unless @target_queues[:internal_prio]
        @target_queues[:internal_prio] << message
        add_queue(:PRIORITY, @target_queues[:internal_prio])
    end
    message
end

#empty?Boolean

Returns true if queue is empty

Returns:

  • (Boolean)


85
86
87
# File 'lib/splib/PriorityQueue.rb', line 85

def empty?
    @lock.synchronize{@target_queues.values.find{|n|!n.empty?}.nil?}
end

#popObject

raise_e

raise an exception on empty

Returns the next message to send. This method decides what message to send based on the priority of the message. It will throw an Exceptions::EmptyQueue when there are no messages left.

Raises:



66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
# File 'lib/splib/PriorityQueue.rb', line 66

def pop
    m = nil
    @lock.synchronize do
        [:PRIORITY, :NEW, :NORMAL, :WHOCARES].each do |k|
            unless(@queues[k].empty?)
                q = @queues[k].shift
                unless(q.empty?)
                    m = q.shift
                    add_queue(k, q) unless(q.empty?)
                    break
                end
            end
        end
    end
    raise EmptyQueue.new('Queue is currently empty') if m.nil? && @raise
    return m
end

#prioritized_queue(target, item) ⇒ Object Also known as: push

target

target queue

item

item to queue

This prioritizes output to help reduce lag when lots of output is being sent to another target. This will automatically decide how to queue the item based on the target

Raises:

  • (NameError)


30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
# File 'lib/splib/PriorityQueue.rb', line 30

def prioritized_queue(target, item)
    raise NameError.new('The target :internal_prio is a restricted target') if target == :internal_prio
    @lock.synchronize do
        @target_queues[target] = [] unless @target_queues[target]
        if(@whocares && @whocares.call(target))
            @target_queues[target] << item
            add_queue(:WHOCARES, @target_queues[target])
        else
            @target_queues[target] << item
            if(@target_queues[target].size < 2)
                add_queue(:NEW, @target_queues[target])
            else
                add_queue(:NORMAL, @target_queues[target])
            end
        end
    end
    item
end