1 ==========================
2 Listener Dependency Helper
3 ==========================
5 https://git.opendaylight.org/gerrit/#/q/topic:ListenerDepedencyHelper
7 Listener Dependency Helper makes "Data Store Listeners" independent from dependency
12 When a DataStore-Listener is fired with config add/update/delete event, as
13 part of listener processing it may try to read the other data store objects,
14 at times those datastore objects are not yet populated. In this scenario,
15 listener event processing has to be delayed (or) discarded, as the required
16 information is NOT entirely available. Later when the dependant data objects
17 are available, this listener event will not be triggered again by DataStore.
19 This results in some events not getting processed resulting in possible
20 data-path, bgp control and data plane failures.
22 **Example**: VpnInterface add() callback triggered by MD-SAL on vpnInterface
23 add. While processing add() callback, the corresponding vpnInstance is
24 expected to be present in MD-SAL operational DS; which means that vpnInstance
25 creation is complete (updating the vpn-targets in Operational DS and BGP).
28 Information: vpnInstance Config-DS listener thread has to process vpnInstance
29 creation and update vpnInstance in operational DS. vpnInstance creation
30 listener callback is handled by different listener thread.
34 **Use Case 1:** VPNInterfaces may get triggered before VPNInstance Creation.
36 Current implementation: Delay based waits for handling VPNInterfaces that may
37 get triggered before VPNInstance Creation(waitForVpnInstance()).
39 **Use Case 2:** VPNManager to handle successful deletion of VPN which has a
40 large number of BGP Routes (internal/external):
42 Current implementation: Delay-based logic on VPNInstance delete in
43 VPNManager (waitForOpRemoval()).
45 **Use Case 3:** VpnSubnetRouteHandler that may get triggered before VPNInstance
48 Current implementation: Delay based waits in VpnSubnetRouteHandler which may
49 get triggered before VPNInstance Creation(waitForVpnInstance()).
51 **Use Case 4:** VPN Swaps (Internal to External and vice-versa)
53 Current implementation: Currently we support max of 100 VM’s for swap
54 (VpnInterfaceUpdateTimerTask, waitForFibToRemoveVpnPrefix()).
58 During Listener event call-back (AsyncDataTreeChangeListenerBase) from
59 DataStore, check for pending events in "Listener-Dependent-Queue" with
60 same InstanceIdentifier to avoid re-ordering.
62 Generic Queue Event Format:
63 ---------------------------
64 key : Instance Identifier
65 eventType : Type of event (ADD/UPDATE/DELETE)
66 oldData : Data before modification (for Update event);
67 newData : Newly populated data
68 queuedTime : at which the event is queued to LDH.
69 lastProcessedTime : latest time at which dependency list verified
70 expiryTime : beyond which processing for event is useless
71 waitBetweenDependencyCheckTime : wait time between each dependency check
72 dependentIIDs : list of dependent InstanceIdentifiers
73 retryCount : max retries allowed.
74 databroker : data broker.
75 deferTimerBased : flag to choose between (timer/listener based).
77 For Use Case - 1: deferTimerBased shall be set to TRUE (as per the specification).
79 During processing of events (either directly from DataStore or from
80 "Listener-Dependent-Queue"), if there any dependent objects are yet to
81 populated; queue them to "Listener-Dependent-Queue".
83 Expectations from Listener: Listener will push the callable instance to
84 "Listener-Dependent-Queue" if it cannot proceed with processing of the
85 event due to dependent objects/InstanceIdentifier and list of dependent IID's.
87 There are two approaches the Listener Dependency check can be verified.
89 **approach-1** Get the list of dependent-IID's, query DataStore/Cache for
90 dependency resolution at regular intervals using "timer-task-pool". Once
91 all the dependent IID's are resolved, call respective listener for
94 LDH-task-pool : pool of threads which query for dependency resolution READ
95 ONLY operation in DataStore. These threads are part of LDH common for all
98 hasDependencyResolved(<InstanceIdentifier iid, Boolean shouldDataExist,
99 DataStoreType DSType> List), this shall return either Null list (or) the list
100 which has dependencies yet to be resolved. In case Listener has local-cache
101 implemented for set of dependencies, it can look at cache and identify. This
102 api will be called from LDH-task-pool of thread(s).
104 instanceIdentifier is the MD-SAL key value which need to be verified for
105 existence/non-existence of data.
106 Boolean shouldDataExist: shall be TRUE, if the Listener expects to have the
107 information exists in MD-SAL; False otherwise.
109 **approach-2** Register Listener for wild-card path of IID's.
111 When a Listener gets queued to ""Listener-Dependent-Queue", LDH shall register
112 itself as Listener for the dependent IID's (using wild-card-path/parent-node).
113 Once the listener gets fired, identify the dependent listeners waiting for the
114 Data. Once the dependent Listener is identified, if the dependent-IID list is
115 NULL. Trigger listener for processing the event.
116 LDH-task-pool shall unregister itself from wild-card-path/parent-node once there
117 are no dependent listeners on child-nodes.
121 The following scenario, when re-ordering can happen and avoidance of the same:
123 Example: Key1 and Value1 are present in MD-SAL Data Store under Tree1, SubTree1
124 (for say). Update-Listener for Key1 is dependent on Dependency1.
126 Key1 received UPDATE event (UPDATE-1) with value=x, at the time of processing
127 UPDATE-1, dependency is not available. So Listener Queued ‘UPDATE-1’ event to
128 “UnProcessed-EventQueue”.
129 same key1 received UPDATE event (UPDATE-2) with value=y, at the time of
130 processing UPDATE-2, dependency is available (Dependency1 is resolved), so it
131 goes and processes the event and updates value of Key1 to y.
133 After WaitTime, event Key1, UPDATE-1 is de-queued from “UnProcessed-EventQueue”
134 and put for processing in Lister. Listener processes it and updates the Key1
135 value to x. (which is incorrect, happened due to re-ordering of events).
137 To avoid reordering of events within listener, every listener call back shall
138 peek into “UnProcessed-EventQueue” to identify if there exists a pending event
139 with same key value; if so, either suppress (or)
140 queue the event. Below are event ordering expected from MD-SAL and respective
143 **what to consider before processing the event to avoid re-ordering of events:**
145 +-----------------------------------------------------------------+
146 | Current Event| Queued Event| Action |
147 +-----------------------------------------------------------------+
148 | ADD | ADD | NOT EXPECTED |
149 +-----------------------------------------------------------------+
150 | ADD | REMOVE | QUEUE THE EVENT |
151 +-----------------------------------------------------------------+
152 | ADD | UPDATE | NOT EXPECTED |
153 +-----------------------------------------------------------------+
154 | UPDATE | ADD | QUEUE EVENT |
155 +-----------------------------------------------------------------+
156 | UPDATE | UPDATE | QUEUE EVENT |
157 +-----------------------------------------------------------------+
158 | UPDATE | REMOVE | NOT EXPECTED |
159 +-----------------------------------------------------------------+
160 | REMOVE | ADD | SUPPRESS BOTH |
161 +-----------------------------------------------------------------+
162 | REMOVE | UPDATE | EXECUTE REMOVE SUPPRESS UPDATE |
163 +-----------------------------------------------------------------+
164 | REMOVE | REMOVE | NOT EXPECTED |
165 +-----------------------------------------------------------------+
179 Clustering considerations
180 -------------------------
181 In the two approaches mentioned:
182 1 - Timer: polling MD-SAL for dependency resolution may incur in more
185 2 - RegisterListener: RegisterListener may some impact at the time of
186 registering listener after which a notification message to cluser nodes.
188 Predifined List of Listeners
189 ----------------------------
190 operational/odl-l3vpn:vpn-instance-op-data/vpn-instance-op-data-entry/*
191 operational/odl-l3vpn:vpn-instance-op-data/vpn-instance-op-data-entry/
192 vpn-id/vpn-to-dpn-list/*
193 config/l3vpn:vpn-instances/*
196 Other Infra considerations
197 --------------------------
199 Security considerations
200 -----------------------
203 Scale and Performance Impact
204 ----------------------------
205 this infra, shall improve scaling of application without having to wait for
206 dependent data store gets populated.
207 Performance shall remain intact.
215 - use polling/wait mechanisms
226 CLI will be added for debugging purpose.
235 Siva Kumar Perumalla (sivakumar.perumalla@ericsson.com)
267 IID: InstanceIdentifier