Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

XWIKI-22323: Refactoring operation should wait for the Solr index to be empty before proceeding #3403

Merged
merged 15 commits into from
Oct 14, 2024
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
15 commits
Select commit Hold shift + click to select a range
8be8237
XWIKI-22323: Refactoring operation should wait for the Solr index to …
michitux Sep 9, 2024
5880ce8
XWIKI-22323: Refactoring operation should wait for the Solr index to …
michitux Sep 10, 2024
b0e35f5
XWIKI-22323: Refactoring operation should wait for the Solr index to …
michitux Sep 10, 2024
8934071
XWIKI-22323: Refactoring operation should wait for the Solr index to …
michitux Sep 11, 2024
2f8e942
XWIKI-22323: Refactoring operation should wait for the Solr index to …
michitux Sep 11, 2024
eb7a6dd
XWIKI-22323: Refactoring operation should wait for the Solr index to …
michitux Sep 11, 2024
7045cb5
XWIKI-22323: Refactoring operation should wait for the Solr index to …
michitux Sep 11, 2024
270589c
XWIKI-22323: Refactoring operation should wait for the Solr index to …
michitux Sep 18, 2024
dd85ea0
XWIKI-22323: Refactoring operation should wait for the Solr index to …
michitux Sep 18, 2024
f838d65
XWIKI-22323: Refactoring operation should wait for the Solr index to …
michitux Sep 18, 2024
9bd5897
XWIKI-22323: Refactoring operation should wait for the Solr index to …
michitux Sep 18, 2024
1142d6b
XWIKI-22323: Refactoring operation should wait for the Solr index to …
michitux Oct 1, 2024
e4e7aea
XWIKI-22323: Refactoring operation should wait for the Solr index to …
michitux Oct 1, 2024
f4b5a9f
XWIKI-22323: Refactoring operation should wait for the Solr index to …
michitux Oct 8, 2024
4f0ab9d
XWIKI-22323: Refactoring operation should wait for the Solr index to …
michitux Oct 14, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
/*
* See the NOTICE file distributed with this work for additional
* information regarding copyright ownership.
*
* This is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as
* published by the Free Software Foundation; either version 2.1 of
* the License, or (at your option) any later version.
*
* This software is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this software; if not, write to the Free
* Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
* 02110-1301 USA, or see the FSF site: http://www.fsf.org.
*/
package org.xwiki.link;

import java.util.concurrent.TimeUnit;

import org.xwiki.component.annotation.Role;
import org.xwiki.stability.Unstable;

/**
* Provides access to the indexing status of links in the {@link LinkStore}.
*
* @version $Id$
* @since 16.8.0RC1
* @since 15.10.13
* @since 16.4.4
*
* @version $Id$
*/
@Unstable
@Role
public interface LinkIndexingStatus
michitux marked this conversation as resolved.
Show resolved Hide resolved
{
/**
* @return the number of entities that are waiting to be indexed by the link store
*/
int getQueueSize();

/**
* Wait for the link indexing queue to become empty, or the timeout to happen.
*
* @param timeout the maximum wait time
* @param unit the unit of the wait time
* @return the size of the queue after waiting
* @throws InterruptedException if interrupted while waiting
*/
int waitForEmpty(long timeout, TimeUnit unit) throws InterruptedException;
}
Original file line number Diff line number Diff line change
Expand Up @@ -20,9 +20,11 @@
package org.xwiki.link;

import java.util.Set;
import java.util.concurrent.CompletableFuture;

import org.xwiki.component.annotation.Role;
import org.xwiki.model.reference.EntityReference;
import org.xwiki.stability.Unstable;

/**
* Allow accessing the links extracted from various entities.
Expand All @@ -48,4 +50,32 @@ public interface LinkStore
* @throws LinkException when failing to load the backlinks
*/
Set<EntityReference> resolveBackLinkedEntities(EntityReference reference) throws LinkException;

