[ https://issues.apache.org/jira/browse/MAHOUT-247?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel ]
Sean Owen resolved MAHOUT-247. ------------------------------ Resolution: Fixed Tentatively resolving this after applying a fix to the most obvious case where this issue could come up. It's not truly fixed in all cases, though at the moment, I think this is all that is practical to attempt. I'm open to more suggestions about how to address this. > GenericUserBasedRecommender.recommend causes connection leak when called for > user with no preferences > ----------------------------------------------------------------------------------------------------- > > Key: MAHOUT-247 > URL: https://issues.apache.org/jira/browse/MAHOUT-247 > Project: Mahout > Issue Type: Bug > Components: Collaborative Filtering > Affects Versions: 0.2 > Environment: Reproducable on Win32 and Ubuntu > Reporter: Tolga Oral > Assignee: Sean Owen > Priority: Minor > Fix For: 0.3 > > > UserSimilarity userSimilarity = new > TanimotoCoefficientSimilarity(getBooleanPrefDataModel()); > UserNeighborhood neighborhood = new > NearestNUserNeighborhood(3, userSimilarity, getBooleanPrefDataModel()); > Recommender recommender = new > GenericBooleanPrefUserBasedRecommender(getBooleanPrefDataModel(), > neighborhood, userSimilarity); > recommender.recommend(userwithnopreferencesdata, 10); > code properly throws NoSuchUserException however one of the connections is > hang on LongPrimitiveIterator backed by > org.apache.mahout.cf.taste.impl.model.jdbc.AbstractJDBCDataModel$ResultSetIDIterator > as Exception is thrown before TopItems.getTopUsers finishes the while loop > public static long[] getTopUsers(int howMany, > LongPrimitiveIterator allUserIDs, > Rescorer<Long> rescorer, > Estimator<Long> estimator) throws > TasteException { > Queue<SimilarUser> topUsers = new PriorityQueue<SimilarUser>(howMany + 1, > Collections.reverseOrder()); > boolean full = false; > double lowestTopValue = Double.NEGATIVE_INFINITY; > //HERE IS THE ITERATOR > while (allUserIDs.hasNext()) { > long userID = allUserIDs.next(); > if (rescorer != null && rescorer.isFiltered(userID)) { > continue; > } > //EXCEPTION THROWN HERE CAUSES THE CONNECTION LEAK > double similarity = estimator.estimate(userID); > double rescoredSimilarity = rescorer == null ? similarity : > rescorer.rescore(userID, similarity); > if (!Double.isNaN(rescoredSimilarity) && (!full || rescoredSimilarity > > lowestTopValue)) { > topUsers.add(new SimilarUser(userID, similarity)); > if (full) { > topUsers.poll(); > } else if (topUsers.size() > howMany) { > full = true; > topUsers.poll(); > } > lowestTopValue = topUsers.peek().getSimilarity(); > } > } > if (topUsers.isEmpty()) { > return NO_IDS; > } > List<SimilarUser> sorted = new ArrayList<SimilarUser>(topUsers.size()); > sorted.addAll(topUsers); > Collections.sort(sorted); > long[] result = new long[sorted.size()]; > int i = 0; > for (SimilarUser similarUser : sorted) { > result[i++] = similarUser.getUserID(); > } > return result; > } > ============================================================================================================ > I currently fixed it in our application by checking first to see if user has > preferences for the given dataset (user might exists and have preferences for > a different dataset). > However this edge case does not cause issues in some other recommenders as > long as we handle the NoSuchUserException. > Easy solution is to use AbstractJDBCDataModel$ResultSetIDIterator always with > try/catch/finally and release the connection. -- This message is automatically generated by JIRA. - You can reply to this email to add a comment to the issue online.