@Override public synchronized void updateEntry(final String key, final HttpCacheUpdateCallback callback) throws IOException, HttpCacheUpdateException { int numRetries = 0; do { final Element oldElement = cache.get(key); HttpCacheEntry existingEntry = null; if (oldElement != null) { final byte[] data = (byte[]) oldElement.getValue(); existingEntry = serializer.readFrom(new ByteArrayInputStream(data)); } final HttpCacheEntry updatedEntry = callback.update(existingEntry); if (existingEntry == null) { putEntry(key, updatedEntry); return; } else { // Attempt to do a CAS replace, if we fail then retry // While this operation should work fine within this instance, multiple instances // could trample each others' data final ByteArrayOutputStream bos = new ByteArrayOutputStream(); serializer.writeTo(updatedEntry, bos); final Element newElement = new Element(key, bos.toByteArray()); if (cache.replace(oldElement, newElement)) { return; } else { numRetries++; } } } while (numRetries <= maxUpdateRetries); throw new HttpCacheUpdateException("Failed to update"); }
@Test public void testCASOperationsNotSupported() throws Exception { LOG.info("START TEST"); final Ehcache cache1 = manager1.getEhcache(cacheName); final Ehcache cache2 = manager2.getEhcache(cacheName); final Ehcache cache3 = manager3.getEhcache(cacheName); final Ehcache cache4 = manager4.getEhcache(cacheName); try { cache1.putIfAbsent(new Element("foo", "poo")); throw new AssertionError("CAS operation should have failed."); } catch (CacheException ce) { assertEquals(true, ce.getMessage().contains("CAS")); } try { cache2.removeElement(new Element("foo", "poo")); throw new AssertionError("CAS operation should have failed."); } catch (CacheException ce) { assertEquals(true, ce.getMessage().contains("CAS")); } try { cache3.replace(new Element("foo", "poo")); throw new AssertionError("CAS operation should have failed."); } catch (CacheException ce) { assertEquals(true, ce.getMessage().contains("CAS")); } try { cache4.replace(new Element("foo", "poo"), new Element("foo", "poo2")); throw new AssertionError("CAS operation should have failed."); } catch (CacheException ce) { assertEquals(true, ce.getMessage().contains("CAS")); } LOG.info("END TEST"); }
@Override protected void doReceive(Message message) throws Exception { PortalCacheClusterEvent portalCacheClusterEvent = (PortalCacheClusterEvent) message.getPayload(); if (portalCacheClusterEvent == null) { if (_log.isWarnEnabled()) { _log.warn("Payload is null"); } return; } String cacheName = portalCacheClusterEvent.getCacheName(); Ehcache ehcache = _portalCacheManager.getEhcache(cacheName); if (ehcache == null) { ehcache = _hibernateCacheManager.getEhcache(cacheName); } if (ehcache != null) { PortalCacheClusterEventType portalCacheClusterEventType = portalCacheClusterEvent.getEventType(); if (portalCacheClusterEventType.equals(PortalCacheClusterEventType.REMOVEALL)) { ehcache.removeAll(true); } else if (portalCacheClusterEventType.equals(PortalCacheClusterEventType.PUT) || portalCacheClusterEventType.equals(PortalCacheClusterEventType.UPDATE)) { Serializable elementKey = portalCacheClusterEvent.getElementKey(); Serializable elementValue = portalCacheClusterEvent.getElementValue(); if (elementValue == null) { ehcache.remove(portalCacheClusterEvent.getElementKey(), true); } else { Element oldElement = ehcache.get(elementKey); Element newElement = new Element(elementKey, elementValue); if (oldElement != null) { ehcache.replace(newElement); } else { ehcache.put(newElement); } } } else { ehcache.remove(portalCacheClusterEvent.getElementKey(), true); } } }