diff --git a/server-core/src/main/java/io/onedev/server/data/migration/DataMigrator.java b/server-core/src/main/java/io/onedev/server/data/migration/DataMigrator.java index 05bceef739..66a72a4c01 100644 --- a/server-core/src/main/java/io/onedev/server/data/migration/DataMigrator.java +++ b/server-core/src/main/java/io/onedev/server/data/migration/DataMigrator.java @@ -8159,4 +8159,26 @@ public class DataMigrator { } } + private void migrate207(File dataDir, Stack versions) { + for (File file : dataDir.listFiles()) { + if (file.getName().startsWith("Projects.xml")) { + VersionedXmlDoc dom = VersionedXmlDoc.fromFile(file); + for (Element element : dom.getRootElement().elements()) { + element.element("lastEventDate").setName("lastActivityDate"); + } + dom.writeToFile(file, false); + } else if (file.getName().startsWith("ProjectLastEventDates.xml")) { + VersionedXmlDoc dom = VersionedXmlDoc.fromFile(file); + for (Element element : dom.getRootElement().elements()) { + element.setName("io.onedev.server.model.ProjectLastActivityDate"); + var commitElement = element.element("commit"); + if (commitElement != null) + commitElement.detach(); + element.element("activity").setName("value"); + } + dom.writeToFile(new File(dataDir, file.getName().replace("ProjectLastEventDates", "ProjectLastActivityDates")), false); + } + } + } + } diff --git a/server-core/src/main/java/io/onedev/server/entitymanager/ProjectLastEventDateManager.java b/server-core/src/main/java/io/onedev/server/entitymanager/ProjectLastEventDateManager.java index adb45ebfc6..70d44a977d 100644 --- a/server-core/src/main/java/io/onedev/server/entitymanager/ProjectLastEventDateManager.java +++ b/server-core/src/main/java/io/onedev/server/entitymanager/ProjectLastEventDateManager.java @@ -1,10 +1,10 @@ package io.onedev.server.entitymanager; -import io.onedev.server.model.ProjectLastEventDate; +import io.onedev.server.model.ProjectLastActivityDate; import io.onedev.server.persistence.dao.EntityManager; -public interface ProjectLastEventDateManager extends EntityManager { +public interface ProjectLastEventDateManager extends EntityManager { - void create(ProjectLastEventDate lastEventDate); + void create(ProjectLastActivityDate lastEventDate); } diff --git a/server-core/src/main/java/io/onedev/server/entitymanager/impl/DefaultProjectLastEventDateManager.java b/server-core/src/main/java/io/onedev/server/entitymanager/impl/DefaultProjectLastEventDateManager.java index 26fe46127f..53abb46c37 100644 --- a/server-core/src/main/java/io/onedev/server/entitymanager/impl/DefaultProjectLastEventDateManager.java +++ b/server-core/src/main/java/io/onedev/server/entitymanager/impl/DefaultProjectLastEventDateManager.java @@ -7,7 +7,7 @@ import io.onedev.server.event.project.ProjectCreated; import io.onedev.server.event.project.ProjectEvent; import io.onedev.server.event.project.RefUpdated; import io.onedev.server.model.Project; -import io.onedev.server.model.ProjectLastEventDate; +import io.onedev.server.model.ProjectLastActivityDate; import io.onedev.server.persistence.annotation.Transactional; import io.onedev.server.persistence.dao.BaseEntityManager; import io.onedev.server.persistence.dao.Dao; @@ -17,7 +17,7 @@ import javax.inject.Singleton; import java.util.Date; @Singleton -public class DefaultProjectLastEventDateManager extends BaseEntityManager implements ProjectLastEventDateManager { +public class DefaultProjectLastEventDateManager extends BaseEntityManager implements ProjectLastEventDateManager { @Inject public DefaultProjectLastEventDateManager(Dao dao) { @@ -29,18 +29,17 @@ public class DefaultProjectLastEventDateManager extends BaseEntityManager } project.setPath(project.calcPath()); - ProjectLastEventDate lastEventDate = new ProjectLastEventDate(); - project.setLastEventDate(lastEventDate); + ProjectLastActivityDate lastEventDate = new ProjectLastActivityDate(); + project.setLastActivityDate(lastEventDate); lastEventDateManager.create(lastEventDate); dao.persist(project); @@ -519,7 +517,7 @@ public class DefaultProjectManager extends BaseEntityManager packBlobManager.delete(packBlob); dao.remove(project); - lastEventDateManager.delete(project.getLastEventDate()); + lastEventDateManager.delete(project.getLastActivityDate()); synchronized (repositoryCache) { Repository repository = repositoryCache.remove(project.getId()); @@ -622,7 +620,6 @@ public class DefaultProjectManager extends BaseEntityManager @Transactional @Override public void fork(Project from, Project to) { - to.getLastEventDate().setCommit(from.getLastEventDate().getCommit()); Long fromId = from.getId(); String fromPath = from.getPath(); Long toId = to.getId(); @@ -816,8 +813,8 @@ public class DefaultProjectManager extends BaseEntityManager cache.put(project.getId(), project.getFacade()); } - Map lastEventDates = new HashMap<>(); - for (ProjectLastEventDate lastEventDate : lastEventDateManager.query()) + Map lastEventDates = new HashMap<>(); + for (ProjectLastActivityDate lastEventDate : lastEventDateManager.query()) lastEventDates.put(lastEventDate.getId(), lastEventDate); logger.info("Checking projects..."); @@ -842,16 +839,6 @@ public class DefaultProjectManager extends BaseEntityManager checkGitDir(projectId); HookUtils.checkHooks(getGitDir(projectId)); checkGitConfig(projectId, project.getGitPackConfig()); - - if (project.isCodeManagement()) { - ProjectLastEventDate lastEventDate = lastEventDates.get(project.getLastEventDateId()); - RevCommit lastCommit = getLastCommit(getRepository(projectId)); - if (lastCommit != null) { - var lastCommitDate = lastCommit.getCommitterIdent().getWhen(); - if (lastEventDate.getCommit() == null || lastEventDate.getCommit().before(lastCommitDate)) - lastEventDate.setCommit(lastCommitDate); - } - } LinkedHashMap newReplicasOfProject; var replica = new ProjectReplica(); @@ -877,7 +864,7 @@ public class DefaultProjectManager extends BaseEntityManager throw new RuntimeException(e); } } - updateActiveServer(projectId, newReplicasOfProject, false); + updateActiveServer(projectId, newReplicasOfProject, false); } } } @@ -1062,16 +1049,16 @@ public class DefaultProjectManager extends BaseEntityManager for (var order: orders) { if (order.getExpression() instanceof SingularAttributePath) { var expr = (SingularAttributePath) order.getExpression(); - if (expr.getAttribute().getName().equals(ProjectLastEventDate.PROP_ACTIVITY) + if (expr.getAttribute().getName().equals(ProjectLastActivityDate.PROP_VALUE) && expr.getPathSource() instanceof SingularAttributePath - && ((SingularAttributePath) expr.getPathSource()).getAttribute().getName().equals(Project.PROP_LAST_EVENT_DATE)) { + && ((SingularAttributePath) expr.getPathSource()).getAttribute().getName().equals(Project.PROP_LAST_ACTIVITY_DATE)) { found = true; break; } } } if (!found) - orders.add(builder.desc(ProjectQuery.getPath(root, Project.PROP_LAST_EVENT_DATE + "." + ProjectLastEventDate.PROP_ACTIVITY))); + orders.add(builder.desc(ProjectQuery.getPath(root, Project.PROP_LAST_ACTIVITY_DATE + "." + ProjectLastActivityDate.PROP_VALUE))); query.orderBy(orders); diff --git a/server-core/src/main/java/io/onedev/server/model/Project.java b/server-core/src/main/java/io/onedev/server/model/Project.java index 9aa7e74520..42720137c6 100644 --- a/server-core/src/main/java/io/onedev/server/model/Project.java +++ b/server-core/src/main/java/io/onedev/server/model/Project.java @@ -145,7 +145,7 @@ import io.onedev.server.xodus.CommitInfoManager; @Table( indexes={ @Index(columnList="o_parent_id"), @Index(columnList="o_forkedFrom_id"), - @Index(columnList="o_lastEventDate_id"), @Index(columnList=PROP_NAME), + @Index(columnList="o_lastActivityDate_id"), @Index(columnList=PROP_NAME), @Index(columnList=PROP_PATH) }, uniqueConstraints={@UniqueConstraint(columnNames={"o_parent_id", PROP_NAME})} @@ -187,10 +187,8 @@ public class Project extends AbstractEntity implements LabelSupport QUERY_FIELDS = Lists.newArrayList( - NAME_NAME, NAME_KEY, NAME_PATH, NAME_LABEL, NAME_SERVICE_DESK_EMAIL_ADDRESS, NAME_ID, NAME_DESCRIPTION, NAME_LAST_ACTIVITY_DATE, NAME_LAST_COMMIT_DATE); + NAME_NAME, NAME_KEY, NAME_PATH, NAME_LABEL, NAME_SERVICE_DESK_EMAIL_ADDRESS, NAME_ID, NAME_DESCRIPTION, NAME_LAST_ACTIVITY_DATE); public static final Map> SORT_FIELDS = new LinkedHashMap<>(); static { @@ -228,8 +226,7 @@ public class Project extends AbstractEntity implements LabelSupport(PROP_NAME)); SORT_FIELDS.put(NAME_KEY, new SortField<>(PROP_KEY)); SORT_FIELDS.put(NAME_SERVICE_DESK_EMAIL_ADDRESS, new SortField<>(PROP_SERVICE_DESK_EMAIL_ADDRESS)); - SORT_FIELDS.put(NAME_LAST_ACTIVITY_DATE, new SortField<>(PROP_LAST_EVENT_DATE + "." + ProjectLastEventDate.PROP_ACTIVITY, DESCENDING)); - SORT_FIELDS.put(NAME_LAST_COMMIT_DATE, new SortField<>(PROP_LAST_EVENT_DATE + "." + ProjectLastEventDate.PROP_COMMIT, DESCENDING)); + SORT_FIELDS.put(NAME_LAST_ACTIVITY_DATE, new SortField<>(PROP_LAST_ACTIVITY_DATE + "." + ProjectLastActivityDate.PROP_VALUE, DESCENDING)); } static ThreadLocal> stack = ThreadLocal.withInitial(() -> new Stack<>()); @@ -257,7 +254,7 @@ public class Project extends AbstractEntity implements LabelSupport getIncomingRequests() { @@ -756,7 +753,7 @@ public class Project extends AbstractEntity implements LabelSupport { - - private static final long serialVersionUID = 1L; - - private final int operator; - - private final String value; - - private final Date date; - - public CommitDateCriteria(String value, int operator) { - date = EntityQuery.getDateValue(value); - this.operator = operator; - this.value = value; - } - - @Override - public Predicate getPredicate(@Nullable ProjectScope projectScope, CriteriaQuery query, From from, CriteriaBuilder builder) { - Path attribute = ProjectQuery.getPath(from, Project.PROP_LAST_EVENT_DATE + "." + ProjectLastEventDate.PROP_COMMIT); - if (operator == ProjectQueryLexer.IsUntil) - return builder.lessThan(attribute, date); - else - return builder.greaterThan(attribute, date); - } - - @Override - public boolean matches(Project project) { - if (project.getLastEventDate().getCommit() != null) { - if (operator == ProjectQueryLexer.IsUntil) - return project.getLastEventDate().getCommit().before(date); - else - return project.getLastEventDate().getCommit().after(date); - } else { - return false; - } - } - - @Override - public String toStringWithoutParens() { - return Criteria.quote(Project.NAME_LAST_COMMIT_DATE) + " " - + ProjectQuery.getRuleName(operator) + " " - + Criteria.quote(value); - } - -} diff --git a/server-core/src/main/java/io/onedev/server/search/entity/project/LastActivityDateCriteria.java b/server-core/src/main/java/io/onedev/server/search/entity/project/LastActivityDateCriteria.java index a96b81977e..1433816941 100644 --- a/server-core/src/main/java/io/onedev/server/search/entity/project/LastActivityDateCriteria.java +++ b/server-core/src/main/java/io/onedev/server/search/entity/project/LastActivityDateCriteria.java @@ -10,7 +10,7 @@ import javax.persistence.criteria.Path; import javax.persistence.criteria.Predicate; import io.onedev.server.model.Project; -import io.onedev.server.model.ProjectLastEventDate; +import io.onedev.server.model.ProjectLastActivityDate; import io.onedev.server.search.entity.EntityQuery; import io.onedev.server.util.ProjectScope; import io.onedev.server.util.criteria.Criteria; @@ -41,7 +41,7 @@ public class LastActivityDateCriteria extends Criteria { @Override public Predicate getPredicate(@Nullable ProjectScope projectScope, CriteriaQuery query, From from, CriteriaBuilder builder) { - Path attribute = ProjectQuery.getPath(from, Project.PROP_LAST_EVENT_DATE + "." + ProjectLastEventDate.PROP_ACTIVITY); + Path attribute = ProjectQuery.getPath(from, Project.PROP_LAST_ACTIVITY_DATE + "." + ProjectLastActivityDate.PROP_VALUE); if (operator == ProjectQueryLexer.IsUntil) return builder.lessThan(attribute, date); else @@ -51,9 +51,9 @@ public class LastActivityDateCriteria extends Criteria { @Override public boolean matches(Project project) { if (operator == ProjectQueryLexer.IsUntil) - return project.getLastEventDate().getActivity().before(date); + return project.getLastActivityDate().getValue().before(date); else - return project.getLastEventDate().getActivity().after(date); + return project.getLastActivityDate().getValue().after(date); } @Override diff --git a/server-core/src/main/java/io/onedev/server/search/entity/project/ProjectQuery.java b/server-core/src/main/java/io/onedev/server/search/entity/project/ProjectQuery.java index 7d8ad409b0..c2aaafcd5e 100644 --- a/server-core/src/main/java/io/onedev/server/search/entity/project/ProjectQuery.java +++ b/server-core/src/main/java/io/onedev/server/search/entity/project/ProjectQuery.java @@ -182,10 +182,7 @@ public class ProjectQuery extends EntityQuery { break; case IsUntil: case IsSince: - if (fieldName.equals(Project.NAME_LAST_ACTIVITY_DATE)) - criterias.add(new LastActivityDateCriteria(value, operator)); - else - criterias.add(new CommitDateCriteria(value, operator)); + criterias.add(new LastActivityDateCriteria(value, operator)); break; default: throw new ExplicitException("Unexpected operator " + getRuleName(operator)); @@ -272,7 +269,7 @@ public class ProjectQuery extends EntityQuery { case IsUntil: case IsSince: if (!fieldName.equals(Project.NAME_LAST_ACTIVITY_DATE) - && !fieldName.equals(Project.NAME_LAST_COMMIT_DATE)) { + && !fieldName.equals(Project.NAME_LAST_ACTIVITY_DATE)) { throw newOperatorException(fieldName, operator); } break; diff --git a/server-core/src/main/java/io/onedev/server/web/behavior/ProjectQueryBehavior.java b/server-core/src/main/java/io/onedev/server/web/behavior/ProjectQueryBehavior.java index cb3fe09f8b..ddeaf4d870 100644 --- a/server-core/src/main/java/io/onedev/server/web/behavior/ProjectQueryBehavior.java +++ b/server-core/src/main/java/io/onedev/server/web/behavior/ProjectQueryBehavior.java @@ -87,7 +87,7 @@ public class ProjectQueryBehavior extends ANTLRAssistBehavior { String fieldName = ProjectQuery.getValue(fieldElements.get(0).getMatchedText()); try { ProjectQuery.checkField(fieldName, operator); - if (fieldName.equals(Project.NAME_LAST_ACTIVITY_DATE) || fieldName.equals(Project.NAME_LAST_COMMIT_DATE)) { + if (fieldName.equals(Project.NAME_LAST_ACTIVITY_DATE)) { List suggestions = SuggestionUtils.suggest(DateUtils.RELAX_DATE_EXAMPLES, matchWith); return !suggestions.isEmpty()? suggestions: null; } else if (fieldName.equals(Project.NAME_NAME)) { diff --git a/server-core/src/main/java/io/onedev/server/xodus/DefaultCommitInfoManager.java b/server-core/src/main/java/io/onedev/server/xodus/DefaultCommitInfoManager.java index ec4990b868..f7e9ed6d03 100644 --- a/server-core/src/main/java/io/onedev/server/xodus/DefaultCommitInfoManager.java +++ b/server-core/src/main/java/io/onedev/server/xodus/DefaultCommitInfoManager.java @@ -23,7 +23,6 @@ import java.util.Iterator; import java.util.LinkedHashMap; import java.util.List; import java.util.Map; -import java.util.Objects; import java.util.Optional; import java.util.Set; import java.util.Stack; @@ -31,6 +30,7 @@ import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.atomic.AtomicBoolean; import java.util.concurrent.atomic.AtomicInteger; import java.util.function.Consumer; +import java.util.stream.Collectors; import javax.annotation.Nullable; import javax.inject.Inject; @@ -57,8 +57,6 @@ import org.slf4j.LoggerFactory; import com.google.common.base.Preconditions; import com.google.common.base.Splitter; import com.google.common.collect.Sets; -import com.hazelcast.map.EntryProcessor; -import com.hazelcast.map.IMap; import io.onedev.commons.loader.ManagedSerializedForm; import io.onedev.commons.utils.ExplicitException; @@ -81,7 +79,6 @@ import io.onedev.server.event.project.ActiveServerChanged; import io.onedev.server.event.project.RefUpdated; import io.onedev.server.event.project.issue.IssueCommitsAttached; import io.onedev.server.event.system.SystemStarted; -import io.onedev.server.event.system.SystemStarting; import io.onedev.server.git.GitContribution; import io.onedev.server.git.GitContributor; import io.onedev.server.git.GitUtils; @@ -211,9 +208,7 @@ public class DefaultCommitInfoManager extends AbstractEnvironmentManager private final Map totalCommitCountCache = new ConcurrentHashMap<>(); - private final Map> usersCache = new ConcurrentHashMap<>(); - - private volatile IMap> contributedProjects; + private final Map, Set>> usersCache = new ConcurrentHashMap<>(); @Inject public DefaultCommitInfoManager(ProjectManager projectManager, @@ -257,6 +252,19 @@ public class DefaultCommitInfoManager extends AbstractEnvironmentManager Repository repository = projectManager.getRepository(project.getId()); Pair result = env.computeInTransaction(txn -> { + var users = usersCache.get(project.getId()); + if (users == null) { + byte[] userBytes = readBytes(defaultStore, txn, USERS_KEY); + if (userBytes != null) { + Set nameAndEmails = SerializationUtils.deserialize(userBytes); + users = new Pair<>(nameAndEmails, + nameAndEmails.stream().map(NameAndEmail::getEmailAddress).collect(Collectors.toSet())); + } else { + users = new Pair<>(new HashSet<>(), new HashSet<>()); + } + usersCache.put(project.getId(), users); + } + ByteIterable commitKey = new CommitByteIterable(commitId); byte[] commitBytes = readBytes(commitsStore, txn, commitKey); @@ -288,12 +296,7 @@ public class DefaultCommitInfoManager extends AbstractEnvironmentManager Map commitCountCache = new HashMap<>(); - Set users; - byte[] userBytes = readBytes(defaultStore, txn, USERS_KEY); - if (userBytes != null) - users = SerializationUtils.deserialize(userBytes); - else - users = new HashSet<>(); + var users = usersCache.get(project.getId()); var usersChanged = new AtomicBoolean(false); new ElementPumper() { @@ -384,14 +387,16 @@ public class DefaultCommitInfoManager extends AbstractEnvironmentManager } if (currentCommit.getCommitter() != null) { - if (users.add(new NameAndEmail(currentCommit.getCommitter()))) + if (users.getLeft().add(new NameAndEmail(currentCommit.getCommitter()))) usersChanged.set(true); + users.getRight().add(currentCommit.getCommitter().getEmailAddress()); } if (currentCommit.getAuthor() != null) { NameAndEmail nameAndEmail = new NameAndEmail(currentCommit.getAuthor()); - if (users.add(nameAndEmail)) + if (users.getLeft().add(nameAndEmail)) usersChanged.set(true); + users.getRight().add(nameAndEmail.getEmailAddress()); ByteIterable authorKey = new ArrayByteIterable(SerializationUtils.serialize(nameAndEmail)); int userIndex = readInt(userToIndexStore, txn, authorKey, -1); @@ -475,10 +480,8 @@ public class DefaultCommitInfoManager extends AbstractEnvironmentManager writeInt(defaultStore, txn, NEXT_PATH_INDEX_KEY, nextIndex.path); if (usersChanged.get()) { - userBytes = SerializationUtils.serialize((Serializable) users); + var userBytes = SerializationUtils.serialize((Serializable) users.getLeft()); defaultStore.put(txn, USERS_KEY, new ArrayByteIterable(userBytes)); - usersCache.remove(project.getId()); - updateContributedProjects(project.getId(), users); } for (Map.Entry entry : commitCountCache.entrySet()) @@ -497,26 +500,6 @@ public class DefaultCommitInfoManager extends AbstractEnvironmentManager logger.debug("Collected commit information (project: {}, ref: {})", project.getPath(), refName); } - private void updateContributedProjects(Long projectId, Set users) { - Set emailAddresses = users.stream() - .map(NameAndEmail::getEmailAddress) - .collect(toSet()); - - contributedProjects.executeOnKeys(emailAddresses, new EntryProcessor, Object>() { - @Override - public Object process(IMap.Entry> entry) { - Set contributedProjectsOfEmail = entry.getValue(); - if (contributedProjectsOfEmail == null) { - contributedProjectsOfEmail = new HashSet<>(); - } - if (contributedProjectsOfEmail.add(projectId)) { - entry.setValue(contributedProjectsOfEmail); - } - return null; - } - }); - } - private void collectContributions(Project project, ObjectId commitId) { Environment env = getEnv(project.getId().toString()); Store defaultStore = getStore(env, DEFAULT_STORE); @@ -908,25 +891,14 @@ public class DefaultCommitInfoManager extends AbstractEnvironmentManager @Override public List call() { - List users = usersCache.get(projectId); - if (users == null) { - Environment env = getEnv(projectId.toString()); - Store store = getStore(env, DEFAULT_STORE); - - users = env.computeInReadonlyTransaction(txn -> { - byte[] bytes = readBytes(store, txn, USERS_KEY); - if (bytes != null) { - List innerUsers = - new ArrayList<>(SerializationUtils.deserialize(bytes)); - Collections.sort(innerUsers); - return innerUsers; - } else { - return new ArrayList<>(); - } - }); - usersCache.put(projectId, users); + var users = usersCache.get(projectId); + if (users != null) { + var sortedUsers = new ArrayList<>(users.getLeft()); + Collections.sort(sortedUsers); + return sortedUsers; + } else { + return new ArrayList<>(); } - return users; } }); @@ -1112,8 +1084,37 @@ public class DefaultCommitInfoManager extends AbstractEnvironmentManager sessionManager.run(() -> { Project project = projectManager.load(projectId); List collectingWorks = new ArrayList<>(); - for (Object work : works) - collectingWorks.add((CollectingWork) work); + for (Object work : works) { + if (work instanceof CollectingWork) { + collectingWorks.add((CollectingWork) work); + } else if (work instanceof CheckingWork) { + try (RevWalk revWalk = new RevWalk(projectManager.getRepository(projectId))) { + Collection refs = new ArrayList<>(); + refs.addAll(projectManager.getRepository(projectId).getRefDatabase() + .getRefsByPrefix(Constants.R_HEADS)); + refs.addAll(projectManager.getRepository(projectId).getRefDatabase() + .getRefsByPrefix(Constants.R_TAGS)); + + for (Ref ref : refs) { + RevObject revObj; + try { + revObj = revWalk.peel(revWalk.parseAny(ref.getObjectId())); + } catch (MissingObjectException e) { + var message = String.format("%s (project id: %d, ref: %s)", e.getMessage(), + projectId, ref.getName()); + throw new ExplicitException(message); + } + if (revObj instanceof RevCommit) { + RevCommit commit = (RevCommit) revObj; + collectingWorks.add(new CollectingWork(CHECK_PRIORITY, commit.copy(), + commit.getCommitTime(), ref.getName())); + } + } + } catch (IOException e) { + throw new RuntimeException(e); + } + } + } collectingWorks.sort(new CommitTimeComparator()); for (CollectingWork work : collectingWorks) @@ -1124,65 +1125,12 @@ public class DefaultCommitInfoManager extends AbstractEnvironmentManager }; } - private boolean collect(Long projectId, int priority) { - List works = new ArrayList<>(); - try (RevWalk revWalk = new RevWalk(projectManager.getRepository(projectId))) { - Collection refs = new ArrayList<>(); - refs.addAll(projectManager.getRepository(projectId).getRefDatabase().getRefsByPrefix(Constants.R_HEADS)); - refs.addAll(projectManager.getRepository(projectId).getRefDatabase().getRefsByPrefix(Constants.R_TAGS)); - - for (Ref ref : refs) { - RevObject revObj; - try { - revObj = revWalk.peel(revWalk.parseAny(ref.getObjectId())); - } catch (MissingObjectException e) { - var message = String.format("%s (project id: %d, ref: %s)", e.getMessage(), projectId, ref.getName()); - throw new ExplicitException(message); - } - if (revObj instanceof RevCommit) { - RevCommit commit = (RevCommit) revObj; - works.add(new CollectingWork(priority, commit.copy(), - commit.getCommitTime(), ref.getName())); - } - } - } catch (IOException e) { - throw new RuntimeException(e); - } - - if (!works.isEmpty()) { - works.sort(new CommitTimeComparator()); - - for (CollectingWork work : works) - batchWorkManager.submit(getBatchWorker(projectId), work); - return true; - } else { - return false; - } - } - - @Sessional - @Listen - public void on(SystemStarting event) { - contributedProjects = clusterManager.getHazelcastInstance().getMap("contributedProjects"); - } - @Sessional @Listen public void on(SystemStarted event) { - logger.info("Caching code contribution info..."); for (var projectId: projectManager.getActiveIds()) { checkVersion(getEnvDir(projectId.toString())); - if (collect(projectId, CHECK_PRIORITY)) { - Environment env = getEnv(projectId.toString()); - Store store = getStore(env, DEFAULT_STORE); - - env.computeInReadonlyTransaction(txn -> { - byte[] bytes = readBytes(store, txn, USERS_KEY); - if (bytes != null) - updateContributedProjects(projectId, SerializationUtils.deserialize(bytes)); - return null; - }); - } + batchWorkManager.submit(getBatchWorker(projectId), new CheckingWork(CHECK_PRIORITY)); } } @@ -1191,7 +1139,7 @@ public class DefaultCommitInfoManager extends AbstractEnvironmentManager public void on(ActiveServerChanged event) { for (var projectId: event.getProjectIds()) { checkVersion(getEnvDir(projectId.toString())); - collect(projectId, CHECK_PRIORITY); + batchWorkManager.submit(getBatchWorker(projectId), new CheckingWork(CHECK_PRIORITY)); } } @@ -1258,6 +1206,14 @@ public class DefaultCommitInfoManager extends AbstractEnvironmentManager }); } + static class CheckingWork extends Prioritized { + + public CheckingWork(int priority) { + super(priority); + } + + } + static class CollectingWork extends Prioritized { private final String refName; @@ -1564,53 +1520,54 @@ public class DefaultCommitInfoManager extends AbstractEnvironmentManager @Sessional @Override public Map> getUserCommits(User user, Date fromDate, Date toDate) { + var emailAddresses = user.getEmailAddresses().stream() + .filter(it -> it.isVerified()) + .map(it -> it.getValue()) + .collect(toSet()); + var userCommits = new HashMap>(); - if (contributedProjects != null) { - var emailAddresses = user.getEmailAddresses().stream() - .filter(it -> it.isVerified()) - .map(it -> it.getValue()) - .collect(toSet()); - var cache = projectManager.cloneCache(); - var projectIds = new HashSet(); - contributedProjects.getAll(emailAddresses).values().stream() - .filter(Objects::nonNull) - .forEach(projectIds::addAll); - for (var projectId: projectIds) { - var project = cache.get(projectId); - if (project != null && project.isCodeManagement() && project.getForkedFromId() == null) { - var activeServer = projectManager.getActiveServer(projectId, false); - if (activeServer != null) { - userCommits.put(projectId, clusterManager.runOnServer(activeServer, new ClusterTask<>() { + Map>> result = clusterManager.runOnAllServers(new ClusterTask<>() { - private static final long serialVersionUID = 1L; - - @Override - public Map call() { - Environment env = getEnv(projectId.toString()); - Store userCommitsStore = getStore(env, USER_COMMITS_STORE); - - return env.computeInReadonlyTransaction(new TransactionalComputable>() { - - @Override - public Map compute(Transaction txn) { - var userCommits = new HashMap(); - for (var emailAddress: emailAddresses) { - deserializeUserCommits(readBytes(userCommitsStore, txn, new StringByteIterable(emailAddress))).entrySet().forEach(it -> { - if (it.getValue() >= fromDate.getTime() && it.getValue() <= toDate.getTime()) - userCommits.put(it.getKey(), it.getValue()); - }); - } - return userCommits; + @Override + public Map> call() { + var localServer = clusterManager.getLocalServerAddress(); + var userCommits = new HashMap>(); + for (var entry: usersCache.entrySet()) { + var projectId = entry.getKey(); + if (localServer.equals(projectManager.getActiveServer(projectId, false)) + && emailAddresses.stream().anyMatch(entry.getValue().getRight()::contains)) { + var project = projectManager.findFacade(projectId); + if (project != null && project.isCodeManagement() && project.getForkedFromId() == null) { + Environment env = getEnv(projectId.toString()); + Store userCommitsStore = getStore(env, USER_COMMITS_STORE); + + userCommits.put(projectId, env.computeInReadonlyTransaction(new TransactionalComputable>() { + + @Override + public Map compute(Transaction txn) { + var userCommits = new HashMap(); + for (var emailAddress : emailAddresses) { + deserializeUserCommits( + readBytes(userCommitsStore, txn, new StringByteIterable(emailAddress))) + .entrySet().forEach(it -> { + if (it.getValue() >= fromDate.getTime() + && it.getValue() <= toDate.getTime()) + userCommits.put(it.getKey(), it.getValue()); + }); } - - }); - } - - })); + return userCommits; + } + + })); + } } } + return userCommits; } - } + + }); + for (var entry: result.entrySet()) + userCommits.putAll(entry.getValue()); return userCommits; } diff --git a/server-product/src/main/java/io/onedev/server/product/ProductServletConfigurator.java b/server-product/src/main/java/io/onedev/server/product/ProductServletConfigurator.java index 4d20288ab3..ad8c1c3d37 100644 --- a/server-product/src/main/java/io/onedev/server/product/ProductServletConfigurator.java +++ b/server-product/src/main/java/io/onedev/server/product/ProductServletConfigurator.java @@ -167,9 +167,9 @@ public class ProductServletConfigurator implements ServletConfigurator { context.addServlet(new ServletHolder(jerseyServlet), "/~api/*"); context.addServlet(new ServletHolder(serverServlet), "/~server"); - var mcpServletHolder = new ServletHolder(mcpServerServlet); - context.addServlet(mcpServletHolder, "/~mcp"); - context.addServlet(mcpServletHolder, "/~mcp/*"); + //var mcpServletHolder = new ServletHolder(mcpServerServlet); + //context.addServlet(mcpServletHolder, "/~mcp"); + //context.addServlet(mcpServletHolder, "/~mcp/*"); } }