lightstreamer_client/
subscription_listener.rs

1use crate::item_update::ItemUpdate;
2
3/// Interface to be implemented to listen to Subscription events comprehending notifications
4/// of subscription/unsubscription, updates, errors and others.
5///
6/// Events for these listeners are dispatched by a different thread than the one that generates them.
7/// This means that, upon reception of an event, it is possible that the internal state of the client
8/// has changed. On the other hand, all the notifications for a single LightstreamerClient,
9/// including notifications to ClientListener, SubscriptionListener and ClientMessageListener
10/// will be dispatched by the same thread.
11pub trait SubscriptionListener: Send {
12    /// Event handler that is called by Lightstreamer each time a request to clear the snapshot
13    /// pertaining to an item in the Subscription has been received from the Server.
14    /// More precisely, this kind of request can occur in two cases:
15    ///
16    /// - For an item delivered in COMMAND mode, to notify that the state of the item becomes empty;
17    ///   this is equivalent to receiving an update carrying a DELETE command once for each key
18    ///   that is currently active.
19    ///
20    /// - For an item delivered in DISTINCT mode, to notify that all the previous updates received
21    ///   for the item should be considered as obsolete; hence, if the listener were showing a list
22    ///   of recent updates for the item, it should clear the list in order to keep a coherent view.
23    ///
24    /// Note that, if the involved Subscription has a two-level behavior enabled
25    /// (see `Subscription::set_command_second_level_fields()` and
26    /// `Subscription::set_command_second_level_field_schema()`), the notification refers to the
27    /// first-level item (which is in COMMAND mode). This kind of notification is not possible
28    /// for second-level items (which are in MERGE mode).
29    ///
30    /// # Parameters
31    ///
32    /// - `item_name`: name of the involved item. If the Subscription was initialized using an
33    ///   "Item Group" then a `None` value is supplied.
34    /// - `item_pos`: 1-based position of the item within the "Item List" or "Item Group".
35    fn on_clear_snapshot(&mut self, _item_name: Option<&str>, _item_pos: usize) {
36        // Default implementation does nothing.
37        unimplemented!("Implement on_clear_snapshot method for SubscriptionListener.");
38    }
39
40    /// Event handler that is called by Lightstreamer to notify that, due to internal resource
41    /// limitations, Lightstreamer Server dropped one or more updates for an item that was
42    /// subscribed to as a second-level subscription. Such notifications are sent only if the
43    /// Subscription was configured in unfiltered mode (second-level items are always in "MERGE"
44    /// mode and inherit the frequency configuration from the first-level Subscription).
45    ///
46    /// By implementing this method it is possible to perform recovery actions.
47    ///
48    /// # Parameters
49    ///
50    /// - `lost_updates`: The number of consecutive updates dropped for the item.
51    /// - `key`: The value of the key that identifies the second-level item.
52    ///
53    /// # See also
54    ///
55    /// - `Subscription::set_requested_max_frequency()`
56    /// - `Subscription::set_command_second_level_fields()`
57    /// - `Subscription::set_command_second_level_field_schema()`
58    fn on_command_second_level_item_lost_updates(&mut self, _lost_updates: u32, _key: &str) {
59        // Default implementation does nothing.
60        unimplemented!(
61            "Implement on_command_second_level_item_lost_updates method for SubscriptionListener."
62        );
63    }
64
65    /// Event handler that is called when the Server notifies an error on a second-level subscription.
66    ///
67    /// By implementing this method it is possible to perform recovery actions.
68    ///
69    /// # Parameters
70    ///
71    /// - `code`: The error code sent by the Server. It can be one of the following:
72    ///   - 14 - the key value is not a valid name for the Item to be subscribed; only in this case,
73    ///     the error is detected directly by the library before issuing the actual request to the Server
74    ///   - 17 - bad Data Adapter name or default Data Adapter not defined for the current Adapter Set
75    ///   - 21 - bad Group name
76    ///   - 22 - bad Group name for this Schema
77    ///   - 23 - bad Schema name
78    ///   - 24 - mode not allowed for an Item
79    ///   - 26 - unfiltered dispatching not allowed for an Item, because a frequency limit is associated to the item
80    ///   - 27 - unfiltered dispatching not supported for an Item, because a frequency prefiltering is applied for the item
81    ///   - 28 - unfiltered dispatching is not allowed by the current license terms (for special licenses only)
82    ///   - 66 - an unexpected exception was thrown by the Metadata Adapter while authorizing the connection
83    ///   - 68 - the Server could not fulfill the request because of an internal error.
84    ///   - `<= 0` - the Metadata Adapter has refused the subscription or unsubscription request;
85    ///     the code value is dependent on the specific Metadata Adapter implementation
86    /// - `message`: The description of the error sent by the Server; it can be `None`.
87    /// - `key`: The value of the key that identifies the second-level item.
88    ///
89    /// # See also
90    ///
91    /// - `ConnectionDetails::set_adapter_set()`
92    /// - `Subscription::set_command_second_level_fields()`
93    /// - `Subscription::set_command_second_level_field_schema()`
94    fn on_command_second_level_subscription_error(
95        &mut self,
96        _code: i32,
97        _message: Option<&str>,
98        _key: &str,
99    ) {
100        // Default implementation does nothing.
101        unimplemented!(
102            "Implement on_command_second_level_subscription_error method for SubscriptionListener."
103        );
104    }
105
106    /// Event handler that is called by Lightstreamer to notify that all snapshot events for an item
107    /// in the Subscription have been received, so that real time events are now going to be received.
108    /// The received snapshot could be empty. Such notifications are sent only if the items are delivered
109    /// in DISTINCT or COMMAND subscription mode and snapshot information was indeed requested for the items.
110    /// By implementing this method it is possible to perform actions which require that all the initial
111    /// values have been received.
112    ///
113    /// Note that, if the involved Subscription has a two-level behavior enabled
114    /// (see `Subscription::set_command_second_level_fields()` and
115    /// `Subscription::set_command_second_level_field_schema()`), the notification refers to the
116    /// first-level item (which is in COMMAND mode). Snapshot-related updates for the second-level
117    /// items (which are in MERGE mode) can be received both before and after this notification.
118    ///
119    /// # Parameters
120    ///
121    /// - `item_name`: name of the involved item. If the Subscription was initialized using an
122    ///   "Item Group" then a `None` value is supplied.
123    /// - `item_pos`: 1-based position of the item within the "Item List" or "Item Group".
124    ///
125    /// # See also
126    ///
127    /// - `Subscription::set_requested_snapshot()`
128    /// - `ItemUpdate::is_snapshot()`
129    fn on_end_of_snapshot(&mut self, _item_name: Option<&str>, _item_pos: usize) {
130        // Default implementation does nothing.
131        unimplemented!("Implement on_end_of_snapshot method for SubscriptionListener.");
132    }
133
134    /// Event handler that is called by Lightstreamer to notify that, due to internal resource
135    /// limitations, Lightstreamer Server dropped one or more updates for an item in the Subscription.
136    /// Such notifications are sent only if the items are delivered in an unfiltered mode; this occurs if the subscription mode is:
137    ///
138    /// - RAW
139    /// - MERGE or DISTINCT, with unfiltered dispatching specified
140    /// - COMMAND, with unfiltered dispatching specified
141    /// - COMMAND, without unfiltered dispatching specified (in this case, notifications apply to ADD and DELETE events only)
142    ///
143    /// By implementing this method it is possible to perform recovery actions.
144    ///
145    /// # Parameters
146    ///
147    /// - `item_name`: name of the involved item. If the Subscription was initialized using an
148    ///   "Item Group" then a `None` value is supplied.
149    /// - `item_pos`: 1-based position of the item within the "Item List" or "Item Group".
150    /// - `lost_updates`: The number of consecutive updates dropped for the item.
151    ///
152    /// # See also
153    ///
154    /// - `Subscription::set_requested_max_frequency()`
155    fn on_item_lost_updates(
156        &mut self,
157        _item_name: Option<&str>,
158        _item_pos: usize,
159        _lost_updates: u32,
160    ) {
161        // Default implementation does nothing.
162        unimplemented!("Implement on_item_lost_updates method for SubscriptionListener.");
163    }
164
165    /// Event handler that is called by Lightstreamer each time an update pertaining to an item
166    /// in the Subscription has been received from the Server.
167    ///
168    /// # Parameters
169    ///
170    /// - `update`: a value object containing the updated values for all the fields, together with
171    ///   meta-information about the update itself and some helper methods that can be used to
172    ///   iterate through all or new values.
173    fn on_item_update(&self, _update: &ItemUpdate) {
174        // Default implementation does nothing.
175        unimplemented!("Implement on_item_update method for SubscriptionListener.");
176    }
177
178    /// Event handler that receives a notification when the `SubscriptionListener` instance is
179    /// removed from a `Subscription` through `Subscription::remove_listener()`. This is the last
180    /// event to be fired on the listener.
181    fn on_listen_end(&mut self) {
182        // Default implementation does nothing.
183    }
184
185    /// Event handler that receives a notification when the `SubscriptionListener` instance is
186    /// added to a `Subscription` through `Subscription::add_listener()`. This is the first event
187    /// to be fired on the listener.
188    fn on_listen_start(&mut self) {
189        // Default implementation does nothing.
190    }
191
192    /// Event handler that is called by Lightstreamer to notify the client with the real maximum
193    /// update frequency of the Subscription. It is called immediately after the Subscription is
194    /// established and in response to a requested change (see `Subscription::set_requested_max_frequency()`).
195    /// Since the frequency limit is applied on an item basis and a Subscription can involve multiple
196    /// items, this is actually the maximum frequency among all items. For Subscriptions with two-level
197    /// behavior (see `Subscription::set_command_second_level_fields()` and
198    /// `Subscription::set_command_second_level_field_schema()`), the reported frequency limit applies
199    /// to both first-level and second-level items.
200    ///
201    /// The value may differ from the requested one because of restrictions operated on the server side,
202    /// but also because of number rounding.
203    ///
204    /// Note that a maximum update frequency (that is, a non-unlimited one) may be applied by the Server
205    /// even when the subscription mode is RAW or the Subscription was done with unfiltered dispatching.
206    ///
207    /// # Parameters
208    ///
209    /// - `frequency`: A decimal number, representing the maximum frequency applied by the Server
210    ///   (expressed in updates per second), or the string "unlimited". A `None` value is possible in
211    ///   rare cases, when the frequency can no longer be determined.
212    fn on_real_max_frequency(&mut self, _frequency: Option<f64>) {
213        // Default implementation does nothing.
214        unimplemented!("Implement on_real_max_frequency method for SubscriptionListener.");
215    }
216
217    /// Event handler that is called by Lightstreamer to notify that a Subscription has been successfully
218    /// subscribed to through the Server. This can happen multiple times in the life of a Subscription
219    /// instance, in case the Subscription is performed multiple times through `LightstreamerClient::unsubscribe()`
220    /// and `LightstreamerClient::subscribe()`. This can also happen multiple times in case of automatic
221    /// recovery after a connection restart.
222    ///
223    /// This notification is always issued before the other ones related to the same subscription.
224    /// It invalidates all data that has been received previously.
225    ///
226    /// Note that two consecutive calls to this method are not possible, as before a second
227    /// `on_subscription` event is fired an `on_unsubscription()` event is eventually fired.
228    ///
229    /// If the involved Subscription has a two-level behavior enabled
230    /// (see `Subscription::set_command_second_level_fields()` and
231    /// `Subscription::set_command_second_level_field_schema()`), second-level subscriptions are not notified.
232    fn on_subscription(&mut self) {
233        // Default implementation does nothing.
234    }
235
236    /// Event handler that is called when the Server notifies an error on a Subscription.
237    /// By implementing this method it is possible to perform recovery actions.
238    ///
239    /// Note that, in order to perform a new subscription attempt, `LightstreamerClient::unsubscribe()`
240    /// and `LightstreamerClient::subscribe()` should be issued again, even if no change to the
241    /// Subscription attributes has been applied.
242    ///
243    /// # Parameters
244    ///
245    /// - `code`: The error code sent by the Server. It can be one of the following:
246    ///   - 15 - "key" field not specified in the schema for a COMMAND mode subscription
247    ///   - 16 - "command" field not specified in the schema for a COMMAND mode subscription
248    ///   - 17 - bad Data Adapter name or default Data Adapter not defined for the current Adapter Set
249    ///   - 21 - bad Group name
250    ///   - 22 - bad Group name for this Schema
251    ///   - 23 - bad Schema name
252    ///   - 24 - mode not allowed for an Item
253    ///   - 25 - bad Selector name
254    ///   - 26 - unfiltered dispatching not allowed for an Item, because a frequency limit is associated to the item
255    ///   - 27 - unfiltered dispatching not supported for an Item, because a frequency prefiltering is applied for the item
256    ///   - 28 - unfiltered dispatching is not allowed by the current license terms (for special licenses only)
257    ///   - 29 - RAW mode is not allowed by the current license terms (for special licenses only)
258    ///   - 30 - subscriptions are not allowed by the current license terms (for special licenses only)
259    ///   - 66 - an unexpected exception was thrown by the Metadata Adapter while authorizing the connection
260    ///   - 68 - the Server could not fulfill the request because of an internal error.
261    ///   - `<= 0` - the Metadata Adapter has refused the subscription or unsubscription request;
262    ///     the code value is dependent on the specific Metadata Adapter implementation
263    /// - `message`: The description of the error sent by the Server; it can be `None`.
264    ///
265    /// # See also
266    ///
267    /// - `ConnectionDetails::set_adapter_set()`
268    fn on_subscription_error(&mut self, _code: i32, _message: Option<&str>) {
269        // Default implementation does nothing.
270        unimplemented!("Implement on_subscription_error method for SubscriptionListener.");
271    }
272
273    /// Event handler that is called by Lightstreamer to notify that a Subscription has been successfully
274    /// unsubscribed from. This can happen multiple times in the life of a Subscription instance, in case
275    /// the Subscription is performed multiple times through `LightstreamerClient::unsubscribe()` and
276    /// `LightstreamerClient::subscribe()`. This can also happen multiple times in case of automatic
277    /// recovery after a connection restart.
278    ///
279    /// After this notification no more events can be received until a new `on_subscription` event.
280    ///
281    /// Note that two consecutive calls to this method are not possible, as before a second
282    /// `on_unsubscription` event is fired an `on_subscription()` event is eventually fired.
283    ///
284    /// If the involved Subscription has a two-level behavior enabled
285    /// (see `Subscription::set_command_second_level_fields()` and
286    /// `Subscription::set_command_second_level_field_schema()`), second-level unsubscriptions are not notified.
287    fn on_unsubscription(&mut self) {
288        // Default implementation does nothing.
289    }
290}