Project

General

Profile

« Previous | Next » 

Revision 7343

Added by Chris Jones over 12 years ago

Add locking to the itemAdded() method so ideally only one CN will respond to the request for a 'wanted' pid from the cluster. The lock is on a string, not the pid, and so won't conflict with system metadata locking. The string is based on the pid, with "missing-" as a prefix.

View differences:

src/edu/ucsb/nceas/metacat/dataone/hazelcast/HazelcastService.java
49 49
import com.hazelcast.core.EntryListener;
50 50
import com.hazelcast.core.Hazelcast;
51 51
import com.hazelcast.core.HazelcastInstance;
52
import com.hazelcast.core.ILock;
52 53
import com.hazelcast.core.IMap;
53 54
import com.hazelcast.core.ISet;
54 55
import com.hazelcast.core.ItemListener;
......
76 77
  
77 78
  private static final String SINCE_PROPERTY = "dateSysMetadataModified";
78 79

  
80
  private static final String MISSING_PID_PREFIX = "missing-";
81

  
79 82
/* The instance of the logging class */
80 83
  private static Logger logMetacat = Logger.getLogger(HazelcastService.class);
81 84
  
......
650 653
		return pids;
651 654
	}
652 655

  
656
	/**
657
	 * Respond to itemAdded events on the hzMissingIdentifiers Set.  Uses a
658
	 * distributed ILock to try to prevent multiple put calls on hzSystemMetadata
659
	 * 
660
	 * @param pid   the identifier of the event
661
	 */
653 662
	@Override
654 663
	public void itemAdded(Identifier pid) {
655 664
		// publish the SM for the pid if we have it locally
656 665
		logMetacat.debug("Responding to itemAdded for pid: " + pid.getValue());
666
		ILock lock = null;
657 667
		try {
658
			// look up the local copy of the SM
659
			SystemMetadata sm = IdentifierManager.getInstance().getSystemMetadata(pid.getValue());
660
			if (sm != null) {
661
				// "publish" the system metadata to the shared map since it showed up on the missing queue
662
				logMetacat.debug("Adding SystemMetadata to shared map for pid: " + pid.getValue());
663
				systemMetadata.put(pid, sm);
664
				
665
				// remove the entry since we processed it
666
				missingIdentifiers.remove(pid);
667
			} else {
668
				logMetacat.warn("Local SystemMetadata was null for pid: " + pid.getValue());
669
			}
668
		  lock = hzInstance.getLock(MISSING_PID_PREFIX + pid.getValue());
669
		  
670
		  if ( lock.tryLock() ) {
671
		      // look up the local copy of the SM
672
		      SystemMetadata sm = IdentifierManager.getInstance().getSystemMetadata(pid.getValue());
673
		      if (sm != null) {
674
		        // "publish" the system metadata to the shared map since it showed up on the missing queue
675
		        logMetacat.debug("Adding SystemMetadata to shared map for pid: " + pid.getValue());
676
		        systemMetadata.put(pid, sm);
677
		        
678
		        // remove the entry since we processed it
679
		        missingIdentifiers.remove(pid);
680
		        
681
		      } else {
682
		        logMetacat.warn("Local SystemMetadata was null for pid: " + pid.getValue());
683
		        
684
		      }
685
		      
686
		  } else {
687
		      logMetacat.debug(MISSING_PID_PREFIX + pid.getValue() + " was already locked. Skipping.");
688
		      
689
		  }
670 690
			
671 691
		} catch (Exception e) {
672 692
			logMetacat.error("Error looking up missing system metadata for pid: " + pid.getValue());
693
			
694
		} finally {
695
		    if ( lock != null ) {
696
            lock.unlock();
697
            
698
        }
673 699
		}
674 700
		
675 701
	}
676 702

  
703
	/**
704
   * Respond to itemRemoved events on the hzMissingIdentifiers Set
705
   * 
706
   * @param pid   the identifier of the event
707
   */
677 708
	@Override
678
	public void itemRemoved(Identifier arg0) {
709
	public void itemRemoved(Identifier pid) {
679 710
		// do nothing since someone probably handled the wanted PID
680 711
		
681 712
	}

Also available in: Unified diff