Skip to content

Commit

Permalink
GLSP-1408: Make live validation asynchronous (#247)
Browse files Browse the repository at this point in the history
  • Loading branch information
martin-fleck-at authored Oct 18, 2024
1 parent 3a8f801 commit 818ba4d
Showing 1 changed file with 39 additions and 3 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@
********************************************************************************/
package org.eclipse.glsp.server.features.core.model;

import static java.util.concurrent.TimeUnit.MILLISECONDS;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
Expand All @@ -33,6 +35,8 @@
import org.eclipse.glsp.server.layout.LayoutEngine;
import org.eclipse.glsp.server.layout.ServerLayoutKind;
import org.eclipse.glsp.server.model.GModelState;
import org.eclipse.glsp.server.utils.Debouncer;
import org.eclipse.glsp.server.utils.StatusActionUtil;

import com.google.inject.Inject;
import com.google.inject.Singleton;
Expand Down Expand Up @@ -61,9 +65,17 @@ public class ModelSubmissionHandler {
@Inject
protected GModelState modelState;

@Inject
protected ActionDispatcher actionDispatcher;

@Inject
protected Optional<ModelValidator> validator;

protected Debouncer<ModelValidator> liveValidationDebouncer;

// we use a very slight delay by default to avoid sending very short status messages for very fast validations
protected long liveValidationDelay = 100;

protected final Object modelLock = new Object();
protected Optional<RequestModelAction> requestModelAction = Optional.empty();

Expand Down Expand Up @@ -155,14 +167,38 @@ public List<Action> submitModelDirectly(final String reason) {
result.add(new SetDirtyStateAction(modelState.isDirty(), reason));
}
if (validator.isPresent()) {
List<Marker> markers = validator.get() //
.validate(Arrays.asList(modelState.getRoot()), MarkersReason.LIVE);
result.add(new SetMarkersAction(markers, MarkersReason.LIVE));
result.addAll(validateModel(validator.get()));
}
return result;
}
}

protected List<Action> validateModel(final ModelValidator validator) {
scheduleLiveValidation(validator);
// we are using async live validation so there no actions to return for the model submission
return List.of();
}

protected void scheduleLiveValidation(final ModelValidator validator) {
if (liveValidationDebouncer == null) {
liveValidationDebouncer = new Debouncer<>(this::performLiveValidation, getLiveValidationDelay(), MILLISECONDS);
}
liveValidationDebouncer.accept(validator);
}

public long getLiveValidationDelay() { return this.liveValidationDelay; }

public void setLiveValidationDelay(final long liveValidationDelay) {
this.liveValidationDelay = liveValidationDelay;
}

protected void performLiveValidation(final ModelValidator validator) {
actionDispatcher.dispatch(StatusActionUtil.info("Validate Model..."));
List<Marker> markers = validator.validate(Arrays.asList(modelState.getRoot()), MarkersReason.LIVE);
SetMarkersAction markerAction = new SetMarkersAction(markers, MarkersReason.LIVE);
actionDispatcher.dispatchAll(List.of(markerAction, StatusActionUtil.clear()));
}

public List<Action> submitModelDirectly() {
return submitModelDirectly(null);
}
Expand Down

0 comments on commit 818ba4d

Please sign in to comment.