@Override public void run() { boolean ok = true; Feed feed = context.getFeed(); List<FeedEntry> entries = context.getEntries(); if (entries.isEmpty() == false) { List<String> lastEntries = cache.getLastEntries(feed); List<String> currentEntries = Lists.newArrayList(); List<FeedSubscription> subscriptions = null; for (FeedEntry entry : entries) { String cacheKey = cache.buildUniqueEntryKey(feed, entry); if (!lastEntries.contains(cacheKey)) { log.debug("cache miss for {}", entry.getUrl()); if (subscriptions == null) { subscriptions = feedSubscriptionDAO.findByFeed(feed); } ok &= addEntry(feed, entry, subscriptions); metricsBean.entryCacheMiss(); } else { log.debug("cache hit for {}", entry.getUrl()); metricsBean.entryCacheHit(); } currentEntries.add(cacheKey); } cache.setLastEntries(feed, currentEntries); } if (applicationSettingsService.get().isPubsubhubbub()) { handlePubSub(feed); } if (!ok) { // requeue asap feed.setDisabledUntil(new Date(0)); } metricsBean.feedUpdated(); taskGiver.giveBack(feed); }
private boolean addEntry( final Feed feed, final FeedEntry entry, final List<FeedSubscription> subscriptions) { boolean success = false; // lock on feed, make sure we are not updating the same feed twice at // the same time String key1 = StringUtils.trimToEmpty("" + feed.getId()); // lock on content, make sure we are not updating the same entry // twice at the same time FeedEntryContent content = entry.getContent(); String key2 = DigestUtils.sha1Hex(StringUtils.trimToEmpty(content.getContent() + content.getTitle())); Iterator<Lock> iterator = locks.bulkGet(Arrays.asList(key1, key2)).iterator(); Lock lock1 = iterator.next(); Lock lock2 = iterator.next(); boolean locked1 = false; boolean locked2 = false; try { locked1 = lock1.tryLock(1, TimeUnit.MINUTES); locked2 = lock2.tryLock(1, TimeUnit.MINUTES); if (locked1 && locked2) { feedUpdateService.updateEntry(feed, entry); List<User> users = Lists.newArrayList(); for (FeedSubscription sub : subscriptions) { users.add(sub.getUser()); } cache.invalidateUnreadCount(subscriptions.toArray(new FeedSubscription[0])); cache.invalidateUserRootCategory(users.toArray(new User[0])); metricsBean.entryInserted(); success = true; } else { log.error("lock timeout for " + feed.getUrl() + " - " + key1); } } catch (InterruptedException e) { log.error( "interrupted while waiting for lock for " + feed.getUrl() + " : " + e.getMessage(), e); } finally { if (locked1) { lock1.unlock(); } if (locked2) { lock2.unlock(); } } return success; }