/**
* Get a {@link ReadyIndicator} to wait on for the link store to become ready.
*
* @since 16.8.0RC1
* @since 15.10.13
* @since 16.4.4
* @return the ready indicator
*/
@Unstable
default ReadyIndicator waitReady()
{
/**
* Fake implementation of {@link ReadyIndicator}.
*/
class DummyReadyIndicator extends CompletableFuture<Boolean> implements ReadyIndicator
{
@Override
public int getProgressPercentage()
{
return 100;
}
}

DummyReadyIndicator readyIndicator = new DummyReadyIndicator();
readyIndicator.complete(Boolean.TRUE);
return readyIndicator;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
/*
* See the NOTICE file distributed with this work for additional
* information regarding copyright ownership.
*
* This is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as
* published by the Free Software Foundation; either version 2.1 of
* the License, or (at your option) any later version.
*
* This software is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this software; if not, write to the Free
* Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
* 02110-1301 USA, or see the FSF site: http://www.fsf.org.
*/
package org.xwiki.link;

import java.util.concurrent.Future;

import org.xwiki.stability.Unstable;

/**
* An indicator if the link store is ready, i.e., has completed all indexing tasks that have been submitted before
* the indicator was requested. It resolves to {@link Boolean#TRUE} when all indexing tasks that were before it in
* the queue have been finished and may resolve to {@link Boolean#FALSE} when the queue has been stopped.
*
* @since 16.8.0RC1
* @since 15.10.13
* @since 16.4.4
* @version $Id$
*/
@Unstable
public interface ReadyIndicator extends Future<Boolean>
{
/**
*
* @return a value between 0 and 100 that expresses the progress towards being ready. Values might jump
* non-linearly and might not be fully accurate.
*/
int getProgressPercentage();
}
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,11 @@
<artifactId>xwiki-platform-query-manager</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.xwiki.platform</groupId>
<artifactId>xwiki-platform-link</artifactId>
<version>${project.version}</version>
</dependency>

<!-- Testing dependencies -->
<dependency>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@
package org.xwiki.refactoring.internal.listener;

import java.util.Set;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
import java.util.function.Predicate;

import javax.inject.Inject;
Expand All @@ -31,6 +33,8 @@
import org.xwiki.component.annotation.Component;
import org.xwiki.job.JobContext;
import org.xwiki.job.event.status.JobProgressManager;
import org.xwiki.link.LinkStore;
import org.xwiki.link.ReadyIndicator;
import org.xwiki.model.reference.DocumentReference;
import org.xwiki.model.reference.EntityReference;
import org.xwiki.observation.event.AbstractLocalEventListener;
Expand Down Expand Up @@ -80,6 +84,9 @@ public class BackLinkUpdaterListener extends AbstractLocalEventListener
@Inject
private JobContext jobContext;

@Inject
private LinkStore linkStore;
michitux marked this conversation as resolved.
Show resolved Hide resolved

/**
* Default constructor.
*/
Expand Down Expand Up @@ -139,6 +146,12 @@ private void updateBackLinks(DocumentReference source, DocumentReference target,
{
this.logger.info("Updating the back-links for document [{}].", source);

if (this.jobContext.getCurrentJob() != null) {
// We're inside a job, so some waiting should be okay. Wait for the indexing of the link store to finish.
// TODO: some jobs might indicate already that they don't want to wait. Add support for that.
waitForLinkIndexing();
}

// TODO: it's possible to optimize a bit the actual entities to modify (especially which translation of the
// document to load and parse) since we have the information in the store
Set<DocumentReference> backlinkDocumentReferences = this.modelBridge.getBackLinkedDocuments(source);
Expand All @@ -157,4 +170,41 @@ private void updateBackLinks(DocumentReference source, DocumentReference target,
this.progressManager.popLevelProgress(this);
}
}

private void waitForLinkIndexing()
{
this.progressManager.pushLevelProgress(100, this);
int percent = 0;
this.logger.info("Waiting for the link index to be updated.");
ReadyIndicator readyIndicator = this.linkStore.waitReady();
Boolean isReady = null;
while (isReady == null) {
try {
isReady = readyIndicator.get(1, TimeUnit.SECONDS);
} catch (TimeoutException e) {
for (int i = percent; i < readyIndicator.getProgressPercentage(); ++i) {
this.progressManager.startStep(this);
}

// TODO: after some time, ask if the user wants to continue waiting.
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
this.logger.warn("Interrupted while waiting for the link indexing to be updated.");
isReady = Boolean.FALSE;
} catch (Exception e) {
// Catch a generic Exception here and not ExecutionException to not increase class-fanout complexity.
this.logger.error("Link indexing stopped with an exception while waiting for indexing to complete.",
e.getCause());
isReady = Boolean.FALSE;
}
}

if (Boolean.TRUE.equals(isReady)) {
this.logger.info("The link index is ready now, starting the update of the back-links.");
} else {
this.logger.warn("The link index didn't become ready, starting the update of the back-links "
+ "nevertheless as some updates might be better than none.");
}
this.progressManager.popLevelProgress(this);
}
}
Loading