package org.zstack.storage.ceph; import org.springframework.beans.factory.annotation.Autowire; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Configurable; import org.springframework.transaction.annotation.Transactional; import org.zstack.core.componentloader.PluginRegistry; import org.zstack.core.db.DatabaseFacade; import org.zstack.core.db.GLock; import javax.persistence.LockModeType; /** * Created by frank on 7/28/2015. */ @Configurable(preConstruction = true, autowire = Autowire.BY_TYPE) public class CephCapacityUpdater { @Autowired private DatabaseFacade dbf; @Autowired private PluginRegistry pluginRgty; public void update(String fsid, long total, long avail) { update(fsid, total, avail, true); } @Transactional public void update(String fsid, long total, long avail, boolean updatedAnyway) { CephCapacityVO vo = dbf.getEntityManager().find(CephCapacityVO.class, fsid, LockModeType.PESSIMISTIC_WRITE); boolean updated = false; if (vo == null) { GLock lock = new GLock(String.format("ceph-%s", fsid), 120); lock.lock(); try { vo = dbf.getEntityManager().find(CephCapacityVO.class, fsid, LockModeType.PESSIMISTIC_WRITE); if (vo == null) { vo = new CephCapacityVO(); vo.setFsid(fsid); vo.setTotalCapacity(total); vo.setAvailableCapacity(avail); dbf.getEntityManager().persist(vo); updated = true; } else { if (vo.getAvailableCapacity() != avail || vo.getTotalCapacity() != total) { vo.setTotalCapacity(total); vo.setAvailableCapacity(avail); dbf.getEntityManager().merge(vo); updated = true; } } } finally { lock.unlock(); } } else { if (vo.getAvailableCapacity() != avail || vo.getTotalCapacity() != total) { vo.setTotalCapacity(total); vo.setAvailableCapacity(avail); dbf.getEntityManager().merge(vo); updated = true; } } if (updatedAnyway || updated) { for (CephCapacityUpdateExtensionPoint ext : pluginRgty.getExtensionList(CephCapacityUpdateExtensionPoint.class)) { ext.update(fsid, total, avail); } } } }