{"action":"created","issue":{"url":"https://api.github.com/repos/infinispan/infinispan/issues/4711","repository_url":"https://api.github.com/repos/infinispan/infinispan","labels_url":"https://api.github.com/repos/infinispan/infinispan/issues/4711/labels{/name}","comments_url":"https://api.github.com/repos/infinispan/infinispan/issues/4711/comments","events_url":"https://api.github.com/repos/infinispan/infinispan/issues/4711/events","html_url":"https://github.com/infinispan/infinispan/pull/4711","id":194285124,"number":4711,"title":"ISPN-7283 Make cluster and client listeners more fine grained","user":{"login":"galderz","id":50187,"avatar_url":"https://avatars.githubusercontent.com/u/50187?v=3","gravatar_id":"","url":"https://api.github.com/users/galderz","html_url":"https://github.com/galderz","followers_url":"https://api.github.com/users/galderz/followers","following_url":"https://api.github.com/users/galderz/following{/other_user}","gists_url":"https://api.github.com/users/galderz/gists{/gist_id}","starred_url":"https://api.github.com/users/galderz/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/galderz/subscriptions","organizations_url":"https://api.github.com/users/galderz/orgs","repos_url":"https://api.github.com/users/galderz/repos","events_url":"https://api.github.com/users/galderz/events{/privacy}","received_events_url":"https://api.github.com/users/galderz/received_events","type":"User","site_admin":false},"labels":[{"id":154279206,"url":"https://api.github.com/repos/infinispan/infinispan/labels/Backport","name":"Backport","color":"006b75","default":false},{"id":142381603,"url":"https://api.github.com/repos/infinispan/infinispan/labels/Preview","name":"Preview","color":"fbca04","default":false}],"state":"closed","locked":false,"assignee":null,"assignees":[],"milestone":null,"comments":4,"created_at":"2016-12-08T09:25:35Z","updated_at":"2016-12-13T11:03:38Z","closed_at":"2016-12-13T11:03:38Z","pull_request":{"url":"https://api.github.com/repos/infinispan/infinispan/pulls/4711","html_url":"https://github.com/infinispan/infinispan/pull/4711","diff_url":"https://github.com/infinispan/infinispan/pull/4711.diff","patch_url":"https://github.com/infinispan/infinispan/pull/4711.patch"},"body":"https://issues.jboss.org/browse/ISPN-7283\r\n\r\nThis is an unpolished preview PR, please bear that in mind when reviewing.\r\n\r\nTo understand this initial solution, it's important to understand that I started by thinking this was just a problem of server/hotrod, where we were not being as fine grained as possible WRT client interests. So, I started by adding those listener interests to the Hot Rod protocol with a single byte, so that requires a HR protocol change. Then in server, I went for the tedious option of having multiple listener impls depending on which annotation combo I was interested. I knew this wouldn't scale very well if more listener events were added in the future, but I just wanted to get something going...\r\n\r\nThen, I realised that this was enough because the cluster listener is installed around, RemoteClusterListener, listens for everything. So, not only the changes in server/hotrod were needed, but core needed changing too.\r\n\r\nSo, then I started looking into how I could have listener class but have a way to define which, of all the annotations present in that class, I was interested in registering the listener for. This led to the creation of `addFilteredListener` method. I think this is the best concept going forward, rather than having to create N possible listener classes depending on which annotations we're interested in. This of course means that a lot of the new code in server/hotrod can probably go if I can simply call `addFilteredListener` from there.\r\n\r\nSo, if everyone agrees with my approach, a key aspect here is defining where and how this method to add filtered listener should look like. Right now it looks like this:\r\n\r\n```\r\n   /**\r\n    * Add a listener limiting cache entry specific callbacks only to those\r\n    * annotations that are present in the annotation filter collection.\r\n    */\r\n   <C> void addFilteredListener(Object listener,\r\n         CacheEventFilter<? super K, ? super V> filter,\r\n         CacheEventConverter<? super K, ? super V, C> converter,\r\n         Set<Class<? extends Annotation>> filterAnnotations);\r\n```\r\n\r\nSo, the API is slightly clunky right now because those filter annotations can only filter `CacheEntryCreated`, `CacheEntryModified`, `CacheEntryExpired` and `CacheEntryRemoved` annotations. So, what this means if a listener has methods with all these four annotations, and I pass a filterAnnotation containing `CacheEntryCreated` and `CacheEntryModified`, then it will only listen for those. However, a key aspect here is that if the listener had other non cache-entry specific callbacks, e.g. `ViewChanged` or `TransactionCompleted`, I wanted to live those still there (this was actually needed to get `RemoteClusterListener` to work properly).\r\n\r\nIf anyone has other ideas of how this API should look like I'd love to hear. Also, to be able to easily consume this API from server/hotrod, it might be better if it lived in `FilteringListenable`. Would users find this API useful? Otherwise, `CacheNotifier` instance can always be retrieved via `AdvancedCache.getComponentRegistry(...)`.\r\n\r\nFinally, fixes in `CacheNotifierImpl` and `AbstractListenerImpl` contain a lot of code duplication which would need to be sorted out. The code is a bit messy in these classes and in the end, having tried multiple things and debugged odd behaviours, I found the safest thing to do but was to copy/paste some methods and adjust them. Not great :|"},"comment":{"url":"https://api.github.com/repos/infinispan/infinispan/issues/comments/266710049","html_url":"https://github.com/infinispan/infinispan/pull/4711#issuecomment-266710049","issue_url":"https://api.github.com/repos/infinispan/infinispan/issues/4711","id":266710049,"user":{"login":"galderz","id":50187,"avatar_url":"https://avatars.githubusercontent.com/u/50187?v=3","gravatar_id":"","url":"https://api.github.com/users/galderz","html_url":"https://github.com/galderz","followers_url":"https://api.github.com/users/galderz/followers","following_url":"https://api.github.com/users/galderz/following{/other_user}","gists_url":"https://api.github.com/users/galderz/gists{/gist_id}","starred_url":"https://api.github.com/users/galderz/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/galderz/subscriptions","organizations_url":"https://api.github.com/users/galderz/orgs","repos_url":"https://api.github.com/users/galderz/repos","events_url":"https://api.github.com/users/galderz/events{/privacy}","received_events_url":"https://api.github.com/users/galderz/received_events","type":"User","site_admin":false},"created_at":"2016-12-13T11:03:38Z","updated_at":"2016-12-13T11:03:38Z","body":"I've polished this PR and submitted #4721, so closing this one."}}
{"actor":{"display_login":"galderz"}}