1.. _use_limiter_node:
2
3Using limiter_node
4==================
5
6
7One way to limit resource consumption is to use a limiter_node to set a
8limit on the number of messages that can flow through a given point in
9your graph. The constructor for a limiter node takes two arguments:
10
11
12::
13
14
15   limiter_node( graph &g, size_t threshold )
16
17
18The first argument is a reference to the graph it belongs to. The second
19argument sets the maximum number of items that should be allowed to pass
20through before the node starts rejecting incoming messages.
21
22
23A limiter_node maintains an internal count of the messages that it has
24allowed to pass. When a message leaves the controlled part of the graph,
25a message can be sent to the decrement port on the ``limiter_node`` to
26decrement the count, allowing additional messages to pass through. In
27the example below, an ``input_node`` will generate ``M`` big objects. But the
28user wants to allow at most three big objects to reach the ``function_node``
29at a time, and to prevent the ``input_node`` from generating all ``M`` big
30objects at once.
31
32
33::
34
35
36     graph g;
37
38
39     int src_count = 0;
40     int number_of_objects = 0;
41     int max_objects = 3;
42
43
44     input_node< big_object * > s( g, [&]( oneapi::tbb::flow_control& fc ) -> big_object* {
45         if ( src_count < M ) {
46           big_object* v = new big_object();
47           ++src_count;
48           return v;
49         } else {
50           fc.stop();
51           return nullptr;
52         }
53     } );
54     s.activate();
55
56     limiter_node< big_object * > l( g, max_objects );
57
58
59     function_node< big_object *, continue_msg > f( g, unlimited,
60       []( big_object *v ) -> continue_msg {
61         spin_for(1);
62         delete v;
63         return continue_msg();
64     } );
65
66
67
68
69     make_edge( l, f );
70     make_edge( f, l.decrement );
71     make_edge( s, l );
72     g.wait_for_all();
73
74
75The example above prevents the ``input_node`` from generating all ``M`` big
76objects at once. The ``limiter_node`` has a threshold of 3, and will
77therefore start rejecting incoming messages after its internal count
78reaches 3. When the ``input_node`` sees its message rejected, it stops
79calling its body object and temporarily buffers the last generated
80value. The ``function_node`` has its output, a ``continue_msg``, sent to the
81decrement port of the ``limiter_node``. So, after it completes executing,
82the ``limiter_node`` internal count is decremented. When the internal count
83drops below the threshold, messages begin flowing from the ``input_node``
84again. So in this example, at most four big objects exist at a time, the
85three that have passed through the ``limiter_node`` and the one that is
86buffered in the ``input_node``.
87
88