4 Replies Latest reply on Oct 3, 2019 10:57 AM by xavier.marquis

    CacheListerer : identify node that has updated an entry

    xavier.marquis

      Hi,

       

      I begin with infinispan, and I don't understand well the meaning of TransactionalEvent.isOriginLocal() getter method :

       

      I've set a configuration for an distributed infinispan cache DIST_SYNC, with following flags :

      IGNORE_RETURN_VALUES,  SKIP_CACHE_LOAD and SKIP_REMOTE_LOOKUP

       

      In my node application, I've created a CacheListener class like this :

       

      @Listener(clustered = true, sync = false)

      class CacheListener {


         @CacheEntryCreated
         public void onCacheEntryCreated(CacheEntryCreatedEvent event) {

                 // do something ...
         }

         @CacheEntryModified
         public void onCacheEntryModified(CacheEntryModifiedEvent event) {

                 // do something ...
         }

      }

      and called cache.addListener( new CacheListener() ).

       

      Then, when nodeA and nodeB are started and sharing the same cache, and entry E1 is already present in the shared cache, i expected similar behaviour :

      • When nodeA updates entry E1:
        1. CacheListener of nodeA notify it with an event whose isOriginLocal = true
        2. CacheListener of nodeB notify it with an event whose isOriginLocal = false

       

      • When nodeB updates entry E1:
        1. CacheListener of nodeB notify it with an event whose isOriginLocal = true
        2. CacheListener of nodeA notify it with an event whose isOriginLocal = false

       

       

      But that is not the case : During my test, It seems like isOriginLocal = true when E1 entry is updated by 'primary owner',   where 'primary owner' could be defined like this :

      primary owner :

         - node that has created entry E1 (if it still is alive)

         - one of the other nodes (implied with this cache), which own this entry and which has been considered as the new E1 creator, since first E1 creator exited cache.

       

      > Q1. Can someone confirm my conclusion ?

      If it is true, my initial aim was to distinguish, in cacheListener notification events,  node that updates E1 from nodes that receives E1 update.

      If cacheListener does not allow this functionnality, does infinispan framework give another element to deal with it ?

       

      > Q2 : Another notice :

      I don't understand why, but the only events CacheEntryEvent that my application receive are only those after update ( isPre = false ) ...

       

      Thanks for reading,

       

      Xavier

        • 1. Re: CacheListerer : identify node that has updated an entry
          william.burns

          xavier.marquis  wrote:

          > Q1. Can someone confirm my conclusion ?

          If it is true, my initial aim was to distinguish, in cacheListener notification events,  node that updates E1 from nodes that receives E1 update.

          If cacheListener does not allow this functionnality, does infinispan framework give another element to deal with it ?

          I am sorry I am not quite sure what you are trying to say here. Do you only want a node to receive an update that originated on the same node? If so you should not be using clustered listeners and use a regular listener. This will receive the notification based on locality and will also give you pre events. Cluster listeners are always "remote", unless it is on the primary owner and the one who invoked it.

          xavier.marquis  wrote:

           

          > Q2 : Another notice :

          I don't understand why, but the only events CacheEntryEvent that my application receive are only those after update ( isPre = false ) ...

          This is how cluster listeners work, they only receive pre events.  You can read more about them at Developing for Infinispan 10.0

          • 2. Re: CacheListerer : identify node that has updated an entry
            xavier.marquis

            Hello Will, first, thanks for answers

             

            Q1 :

            Do you only want a node to receive an update that originated on the same node?

            I want the inverse : receive an event only and only if update comes from another node.

             

            Cluster listeners are always "remote", unless it is on the primary owner and the one who invoked it.

            I'm really don't understand what does mean "remote" :

            In my application, all nodes are identical (same code), and share the same cache.

            Each node of my application register the same CacheListener.

            actual behaviour : when an cache update is made at one node,  all nodes are notified of the update, including the node that mades the update ...

             

            I just don't want the node doing the update to be notified.

            Since I didn't find in doc a Cluster Listener that does this, I wanted to use isOriginLocal to ignore events coming from the entry updater node.

            But it does not work like this.

            There may be another solution ... ?

             

            Q2 : perfect answer, I should have a look on the doc

            • 3. Re: CacheListerer : identify node that has updated an entry
              william.burns

              xavier.marquis  wrote:

               

              Hello Will, first, thanks for answers

               

              Q1 :

              Do you only want a node to receive an update that originated on the same node?

              I want the inverse : receive an event only and only if update comes from another node.

               

              Cluster listeners are always "remote", unless it is on the primary owner and the one who invoked it.

              I'm really don't understand what does mean "remote" :

              In my application, all nodes are identical (same code), and share the same cache.

              Each node of my application register the same CacheListener.

              actual behaviour : when an cache update is made at one node,  all nodes are notified of the update, including the node that mades the update ...

               

              I just don't want the node doing the update to be notified.

              Since I didn't find in doc a Cluster Listener that does this, I wanted to use isOriginLocal to ignore events coming from the entry updater node.

              But it does not work like this.

              There may be another solution ... ?

              To get what you want, you should use a non clustered listener and only process events where `isOriginLocal` is false.

               

              You can also optionally register a filter that rejects any notification that `isOriginLocal`. This would allow you to not pollute your listener code with doing the origin check. FilteringListenable (Infinispan JavaDoc All 10.0.0.CR2 API)

              • 4. Re: CacheListerer : identify node that has updated an entry
                xavier.marquis

                I didn't say before but I'm using Infinispan 9.4.0.Final.

                Ok, I think i finally was partially successful by enabling a transactionMode in my cache configuration (in following, the red lines) :

                 

                @Bean
                public InfinispanCacheConfigurer cacheConfigurer() {

                 

                  return embededCacheManager -> {

                  org.infinispan.configuration.cache.Configuration ispnConfig = new ConfigurationBuilder()

                  .clustering()

                  .cacheMode(CacheMode.DIST_SYNC)

                  .transaction()

                  .notifications(true)

                  .transactionMode(TransactionMode.TRANSACTIONAL)

                  .build();

                   embededCacheManager.defineConfiguration(NAZA_MAIN_CACHE_NAME, ispnConfig);

                   embededCacheManager.getCache(NAZA_MAIN_CACHE_NAME).getAdvancedCache()

                  .withFlags(Flag.IGNORE_RETURN_VALUES, Flag.SKIP_CACHE_LOAD, Flag.SKIP_REMOTE_LOOKUP);
                   };
                }

                 

                Notice : I also removed clustered=true in @Listener and add  observation = Listener.Observation.POST

                 

                 

                My conclusion (exception misunderstanding) :

                If no transactionMode is set on the cache, then the TransactionalEvent.isOriginLocal  value are not set by infinispan the way we expect it to do, but like the way I explain on my first POST.

                 

                @CacheEntryModified
                public void onCacheEntryModified(CacheEntryModifiedEvent event) {

                   log.info("onCacheEntryModified : isOrigin: {} " , event.isOriginLocal() );

                 

                   if (event.getGlobalTransaction() != null) {

                      log.info("update is remote : {} ", event.getGlobalTransaction().isRemote());
                   }

                }

                 

                I can now notice in the logs of the node that is doing the update, that   isOrigin is true, and is remote is false

                At the other side, in the logs of the node that is receiving the update, that    isOrigin is false, and is remote is true

                This is what I want to do.

                 

                But I have to enable transaction functionnality on the cache. I don't know if it can reduce the performance ...

                Does somebody has answer to it ?

                 

                1 of 1 people found this helpful