1POE::Queue(3) User Contributed Perl Documentation POE::Queue(3)
2
3
4
6 POE::Queue - a flexible, generic priority queue API
7
9 POE::Queue specifies additional methods not illustrated here.
10
11 #!perl
12
13 use warnings;
14 use strict;
15 use POE::Queue::Array;
16
17 my $pqa = POE::Queue::Array->new();
18
19 # Enqueue a few items.
20
21 foreach my $priority (505, 404, 303, 202, 101) {
22 $pqa->enqueue($priority, "payload $priority");
23 }
24
25 # Dequeue until the queue is drained.
26
27 while (1) {
28 my ($priority, $queue_id, $payload) = $pqa->dequeue_next();
29 last unless defined $priority;
30
31 print(
32 "dequeued id($queue_id) ",
33 "priority($priority) ",
34 "payload($payload)\n",
35 );
36 }
37
38 Sample output:
39
40 dequeued id(5) priority(101) payload(payload 101)
41 dequeued id(4) priority(202) payload(payload 202)
42 dequeued id(3) priority(303) payload(payload 303)
43 dequeued id(2) priority(404) payload(payload 404)
44 dequeued id(1) priority(505) payload(payload 505)
45
47 Priority queues may be implemented a number of ways, but they tend to
48 behave similar to lists that are kept in order by some kind of
49 "priority". Enqueued items are stored such that the "next" item to be
50 retrieved is the one with the highest priority. Subsequent fetches
51 return the next lowest priority, and so on, until the queue is emptied.
52
53 Priority queues (also known as priority heaps) attempt to do this while
54 consuming the fewest resources. Go read about it! It's fascinating
55 stuff!
56
57 POE::Queue Items
58 POE::Queue items consist of three fields: A priority, a unique ID
59 assigned at enqueue time, and a payload. The priority and payload are
60 specified by the caller, and the unique ID is generated by POE::Queue
61 when an item is enqueued.
62
63 POE::Queue imposes two limitations on priorities: Priorities must be
64 numeric, and lower numbers indicate higher priorities. Aside from
65 that, POE::Queue doesn't care what the numbers mean.
66
67 Unique IDs are handles into the queue. POE::Queue generates and
68 returns them as new items are enqueued. Some methods manipulate items,
69 and they take IDs to identify the items to alter.
70
71 Item payloads are arbitrary application data. POE::Queue does not
72 examine or alter payloads itself. Any methods that need to examine
73 payloads will accept a filter function. Filter functions examine
74 payloads so POE::Queue need not.
75
77 POE::Queue is an API specification. Subclasses like POE::Queue::Array
78 provide actual implementations.
79
80 new
81 Creates a new priority queue. Returns a reference to the queue.
82
83 my $queue = POE::Queue::Array->new();
84
85 enqueue PRIORITY, PAYLOAD
86 Enqueues a PAYLOAD, which can be just about anything that will fit into
87 a Perl scalar, at a particular PRIORITY level. enqueue() returns a
88 unique ID which can be used to manipulate the payload or its priority
89 directly.
90
91 Following the UNIX tradition, lower priority numbers indicate higher
92 priorities. The payload with the lowest priority number will be
93 dequeued first. If two payloads have the same PRIORITY, then they will
94 be dequeued in the order in which they were enqueued.
95
96 In this example, a queue is used to manage a number of alarms. The
97 "next" alarm will be the one due soonest.
98
99 my $payload_id = $queue->enqueue($alarm_time, [ "stuff" ]);
100
101 dequeue_next
102 Removes the next item from the queue, returning it as three fields:
103 priority, ID and payload.
104
105 The "next" item is the one with the lowest priority number. If
106 multiple items exist with the same priority, dequeue_next() will return
107 the one that was given the priority first.
108
109 ITEM: while (1) {
110 my ($priority, $id, $payload) = $queue->dequeue_next();
111 last ITEM unless defined $priority;
112 ...;
113 }
114
115 get_next_priority
116 Returns the priority of the item at the head of the queue. This is the
117 lowest numeric priority in the queue.
118
119 get_next_priority() can be useful for checking the queue to see if it's
120 time to dequeue some items. In this case, the queue manages multiple
121 alarms, and there's nothing to do if the next alarm isn't due yet.
122
123 ALARM: while (1) {
124 my $next_alarm_time = $queue->get_next_priority();
125 last ALARM unless defined $next_alarm_time;
126
127 if ($next_alarm_time - time() > 0) {
128 sleep($next_alarm_time - time());
129 }
130
131 my ($priority, $id, $payload) = $queue->dequeue_next();
132 ...;
133 }
134
135 get_item_count
136 Returns the number of items in the queue. It's another way to tell
137 whether the queue has been fully drained. Here's an alternative
138 version of the example for get_next_priority().
139
140 ALARM: while ($queue->get_item_count()) {
141 my $next_alarm_time = $queue->get_next_priority();
142 if ($next_alarm_time - time() > 0) {
143 sleep($next_alarm_time - time());
144 }
145
146 my ($priority, $id, $payload) = $queue->dequeue_next();
147 ...;
148 }
149
150 remove_item ITEM_ID, FILTER_FUNCTION
151 Removes a single item by its ID, but only if a FILTER_FUNCTION approves
152 of the item's payload.
153
154 If a payload is found with the given ITEM_ID, it is passed to
155 FILTER_FUNCTION for examination. If FILTER_FUNCTION returns true, the
156 item is removed from the queue and is returned as three fields.
157
158 my ($priority, $id, $payload) = $queue->remove_item(
159 $target_id, \&monkeys
160 );
161
162 sub monkeys {
163 my $payload = shift;
164 $payload->{type} eq "monkey";
165 }
166
167 The returned $priority will be undef on failure, and $! will be set to
168 the reason why the item couldn't be removed. That will be ESRCH if the
169 ITEM_ID was not found in the queue, or EPERM if the filter function
170 returned false.
171
172 remove_items FILTER_FUNCTION [, MAX_ITEM_COUNT ]
173 Removes and returns items from the queue that match a FILTER_FUNCTION.
174 remove_items() will return immediately if MAX_ITEM_COUNT items is
175 specified and that many items have been removed from the queue.
176 MAX_ITEM_COUNT is a bit of optimization if the application knows in
177 advance how many items will match the FILTER_FUNCTION.
178
179 Returns a list of items that were removed. Each item is an array
180 reference containing a priority, item ID, and payload. Returns nothing
181 if FILTER_FUNCTION matched nothing.
182
183 # Remove up to 12 monkeys.
184 my @monkeys = $queue->remove_items(\&monkeys, 12);
185 foreach my $monkey (@monkeys) {
186 my ($priority, $id, $payload) = @$monkey;
187 print(
188 "Removed monkey:\n",
189 " priority = $priority\n",
190 " queue id = $id\n",
191 " payload = $payload\n",
192 );
193 }
194
195 There is no guarantee which items will be removed if MAX_ITEM_COUNT is
196 specified too low.
197
198 peek_items FILTER_FUNCTION [, MAX_ITEM_COUNT ]
199 peek_items() returns up to MAX_ITEM_COUNT items that match a given
200 FILTER_FUNCTION without removing them from the queue.
201
202 my @entire_queue = $queue->peek_items(sub { 1 });
203 foreach my $item (@entire_queue) {
204 my ($priority, $id, $payload) = @$item;
205 print(
206 "Item:\n",
207 " priority = $priority\n",
208 " queue id = $id\n",
209 " payload = $payload\n",
210 );
211 }
212
213 adjust_priority ITEM_ID, FILTER_FUNCTION, DELTA
214 Changes the priority of an item by DELTA. The item is identified by
215 its ITEM_ID, and the change will only happen if the item's payload
216 satisfies a FILTER_FUNCTION. Returns the new priority, which is the
217 previous priority + DELTA. DELTA may be negative.
218
219 my $new_priority = $queue->adjust_priority(
220 $item_id, \&one_of_mine, 100
221 );
222
223 sub one_of_mine {
224 my $payload = shift;
225 return $payload->{owner} == $me;
226 }
227
228 Returns undef if the item's priority could not be adjusted, and sets $!
229 to explain why: ESRCH means that the ITEM_ID could not be found, and
230 EPERM means that the FILTER_FUNCTION was not satisfied.
231
232 set_priority ITEM_ID, FILTER_FUNCTION, ABSOLUTE_PRIORITY
233 Sets an item's priority to a new ABSOLUTE_PRIORITY. The item is
234 identified by its ITEM_ID, and the change will only be allowed to
235 happen if the item's payload satisfies a FILTER_FUNCTION. Returns the
236 new priority, which should match ABSOLUTE_PRIORITY.
237
238 Returns undef if the item's priority could not be set, and sets $! to
239 explain why: ESRCH means that the ITEM_ID could not be found, and EPERM
240 means that the FILTER_FUNCTION was not satisfied.
241
242 my $new_priority = $queue->set_priority(
243 $item_id, \&one_of_mine, time() + 60
244 );
245
246 unless (defined $new_priority) {
247 die "one of our submarines is missing: $item_id" if $! == ESRCH;
248 die "set_priority disallowed for item $item_id" if $! == EPERM;
249 die $!;
250 }
251
252 sub one_of_mine {
253 $_[0]{owner} == $me;
254 }
255
257 POE, POE::Queue::Array
258
260 None known.
261
263 Please see POE for more information about authors, contributors, and
264 POE's licensing.
265
266
267
268perl v5.34.0 2021-07-22 POE::Queue(3)