-
Notifications
You must be signed in to change notification settings - Fork 18
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Model change events subscription #25
Comments
Eventually, we will support all of the points you raised above. 👍 Right now, it's a bit of a broadcast with a singular update event when any value change occurs inside the The create/delete events likely only applies for As to XPATH expression, I'm trying to come up with the best expression to capture listening for a sub-element of interest. It would be simpler if the XPATH was a way to subscribe to any event from the matching node(s), but probably a bit more involved if we need to somehow express one-or-more specific type of event from the matching node(s). |
Create/Delete events could be applied to container/list entries. I think "update" can be considered a general bucket for pushing events when -
When a list is updated (a new entry for example or change to attributes of existing list entry), I would expect multiple events. i.e. One for update on the list, and others for set on attributes of the list entry attributes. Hope this makes sense. I agree, its a little tricky to come up with the XPATH expression filters for selective event subscription. However, I meant YPATH instead of XPATH if you will. YPATH is an expression pointing to the model schema while XPATH may point to instance data. I prefer being able to specify YPATH for event subscription filters. For example, if I subscriber to "/subscriber/name" YPATH where 'subscriber' is a list and 'name' is a leaf attribute, I expect events raised when "name" is changed (set/update/delete) for any instance (existing or new) abiding the subscriber data model. Does this make sense ? If not, may be NETCONF specification for notifications may provide hints on what to allow. |
@ramukima - the current I've added additional The case where one of the attributes for a given list item is updated, only Yes, I've also noted a need to have some internal separation between pure XPATH and the new pseudo YPATH construct. It's not entirely clean right now but it will behave in the way you describe. BTW, is YPATH an actual specification or just something we're making up here? |
expression as discussed on #25. cleanup some internal Model schema associations and adjust Model.access accordingly.
@ramukima - with the latest update, you can now attach to a specific XPATH filter on a given Model's event: model = (yang 'list foo { container bar { leaf a; leaf b; } }') foo: [ bar: { a: 'hi', b: 'there' } ]
model.on 'update', '/foo/bar/a', -> console.log "property 'a' updated"
model.foo[0].bar.a = 'bye' # fires the above event callback handler Hopefully this gives you the granular event subscription you're looking for. |
Wonderful. Many thanks for getting it in so quickly. Few differences though -
I do a POST to create an item to this list by using the following -
This generates a 'create' event for the new list entry added as well as an 'update' event on the original foo list, perfect so far 👍 I then attempt to update the "name" attribute of the record added above to "foo2" like below -
This generates an 'update' event for "name" field change. Perfect 👍 However, in this case the "prop.path" could indicate the absolute path e.g. "/foo/1/name" instead of "foo/name". Alternatively, the event could inject the "key" of the list entry updated in the event data. Otherwise, I have no way to figure out which record got updated in this case. Does that make sense ? I then attempt to run the same update by running the same curl command again to check what event is generated (I do not expect any event in this case, as there is actually NO update if a diff was calculated). However, I see an 'update' event on "name" field even though its value did not change. I believe such diff calculator could be very well part of the core event propagation. Hopefully it all makes sense. Let me know if you believe the notification should behave otherwise. |
No, you're right - I was aware of those shortcomings, I just haven't gotten As to diff() operation, I'm currently sending the new Property and the old I figured it would be better to send new and old and let the callback I can suppress the "update" event if the operation did not result in a data For example, if you consider a time/refresh type of data where
|
It is reasonable to expect an application to perform a diff of changes before taking further actions. I did not notice the (prev, prop) thing earlier, hence my confusion. Regarding the timestamp on data, I guess that can be integral part of the model even though it may be auto-computed in the backend. Hence, in such situations, an event is expected even when no state in actual data was changed, other than the automatically computed timestamp. I like the idea of touch events. Also, may be aligning it with NETCONF subscription specification is beneficial as well. |
Sure perfectly reasonable since none of this has been documented. :-) Need to add Events API section in the README. Probably need to transition
|
…elated to for a list item returning its key
…ed inside the Model (see #25), also added some documentation on 'Model Events'
I think I've addressed most, if not all of the events API as discussed. Please give the latest version a try and we can close this issue and open more specific ones later as needed. Take a look at the latest documentation - there's more work at hand but I think it's a significant improvement. |
BTW - I've decided against using the wiki since it would be better to have documentation version tagged with the given snapshot being used. |
I am somehow still not able to get the filter based event subscription working. I have two 'on' subscriptions on my model. One without a filter path and other with a filter path. I never see the one with filter specified being called -
Also, I am not sure if I can specify a filter for 'create' events as well. For example, I want to know when a 'childpet' is created. So not sure if something like this will work -
I need few examples here. |
I'll take a look - the recent change to internal XPATH processing, etc. may The unit test suite needs some major update to also include method
|
@ramukima - sorry I was not able to replicate your issue. It all seems to be working fine... This is what I tried in the coffee REPL:
The last action with It is able to map the Now Right now, there is an issue where making direct manipulations to the array instance itself, via .push/.pop, etc. is NOT schema protected. I'm planning on making the array be a copy instead of the real thing when accessed via the In any case, the above set of REPL commands should reproduce what you'd expect during series of RESTJSON transactions. Please let me know if you run into any other issues. |
One thing to note is that setting the As you've probably noted in the Hope this all makes sense. |
BTW, once you have the initial data set loaded and only interested in listening to a particular element, you can also try this: model.in('/pet/one/childpet/child-one/id').on 'update', (x) -> console.log "id changed" This style of event listener will require some prior knowledge on the exact path to traverse, but the benefit is that it will persist across any changes to the However, if you used this: model.on 'update', '/pet/one/childpet/child-one/id`, (x) -> console.log "dynamic path: id changed" Then it will only apply to any particular instance that happens to be that XPATH expression at any time. So the event listener is actually NOT bound to that matching node, but to the |
Ok, thanks for documenting it nicely. I will try it the way you recommend. |
I noticed the paths here you mentioned for the filters is "absolute" XPATH pointing to instances. I was thinking I could do that using YPATH (Yang Path) e.g. on update of /pet/childpet, I could receive events whenever any instances are created/updated/deleted/set/unset under that model. |
Yes, the event listener filter paths apply to events from that "matching" element (and sub-elements). |
By the way, I want to mention that "state synschronization" through eventing is a means for external system integration. However, I am skeptical whether thats the right approach for persisting model state changes for the core application. Imagine I have a event subscription to propagate a list into a data store when new entries in the list get added. When I restart my application, I must fetch that data from the datastore before my application loads completely. Loading such bulk data at once from the persistent datastore in-memory is not advised due to performance and scale reasons. The best thing would be to introduce "datastore adaptors" my means of "data provider apis". A reference implementation (in-memory, the way it is currently) is provided by the core and applications can hook in other providers when they have the "data provider" APIs implemented. |
Sure, this is how I was planning on addressing this scenario. We can introduce support for This way, it can still perform necessary schema validations on elements needed as it is being used instead of requiring the entire state to be loaded into memory every time during start. I think it will help optimize in scenarios where there may be nested lists but if there is a large flat list at the top of the model, it'd still likely require loading most of that data in order to properly transact XPATH predicate operations on it. |
Few questions -
The text was updated successfully, but these errors were encountered: