Skip to content

Commit

Permalink
Merge pull request mvnpm#1916 from phillip-kruger/error-retry
Browse files Browse the repository at this point in the history
Added retry on error daily and from UI
  • Loading branch information
phillip-kruger authored Nov 23, 2023
2 parents 1e877d2 + 33c22db commit 9d23ac3
Show file tree
Hide file tree
Showing 6 changed files with 114 additions and 19 deletions.
4 changes: 2 additions & 2 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
<modelVersion>4.0.0</modelVersion>
<groupId>io.mvnpm</groupId>
<artifactId>mvnpm</artifactId>
<version>3.0.11-SNAPSHOT</version>
<version>3.0.12-SNAPSHOT</version>
<name>mvnpm</name>
<description>Maven on NPM</description>
<url>https://mvnpm.org/</url>
Expand Down Expand Up @@ -53,7 +53,7 @@
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<quarkus.platform.artifact-id>quarkus-bom</quarkus.platform.artifact-id>
<quarkus.platform.group-id>io.quarkus.platform</quarkus.platform.group-id>
<quarkus.platform.version>3.5.2</quarkus.platform.version>
<quarkus.platform.version>3.5.3</quarkus.platform.version>
<skipITs>true</skipITs>
<surefire-plugin.version>3.1.2</surefire-plugin.version>
<formatter.plugin.version>2.23.0</formatter.plugin.version>
Expand Down
25 changes: 25 additions & 0 deletions src/main/java/io/mvnpm/mavencentral/sync/CentralSyncApi.java
Original file line number Diff line number Diff line change
Expand Up @@ -139,6 +139,31 @@ public CentralSyncItem requestFullSync(@PathParam("groupId") String groupId, @Pa
return centralSyncItemService.findOrCreate(groupId, artifactId, version);
}

@GET
@Path("/retry/{groupId}/{artifactId}")
public CentralSyncItem retryFullSync(@PathParam("groupId") String groupId, @PathParam("artifactId") String artifactId,
@DefaultValue("latest") @QueryParam("version") String version) {

if (version.equalsIgnoreCase("latest")) {
version = getLatestVersion(groupId, artifactId);
}

CentralSyncItem centralSyncItem = centralSyncItemService.findOrCreate(groupId, artifactId, version);

// Already being synced
if (centralSyncItem.isInProgress() || centralSyncItem.stage.equals(Stage.INIT))
return centralSyncItem;

// Check the remote status
if (!centralSyncItem.alreadyRealeased() && centralSyncService.isInMavenCentralRemoteCheck(centralSyncItem)) {
centralSyncItem.stage = Stage.RELEASED;
centralSyncItemService.merge(centralSyncItem);
return centralSyncItem;
}

return continuousSyncService.tryErroredItemAgain(centralSyncItem);
}

@GET
@Path("/item/{stage}")
public List<CentralSyncItem> getItems(@PathParam("stage") Stage stage) {
Expand Down
4 changes: 2 additions & 2 deletions src/main/java/io/mvnpm/mavencentral/sync/CentralSyncItem.java
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,8 @@
@Entity
@IdClass(Gav.class)
@NamedQueries({
@NamedQuery(name = "CentralSyncItem.findByStage", query = "from CentralSyncItem where stage = ?1 order by stageChangeTime LIMIT 999"),
@NamedQuery(name = "CentralSyncItem.findUploadedButNotReleased", query = "from CentralSyncItem where stage IN ?1 order by stageChangeTime")
@NamedQuery(name = "CentralSyncItem.findByStage", query = "from CentralSyncItem where stage = ?1 order by stageChangeTime DESC LIMIT 999"),
@NamedQuery(name = "CentralSyncItem.findUploadedButNotReleased", query = "from CentralSyncItem where stage IN ?1 order by stageChangeTime DESC")
})
public class CentralSyncItem extends PanacheEntityBase {
@Id
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -243,7 +243,7 @@ void onStart(@Observes StartupEvent ev) throws StatusCheckException {
// Reset promotion if the server restarts
resetPromotion();

eventLogApi.clearLog();
//eventLogApi.clearLog();
}

private void resetUpload() {
Expand Down Expand Up @@ -271,10 +271,37 @@ private boolean isInternal(String groupId, String artifactId) {
(groupId.equals("org.mvnpm") && artifactId.equals("vaadin-web-components")); // Before we used the @mvnpm namespave
}

@Scheduled(cron = "{mvnpm.checkerror.cron.expr}", concurrentExecution = SKIP)
@Blocking
public void checkError() {
try {
Log.debug("Starting error retry...");
List<CentralSyncItem> error = CentralSyncItem.findByStage(Stage.ERROR);

if (error != null && !error.isEmpty()) {
for (CentralSyncItem centralSyncItem : error) {
tryErroredItemAgain(centralSyncItem);
}
}
} catch (Throwable t) {
Log.error(t.getMessage());
}
}

public CentralSyncItem tryErroredItemAgain(CentralSyncItem centralSyncItem) {
if (centralSyncItem.uploadAttempts > 0) {
centralSyncItem.uploadAttempts = centralSyncItem.uploadAttempts - 1;
}
if (centralSyncItem.promotionAttempts > 0) {
centralSyncItem.promotionAttempts = centralSyncItem.promotionAttempts - 1;
}
return centralSyncItemService.changeStage(centralSyncItem, Stage.INIT);
}

/**
* Check all known artifacts for updates
*/
@Scheduled(cron = "{mvnpm.cron.expr}", concurrentExecution = SKIP)
@Scheduled(cron = "{mvnpm.checkall.cron.expr}", concurrentExecution = SKIP)
@Blocking
public void checkAll() {
try {
Expand Down
7 changes: 5 additions & 2 deletions src/main/resources/application.properties
Original file line number Diff line number Diff line change
Expand Up @@ -46,8 +46,11 @@ quarkus.cache.caffeine."maven-search-cache".expire-after-write=180S

quarkus.native.resources.includes=importmap.json,**/importmap.json

%dev.mvnpm.cron.expr=0 0/1 * * * ?
mvnpm.cron.expr=0 0 0/4 * * ?
%dev.mvnpm.checkall.cron.expr=0 0/1 * * * ?
mvnpm.checkall.cron.expr=0 0 0/4 * * ?

%mvnpm.checkerror.cron.expr=0 0/1 * * * ?
mvnpm.checkerror.cron.expr=0 0 5 * * ?

quarkus.http.read-timeout=5M
quarkus.rest-client.read-timeout=500000
Expand Down
62 changes: 51 additions & 11 deletions src/main/resources/web/app/mvnpm-releases.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import '@vaadin/radio-group';
import '@vaadin/progress-bar';
import '@vaadin/grid';
import '@vaadin/grid/vaadin-grid-sort-column.js';
import { columnBodyRenderer } from '@vaadin/grid/lit.js';

/**
* This component shows the Item stage screen
Expand All @@ -12,12 +13,26 @@ import '@vaadin/grid/vaadin-grid-sort-column.js';
export class MvnpmReleases extends LitElement {
static styles = css`
:host {
display: flex;
flex-direction: column;
gap: 10px;
width: 100%;
padding: 20px;
}`;
display: flex;
flex-direction: column;
gap: 10px;
width: 100%;
padding: 20px;
}
.rotate {
animation: rotation 1s infinite linear;
}
@keyframes rotation {
from {
transform: rotate(0deg);
}
to {
transform: rotate(360deg);
}
}
`;

@state({ type: Array })
private _itemList: any[] | null = null;
Expand All @@ -26,14 +41,13 @@ export class MvnpmReleases extends LitElement {
constructor() {
super();
this._itemList = null;
this._selectedState = null;
}

connectedCallback() {
super.connectedCallback();

fetch("/api/sync/item/RELEASED")
.then(response => response.json())
.then(response => this._itemList = response);
this._selectedState = "RELEASED";
this._fetchSelectedItemList();
}

disconnectedCallback() {
Expand Down Expand Up @@ -70,6 +84,7 @@ export class MvnpmReleases extends LitElement {
<vaadin-grid-sort-column header="Staging Repo Id" path="stagingRepoId"></vaadin-grid-sort-column>
<vaadin-grid-sort-column header="Upload attemps" path="uploadAttempts"></vaadin-grid-sort-column>
<vaadin-grid-sort-column header="Promotion attemps" path="promotionAttempts"></vaadin-grid-sort-column>
${this._renderRetryCol()}
</vaadin-grid>`;
} else if(!this._itemList){
return html`<vaadin-progress-bar class="progressBar" indeterminate></vaadin-progress-bar>`;
Expand All @@ -78,9 +93,34 @@ export class MvnpmReleases extends LitElement {
}
}

private _renderRetryCol(){
if(this._selectedState === "ERROR"){
return html`<vaadin-grid-sort-column resizable
header="Retry"
${columnBodyRenderer(this._retryRenderer, [])}>`;
}
}

private _retryRenderer(item) {
return html`<span style="cursor: pointer;" @click="${(e) => this._requestFullSync(e, item)}"><vaadin-icon style="color:var(--lumo-success-color)" icon="vaadin:refresh"></vaadin-icon></span>`;
}

private _requestFullSync(e, item){
e.target.className = "rotate";
var fullSyncRequest = "/api/sync/retry/" + item.groupId + "/" + item.artifactId + "?version=" + item.version;
fetch(fullSyncRequest)
.then(response => response.json())
.then(response => this._fetchSelectedItemList());
}

private _stageChange(e){
this._selectedState = e.target.value;
this._fetchSelectedItemList();
}

private _fetchSelectedItemList(){
this._itemList = null;
fetch("/api/sync/item/" + e.target.value)
fetch("/api/sync/item/" + this._selectedState)
.then(response => response.json())
.then(response => this._itemList = response);
}
Expand Down

0 comments on commit 9d23ac3

Please sign in to comment.