Build a Recommender for Reviewer Suggestion
Until now, reviewer suggestion was purely based on a search. I've built a small recommender to improve the suggestions based on past contributions by the individual reviewers and added an extension point so that people can customize this feature. The built-in recommender makes a default suggestion of reviewers before the user types a query. These are based on people that have reviewed the last contributions that a user made. If the user starts typing in the box, we generate a list of candidates using the account index and feed it into a small recommender. The recommender ranks the list by looking at recent contributions of the candidates made in the same project. Contributions include reviews, owned-changes and comments at different weights. Change-Id: I5aca23ddd2442146fd26bdc12e7c18da85de7ac1
This commit is contained in:
@@ -14,6 +14,7 @@
|
||||
|
||||
package com.google.gerrit.client.ui;
|
||||
|
||||
import com.google.gwt.user.client.Timer;
|
||||
import com.google.gwt.user.client.ui.SuggestOracle;
|
||||
|
||||
/**
|
||||
@@ -31,6 +32,10 @@ public class RemoteSuggestOracle extends SuggestOracle {
|
||||
private final SuggestOracle oracle;
|
||||
private Query query;
|
||||
private String last;
|
||||
private Timer requestRetentionTimer;
|
||||
private boolean cancelOutstandingRequest;
|
||||
|
||||
private boolean serveSuggestions;
|
||||
|
||||
public RemoteSuggestOracle(SuggestOracle src) {
|
||||
oracle = src;
|
||||
@@ -42,13 +47,33 @@ public class RemoteSuggestOracle extends SuggestOracle {
|
||||
|
||||
@Override
|
||||
public void requestSuggestions(Request req, Callback cb) {
|
||||
Query q = new Query(req, cb);
|
||||
if (query == null) {
|
||||
query = q;
|
||||
q.start();
|
||||
} else {
|
||||
query = q;
|
||||
if (!serveSuggestions){
|
||||
return;
|
||||
}
|
||||
|
||||
// Use a timer for key stroke retention, such that we don't query the
|
||||
// backend for each and every keystroke we receive.
|
||||
if (requestRetentionTimer != null) {
|
||||
requestRetentionTimer.cancel();
|
||||
}
|
||||
requestRetentionTimer = new Timer() {
|
||||
@Override
|
||||
public void run() {
|
||||
Query q = new Query(req, cb);
|
||||
if (query == null) {
|
||||
query = q;
|
||||
q.start();
|
||||
} else {
|
||||
query = q;
|
||||
}
|
||||
}
|
||||
};
|
||||
requestRetentionTimer.schedule(200);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void requestDefaultSuggestions(Request req, Callback cb) {
|
||||
requestSuggestions(req, cb);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -56,6 +81,19 @@ public class RemoteSuggestOracle extends SuggestOracle {
|
||||
return oracle.isDisplayStringHTML();
|
||||
}
|
||||
|
||||
public void cancelOutstandingRequest() {
|
||||
if (requestRetentionTimer != null) {
|
||||
requestRetentionTimer.cancel();
|
||||
}
|
||||
if (query != null) {
|
||||
cancelOutstandingRequest = true;
|
||||
}
|
||||
}
|
||||
|
||||
public void setServeSuggestions(boolean serveSuggestions) {
|
||||
this.serveSuggestions = serveSuggestions;
|
||||
}
|
||||
|
||||
private class Query implements Callback {
|
||||
final Request request;
|
||||
final Callback callback;
|
||||
@@ -71,7 +109,11 @@ public class RemoteSuggestOracle extends SuggestOracle {
|
||||
|
||||
@Override
|
||||
public void onSuggestionsReady(Request req, Response res) {
|
||||
if (query == this) {
|
||||
if (cancelOutstandingRequest || !serveSuggestions) {
|
||||
// If cancelOutstandingRequest() was called, we ignore this response
|
||||
cancelOutstandingRequest = false;
|
||||
query = null;
|
||||
} else if (query == this) {
|
||||
// No new request was started while this query was running.
|
||||
// Propose this request's response as the suggestions.
|
||||
query = null;
|
||||
|
||||
Reference in New Issue
Block a user