Skip to content

Commit

Permalink
Starting engine status management
Browse files Browse the repository at this point in the history
  • Loading branch information
fvilla committed Sep 18, 2024
1 parent 7374ae5 commit 8a79428
Show file tree
Hide file tree
Showing 24 changed files with 372 additions and 158 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,31 @@
*/
public interface Engine extends KlabService {

/**
* Comprehensive engine status is kept up to date by polling or listening to services. Whenever the status
* changes, either because of service lifecycle or because of the user choosing a different service as the
* current one, a message is sent (intercepted by the modeler and also sent to the UI).
*/
interface Status {

/**
* True if every service is available and a worldview is loaded in the reasoner.
*
* @return
*/
boolean isOperational();

/**
* Return the current status of each specific service. If the service is not even connected, a
* non-null inactive status is returned.
*
* @param serviceType
* @return
*/
ServiceStatus getServiceStatus(KlabService.Type serviceType);

}

/**
* The engine is available to boot.
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -153,8 +153,24 @@ interface ServiceStatus extends Serializable {

String getServiceId();

/**
* Available means that the service has been initialized and is accepting connections. It does not
* mean that the API is fully functional: it may not have gathered enough information from other
* services, or it may be configured in ways that make it inoperative. Use {@link #isOperational()} to
* check for that, and/or use the capabilities to check what functions are supported.
*
* @return
*/
boolean isAvailable();

/**
* Operational means that the entire API of the service is available to support the functions declared
* as supported in the capabilities.
*
* @return
*/
boolean isOperational();

boolean isBusy();

/**
Expand Down Expand Up @@ -328,21 +344,21 @@ interface ServiceCapabilities extends Serializable {
/**
* Register a session created by the scope manager after receiving a CREATE_SESSION request. Return a
* unique session ID that may be requested with the session or generated within the service.
*
* @param sessionScope a client scope that should record the ID for future communication. If the ID is
* null, the call has failed.
* @return the ID of the new session created at server side, or null in case of failure.
*/
String registerSession(SessionScope sessionScope);

/**
* Register a context scope created by the scope manager. Return a unique session ID that may be
* requested with the session or generated within the service. Context starts empty with the default
* observer for the worldview, using the services available to the user and passed as parameters. The same
* runtime that hosts the context must become the one and only runtime accessible to the resulting scope.
* If the service is not a runtime, the request must come from another service and the scope should be
* Register a context scope created by the scope manager. Return a unique session ID that may be requested
* with the session or generated within the service. Context starts empty with the default observer for
* the worldview, using the services available to the user and passed as parameters. The same runtime that
* hosts the context must become the one and only runtime accessible to the resulting scope. If the
* service is not a runtime, the request must come from another service and the scope should be
* instrumented as necessary for its purposes.
*
* @param contextScope a client scope that should record the ID for future communication. If the ID is
* null, the call has failed.
* @return the ID of the new context scope created at server side, or null in case of failure.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -986,7 +986,7 @@ interface Admin {
* @return a {@link ResourceSet} including the ontologies, observation strategies, each with any
* notifications created during the load process, with the lexical context set as needed
*/
ResourceSet loadKnowledge(Worldview worldview, UserScope scope);
ResourceSet loadKnowledge(Worldview worldview, Scope scope);

/**
* When a reasoner is registered with a resources service by an external orchestrator, changes in the
Expand Down Expand Up @@ -1014,7 +1014,7 @@ interface Admin {

/**
* The "port" to ingest an individual concept definition, called by
* {@link #loadKnowledge(Worldview, UserScope)} (Worldview)}. Provided separately to make it possible
* {@link #loadKnowledge(Worldview, Scope)} (Worldview)}. Provided separately to make it possible
* for a resolver service to declare individual local concepts, as long as it owns the semantic
* service. Definition must be made only in terms of known concepts (no forward declaration is
* allowed), so order of ingestion is critical.
Expand All @@ -1023,7 +1023,7 @@ interface Admin {
* @param scope admin user scope to report and validate
* @return
*/
Concept defineConcept(KimConceptStatement statement, UserScope scope);
Concept defineConcept(KimConceptStatement statement, Scope scope);

/**
* Export a namespace as an OWL ontology with all dependencies.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,14 @@ interface Capabilities extends ServiceCapabilities {

boolean isWorldviewProvider();

/**
* If true, the service is connected to an operational reasoner and can support semantically aware
* calls such as {@link #queryModels(Observable, ContextScope)}.
*
* @return
*/
boolean isSemanticSearchCapable();

String getAdoptedWorldview();

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ public class ServiceStatusImpl implements KlabService.ServiceStatus {
private boolean available = false;
private boolean busy = false;
private boolean consistent = true;
private boolean operational = false;
private ServiceScope.Locality locality = ServiceScope.Locality.EMBEDDED;
private KlabService.Type serviceType;
private String serviceId;
Expand Down Expand Up @@ -167,6 +168,15 @@ public boolean isConsistent() {
return consistent;
}

@Override
public boolean isOperational() {
return operational;
}

public void setOperational(boolean operational) {
this.operational = operational;
}

public void setConsistent(boolean consistent) {
this.consistent = consistent;
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package org.integratedmodelling.klab.api.services.runtime;

import org.integratedmodelling.klab.api.digitaltwin.DigitalTwin;
import org.integratedmodelling.klab.api.engine.Engine;
import org.integratedmodelling.klab.api.engine.distribution.Distribution;
import org.integratedmodelling.klab.api.identities.UserIdentity;
import org.integratedmodelling.klab.api.lang.kactors.beans.ActionStatistics;
Expand Down Expand Up @@ -184,7 +185,7 @@ enum MessageType {
* Service messages, coming with service capabilities
*/
ServiceInitializing(Queue.Events, KlabService.ServiceCapabilities.class),
ReasoningAvailable(Queue.Events, Reasoner.Capabilities.class),
// ReasoningAvailable(Queue.Events, Reasoner.Capabilities.class),
ServiceAvailable(Queue.Events, KlabService.ServiceCapabilities.class),
ServiceUnavailable(Queue.Events, KlabService.ServiceCapabilities.class),
ServiceStatus(Queue.Events, KlabService.ServiceStatus.class),
Expand Down Expand Up @@ -220,10 +221,10 @@ enum MessageType {
Warning(Queue.Warnings, Notification.class),
Error(Queue.Errors, Notification.class),

/*
* --- reasoning-related messages
*/
LogicalValidation(Queue.Events,ResourceSet.class),
// /*
// * --- reasoning-related messages
// */
// LogicalValidation(Queue.Events,ResourceSet.class),

/**
* Runtime event messages
Expand All @@ -245,6 +246,11 @@ enum MessageType {
ResolutionAborted(Queue.Events, Long.class),


/**
* Engine status has changed
*/
EngineStatusChanged(Queue.Events, Engine.Status.class),

/*
* --- View actor messages
*/
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package org.integratedmodelling.klab.api.view;

import org.integratedmodelling.klab.api.data.mediation.classification.Classification;
import org.integratedmodelling.klab.api.engine.Engine;
import org.integratedmodelling.klab.api.engine.distribution.Distribution;
import org.integratedmodelling.klab.api.identities.UserIdentity;
import org.integratedmodelling.klab.api.knowledge.Expression;
Expand Down Expand Up @@ -160,27 +161,28 @@ enum UIAction {
*/
enum UIEvent {

EngineStarting(EventDirection.EngineToView, UserIdentity.class),
/**
* From this point on, the UI should be synced to the services in the scope and made its functions
* available based on the current service capabilities.
*/
EngineAvailable(EventDirection.EngineToView, UserScope.class),
EngineUnavailable(EventDirection.EngineToView, UserIdentity.class),
/**
* Sent only for the DEFAULT services in case they are local to the modeler's instance.
*/
ServiceStarting(EventDirection.EngineToView, KlabService.ServiceCapabilities.class),
/**
* Sent only for the DEFAULT services in case they are local to the modeler's instance or for other
* services in case they come online after going offline. Besides a default/local service, the
* services listed in the UI should be those listed in the user scope sent with EngineAvailable.
*/
ServiceAvailable(EventDirection.EngineToView, KlabService.ServiceCapabilities.class),
/**
* Sent for any of the services in the user scope when they go offline.
*/
ServiceUnavailable(EventDirection.EngineToView, KlabService.ServiceCapabilities.class),
// EngineStarting(EventDirection.EngineToView, UserIdentity.class),
// /**
// * From this point on, the UI should be synced to the services in the scope and made its functions
// * available based on the current service capabilities.
// */
// EngineAvailable(EventDirection.EngineToView, UserScope.class),
// EngineUnavailable(EventDirection.EngineToView, UserIdentity.class),
EngineStatusChanged(EventDirection.EngineToView, Engine.Status.class),
// /**
// * Sent only for the DEFAULT services in case they are local to the modeler's instance.
// */
// ServiceStarting(EventDirection.EngineToView, KlabService.ServiceCapabilities.class),
// /**
// * Sent only for the DEFAULT services in case they are local to the modeler's instance or for other
// * services in case they come online after going offline. Besides a default/local service, the
// * services listed in the UI should be those listed in the user scope sent with EngineAvailable.
// */
// ServiceAvailable(EventDirection.EngineToView, KlabService.ServiceCapabilities.class),
// /**
// * Sent for any of the services in the user scope when they go offline.
// */
// ServiceUnavailable(EventDirection.EngineToView, KlabService.ServiceCapabilities.class),

/**
* Sent from the UI to the engine to define which service to use as the default for the class, and to
Expand Down Expand Up @@ -234,7 +236,7 @@ enum UIEvent {
ImportProjectRequest(EventDirection.ViewToEngine, String.class),
Notification(EventDirection.Bidirectional, Notification.class),
DistributionSelected(EventDirection.ViewToView, Distribution.class),
ReasoningAvailable(EventDirection.EngineToView, Reasoner.Capabilities.class),
// ReasoningAvailable(EventDirection.EngineToView, Reasoner.Capabilities.class),
UserAuthenticated(EventDirection.Bidirectional, UserIdentity.class),

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,27 +25,31 @@ public interface ServicesViewController extends ViewController<ServicesView> {
*
* @param service
*/
@UIEventHandler(UIEvent.ServiceAvailable)
void serviceAvailable(KlabService.ServiceCapabilities service);
// @UIEventHandler(UIEvent.ServiceAvailable)
// void serviceAvailable(KlabService.ServiceCapabilities service);
//
// @UIEventHandler(UIEvent.ServiceUnavailable)
// void serviceUnavailable(KlabService.ServiceCapabilities service);
//
// @UIEventHandler(UIEvent.ServiceStarting)
// void serviceStarting(KlabService.ServiceCapabilities service);
//
// /**
// * Will be called at least once to report on service status, and possibly at regular intervals
// depending
// * on the engine implementation. This may make the service available, unavailable, busy, and
// report on
// * current load factor and state.
// *
// * @param status
// */
// @UIEventHandler(UIEvent.ServiceStatus)
// void serviceStatus(KlabService.ServiceStatus status);

@UIEventHandler(UIEvent.ServiceUnavailable)
void serviceUnavailable(KlabService.ServiceCapabilities service);

@UIEventHandler(UIEvent.ServiceStarting)
void serviceStarting(KlabService.ServiceCapabilities service);

/**
* Will be called at least once to report on service status, and possibly at regular intervals depending
* on the engine implementation. This may make the service available, unavailable, busy, and report on
* current load factor and state.
*
* @param status
*/
@UIEventHandler(UIEvent.ServiceStatus)
void serviceStatus(KlabService.ServiceStatus status);

@UIEventHandler(UIEvent.ReasoningAvailable)
void reasoningAvailable(Reasoner.Capabilities capabilities);
// @UIEventHandler(UIEvent.ReasoningAvailable)
// void reasoningAvailable(Reasoner.Capabilities capabilities);
@UIEventHandler(UIEvent.EngineStatusChanged)
void engineStatusChanged(Engine.Status status);

/**
* User action choosing a service to focus on. The view handles all the UI implications and then calls
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ public class ResourcesCapabilitiesImpl extends AbstractServiceCapabilities imple
private List<String> workspaceNames = new ArrayList<>();
private Set<CRUDOperation> permissions = EnumSet.of(CRUDOperation.READ);
private List<Notification> serviceNotifications = new ArrayList<>();
private boolean semanticSearchCapable;

@Override
public KlabService.Type getType() {
Expand Down Expand Up @@ -71,4 +72,12 @@ public void setPermissions(Set<CRUDOperation> permissions) {
this.permissions = permissions;
}

@Override
public boolean isSemanticSearchCapable() {
return semanticSearchCapable;
}

public void setSemanticSearchCapable(boolean semanticSearchCapable) {
this.semanticSearchCapable = semanticSearchCapable;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ public abstract class ServiceClient implements KlabService {
private AbstractServiceDelegatingScope scope;
private URL url;
private String token;
private long pollCycleSeconds = 2;
private long pollCycleSeconds = 5;
protected Utils.Http.Client client;
private ServiceCapabilities capabilities;
// this is not null only if the client is used by another service. In that case, the service should be
Expand Down
Loading

0 comments on commit 8a79428

Please sign in to comment.