0 Replies Latest reply: Dec 5, 2012 10:37 AM by AntonZ RSS

    ListenerFilter and Custom ValueExtractors

    AntonZ
      Hi.

      I just noticed that certain listeners remain in the cluster (by monitoring ListenerFilterCount) after shutting down the application that attached them and narrowed this down to listeners that have a transformer with custom extractor used. When coherence's extractors are used, listeners are removed uppon killing the app (like ReflectionExtractor is used). Detailed code that leaves a zombie filter is below.

      .Net Listener attaching

      DelegatingCacheListener Listener2 = new DelegatingCacheListener();
      Listener2.EntryInserted += new CacheEventHandler(DoSomethingHere);
      IValueExtractor extractor = new MyCustomExtractor(MyCustomExtractor.Operation.MYTYPE1);
      CacheEventFilter Filter2 = new CacheEventFilter(CacheEventFilter.CacheEventMask.Inserted, new AlwaysFilter());
      IFilter transformerFilter = new CacheEventTransformerFilter(Filter2, new Tangosol.Util.Transformer.ExtractorEventTransformer(extractor));
      preTradeCache.AddCacheListener(Listener2, transformerFilter, false);

      MyCustomExtractor:

      public class MyCustomExtractor
      implements PortableObject, ValueExtractor {
           
           private MyCustomExtractor.Operation extractorType;
           private Object parameter1;
           private Object parameter2;
           private Object parameter3;
           
           private static final long serialVersionUID = -33L;

      public MyCustomExtractor() {
      }

      public MyCustomExtractor(MyCustomExtractor.Operation _extractorType, Object parameter1,     Object parameter2, Object parameter3)
      {
      this.extractorType = _extractorType;
      this.parameter1 = parameter1;
      this.parameter2 = parameter2;
      this.parameter3 = parameter3;
      }

      public Object extract(Object obj) {
           if (obj!=null)
           {
           MyObject myObj = (MyObject)obj;
                     switch (extractorType)
                     {
                     case MYTYPE1:
                          return results;
                     case MYTYPE2:
                          return results;
                     }
           }
           return null;
      }

      public boolean equals(Object obj) {
           /*
      if (obj == this) {
      return true;
      }
      if (obj.getClass().equals(getClass())) {
      return this.equals(obj);
      }
      */
      if (obj != null && obj.getClass().equals(getClass())) {
      MyCustomExtractor other = (MyCustomExtractor)obj;
      return extractorType.equals(other.extractorType) && parameter1.equals(other.parameter1);
      }
      return false;

      }

      public int hashCode() {
      return extractorType.hashCode();
      }


           public void readExternal(PofReader reader)
      throws IOException
           {
                this.extractorType = Operation.values()[reader.readInt(0)];
                this.parameter1 = reader.readObject(1);
                this.parameter2 = reader.readObject(2);
                this.parameter3 = reader.readObject(3);
           }
           
      public void writeExternal(PofWriter writer)
      throws IOException
           {
                writer.writeInt(0, extractorType.ordinal());
                writer.writeObject(1, parameter1);
                writer.writeObject(2, parameter2);
                writer.writeObject(3, parameter3);
           }

      public enum Operation
      {
      MYTYPE1
      MYTYPE2
      }
      }