4 Replies Latest reply: Mar 18, 2013 6:23 AM by 917390 RSS

    MultiplexingMapListener onMapEvent never gets old value

    917390
      h1. Overview

      Cache: Coherence 3.7.1.4
      Client: C++ (Coherence 3.7.1.4)

      We have a cache of "states" (one entry for each of the four things we're interested in in our system).

      On the Java side we extend AbstractProcessor. This is invoked to handle inserts/updates to the states in the cache.

      On the C++ (client) side we have a continuous query which "listens" for updates to the state.

      When I fiire state changes the Java processor "process" method is invoked (which is fine). I debug through it and it does its job - no exceptions and no NULL pointers.

      h1. The Problem

      When the Java "process" method completes my C++ client onMapEvent method is invoked.
      Calling vEvent->getNewValue() gets the correct new value.
      Calling vEvent->getOldValue() always returns null. We never get the old state even though state exists in the cache before the update.

      Does anyone know why the old value is not being set?

      Thanks.

      h1. Code

      h2. Java (pseudo code)

      @Override
      public Object process(Entry entry)
      {
      try
      {
      // Some logic...
      ProdState newState = new ProdState(/*New values*/);
                
      entry.setValue(newState);

      return newState;
      }
      catch (Throwable t)
      {
      // Log.
      }

      return null;
      }

      h2. C++ Client (initialization)

      // Subscribe to all ProdState entries.
      coherence::util::Filter::Handle filter = coherence::util::filter::AlwaysFilter::create();

      m_hProdStateQuery = coherence::net::cache::ContinuousQueryCache::create(m_hCacheProductState,
      filter,
      true,
      ProdStateListener::create());

      h2. C++ Client (listener)

      *// NOTE: ProdStateListener extends MultiplexingMapListener*

      void ProdStateListener::onMapEvent(MapEvent::View vEvent)
      {
           try
           {
                *// PROBLEM: oldState is always NULL.*     

      Managed<ProdState>::View oldState =
                          coherence::lang::cast<Managed<ProdState>::View>(vEvent->getOldValue());

                *// newState is correct.*     


      Managed<ProdState>::View newState =
                          coherence::lang::cast<Managed<ProdState>::View>(vEvent->getNewValue());

                // ...notify observers.

           }
           catch(const std::exception& ex)
           {
                std::cout << ex.what() << std::endl;
           }
      }
        • 1. Re: MultiplexingMapListener onMapEvent never gets old value
          tmiddlet
          Hi

          A couple of questions.
          1) Can you post a snippet of code calling your EntryProcessor? Is it called from Java or C++?
          2) In your EntryProcessor, are you able to try the following instead of creating a new ProdState() object.
          ProdState prodState = (ProdState) entry.getValue();
          // Call setters to change values for prodState.
          prodState.setX(...);
          prodState.setY(...);
          entry.setValue(prodState);
          3) Are you sure you are updating the same key for the ProdState object?

          Thanks

          Tim
          • 2. Re: MultiplexingMapListener onMapEvent never gets old value
            user123799
            Hi DonLonDon,

            Your EP and CQC look valid enough.

            Have you tried replacing the CQC with a near-cache, or even attaching the listener directly to the grids distributed cache? This might help to isolate your issue, as it may be purely CQC related. If all three result in the same issue its much more likely to be the EP.

            Andy
            • 3. Re: MultiplexingMapListener onMapEvent never gets old value
              DJW
              Hi,

              Perhaps the ContinuousQueryCache constructor is registering the listener in "lite" mode (see method addFilterListener in http://docs.oracle.com/cd/E24290_01/coh.371/e22845/classcoherence_1_1util_1_1_observable_map.html).

              To verify, trying explicitly adding a listener using addFilterListener setting "fLite" to false.

              It may not be useful as a solution to your problem, in that adding the listener afterwards means you'll miss the events arising from initial population of the CQC, but may at least clarify what's happening.


              David
              • 4. Re: MultiplexingMapListener onMapEvent never gets old value
                917390
                Thanks for the suggestions - unfortunately I haven't had time to try any of them out so haven't identified the root cause.

                We came up with a workaround based on data in our newState object.

                As I'm moving on to new development pastures I doubt I'll get chance to look at this problem again but would be interested if anyone solves it.

                Thanks again.