use of io.hops.hopsworks.persistence.entity.serving.Serving in project hopsworks by logicalclocks.
the class ServingUtil method validatePythonUserInput.
private void validatePythonUserInput(Serving serving) throws IllegalArgumentException, ServingException {
// Check model files and/or python scripts
try {
List<Inode> children = inodeController.getChildren(serving.getModelVersionPath());
long modelFiles = children.stream().filter(c -> {
String name = c.getInodePK().getName();
return MODEL_FILE_EXTS.stream().anyMatch(name::endsWith);
}).count();
if (modelFiles == 0) {
// if no model files found
if (children.stream().noneMatch(c -> c.getInodePK().getName().endsWith(".py"))) {
// and no python script
throw new ServingException(RESTCodes.ServingErrorCode.MODEL_FILES_STRUCTURE_NOT_VALID, Level.FINE, "Model" + " path requires either a python script or model file (i.e., joblib or pickle files)");
}
}
} catch (FileNotFoundException e) {
throw new ServingException(RESTCodes.ServingErrorCode.MODEL_PATH_NOT_FOUND, Level.FINE, null);
}
if (serving.isBatchingEnabled()) {
throw new ServingException(RESTCodes.ServingErrorCode.REQUEST_BATCHING_NOT_SUPPORTED, Level.SEVERE, "Request " + "batching is not supported in Python deployments");
}
}
use of io.hops.hopsworks.persistence.entity.serving.Serving in project hopsworks by logicalclocks.
the class ServingUtil method validateUserInput.
/**
* Validates user input before creating or updating a serving. This method contains the common input validation
* between different serving types and then delegates to serving-type-specific controllers to do validation specific
* to the serving type.
*
* @param servingWrapper contains the user-data to validate
* @param project the project where the serving resides
* @throws ServingException
* @throws java.io.UnsupportedEncodingException
*/
public void validateUserInput(ServingWrapper servingWrapper, Project project) throws ServingException, UnsupportedEncodingException {
Serving serving = servingWrapper.getServing();
Serving dbServing = servingFacade.findByProjectAndName(project, serving.getName());
setDefaultRequestBatching(serving);
// NOTE: order matters
validateServingName(serving, dbServing);
validateModelPath(serving);
validateModelVersion(serving);
validateModelServer(serving, dbServing);
validateModelName(serving);
validateServingTool(serving);
validatePredictor(project, serving);
validateKafkaTopicSchema(project, serving, servingWrapper.getKafkaTopicDTO());
validateInstances(serving);
}
use of io.hops.hopsworks.persistence.entity.serving.Serving in project hopsworks by logicalclocks.
the class ServingFacade method updateDbObject.
@TransactionAttribute(TransactionAttributeType.REQUIRES_NEW)
public Serving updateDbObject(Serving newServing, Project project) throws ServingException {
// Update request - execute this code within a transaction
// Merge serving fields
Serving oldDbServing = findByProjectAndId(project, newServing.getId());
Serving dbServing = mergeServings(oldDbServing, newServing);
// Update entity in the db
return merge(dbServing);
}
use of io.hops.hopsworks.persistence.entity.serving.Serving in project hopsworks by logicalclocks.
the class LocalhostServingController method deleteAll.
/**
* Deletes all servings in a project (used for project cleanup)
*
* @param project the project to delete all servings for
* @throws ServingException thrown if a lock for getting the serving could not be acquired
*/
@Override
public void deleteAll(Project project) throws ServingException {
List<Serving> servingList = servingFacade.findForProject(project);
for (Serving serving : servingList) {
// Acquire lock
servingFacade.acquireLock(project, serving.getId());
ServingStatusEnum status = getServingStatus(serving);
// If we reached this point, we just acquired a lock
if (!status.equals(ServingStatusEnum.STARTING)) {
killServingInstance(project, serving, false);
}
servingFacade.delete(serving);
}
}
use of io.hops.hopsworks.persistence.entity.serving.Serving in project hopsworks by logicalclocks.
the class LocalhostServingController method startOrStop.
/**
* Starts or stop a serving instance (depending on the user command). Will call the controller for the corresponding
* model server, such as Tensorflow Serving or Python
*
* @param project the project where the serving resides
* @param user the user making the request
* @param servingId the id of the serving
* @param command the command (start or stop)
* @throws ServingException if the serving could not be started or lock could be acquired
*/
@Override
public void startOrStop(Project project, Users user, Integer servingId, ServingCommands command) throws ServingException {
Serving serving = servingFacade.acquireLock(project, servingId);
ServingStatusEnum currentStatus = getServingStatus(serving);
// If we reached this point, we just acquired a lock
if (currentStatus == ServingStatusEnum.STARTING && command == ServingCommands.START) {
startServingInstance(project, user, serving);
// getServingStatus returns UPDATING if the PID is different than -2 and there is a lock.
// If we reached this point, we just acquired a lock
} else if (currentStatus == ServingStatusEnum.UPDATING && command == ServingCommands.STOP) {
killServingInstance(project, serving, true);
} else {
// Release lock before throwing the exception
servingFacade.releaseLock(project, servingId);
String userMsg = "Instance is already " + (command == ServingCommands.START ? ServingStatusEnum.STARTED.toString() : ServingStatusEnum.STOPPED.toString()).toLowerCase();
throw new ServingException(RESTCodes.ServingErrorCode.LIFECYCLEERROR, Level.FINE, userMsg);
}
}
Aggregations