String methodName = "handleNewServices";
Map<DuccId, ServiceDependency> updates = new HashMap<DuccId, ServiceDependency>(); // to be added to the service map sent to OR
Map<String, ServiceSet> newservices = new HashMap<String, ServiceSet>(); // to be added to our internal maps in serviceState
for ( DuccId id : work.keySet() ) {
DuccWorkJob w = (DuccWorkJob) work.get(id);
//
// On restart we sometimes get stale stuff that we just ignore.
// What else? Is the the right thing to do?
//
if ( !w.isActive() ) {
logger.info(methodName, id, "Bypassing inactive service, state=", w.getStateObject());
continue;
}
ServiceDependency s = new ServiceDependency();
updates.put(id, s);
String endpoint = w.getServiceEndpoint();
if ( endpoint == null ) { // the job is damaged if this happens
String msg = "No service endpoint. Service cannot be validated.";
logger.warn(methodName, id, msg);
s.addMessage("null", msg); // this is a fatal state always
s.setState(ServiceState.NotAvailable);
continue;
}
String[] deps = w.getServiceDependencies(); // other services this svc depends on
ServiceSet sset = serviceStateHandler.getServiceByName(endpoint);
if ( sset == null ) {
// submitted, we just track but not much else
try {
sset = new ServiceSet(serviceManager.newId(), id, endpoint, deps); // creates a "submitted" service
sset.addImplementor(id, w.getJobState());
serviceStateHandler.putServiceByName(endpoint, sset);
} catch ( Exception e ) {
s.addMessage(endpoint, e.getMessage());
s.setState(ServiceState.NotAvailable);
continue;
}
} else if ( sset.isDeregistered() ) {
s.addMessage(endpoint, "Duplicate endpoint: terminating deregistered service.");
s.setState(ServiceState.NotAvailable);
continue;
} else if ( sset.matches(id) ) {
// TODO: not clear we have to do anything here since establish() below will
// add to the implementors. Be sure to update the check so the
// code in the following 'else' clause is executed correctly though.
// and instance/implementor of our own registered services
sset.addImplementor(id, w.getJobState());
} else {
//
// If the new service is not a registered service, and it is a duplicate of another service
// which isn't registered, we allow it to join the party.
//
// When it joins, it needs to "propmote" the ServiceSet to "Submitted".
//
// a) in the case of "implicit" we don't know enough to many any moral judgements at all
// b) in the case of "submitted" it could be the user is increasing the pool of servers by
// submitting more jobs. Perhaps we would better handle this via modify but for the moment,
// just allow it.
// c) in the case of "registered" we know and manage everything and don't allow it. users must
// use the services modify api to increase or decrease instances.
//
if ( !sset.isRegistered() ) {
sset.addImplementor(id, w.getJobState());
sset.promote(); // we'll do this explicitly as a reminder that it's happening and
// to insure we NEVER promote a registered service (which is actually
// a demotion!).
} else {
String msg = "Duplicate endpoint: Registered service.";
logger.warn(methodName, id, msg);
s.addMessage(endpoint, msg);
s.setState(ServiceState.NotAvailable);
continue;
}
}
// The service is new and unique if we get this far
//
// No deps. Put it in the map and move on.
//
if ( deps == null ) {
logger.info(methodName, id, "Added service to map, no service dependencies. ");
s.setState(ServiceState.Available); // good to go in the OR (the state of things i'm dependent upon)
sset.establish(id, w.getJobState()); // sets my own state based entirely on state of w
continue;
}
Map<String, ServiceSet> jobServices = resolveDependencies(w, s); //
for ( ServiceSet depset : jobServices.values() ) {
depset.establish();
}
resolveState(id, s);
sset.establish(id, w.getJobState());
logger.info(methodName, id, "Added to map, with service dependencies,", s.getState());
}
serviceStateHandler.recordNewServices(newservices);
serviceMap.putAll(updates);