All Downloads are FREE. Search and download functionalities are using the official Maven repository.

io.janusproject.services.Services Maven / Gradle / Ivy

There is a newer version: 3.0.12.0
Show newest version
/*
 * $Id: io/janusproject/services/Services.java v2.0.3.1 2016-01-24 00:05:13$
 *
 * Janus platform is an open-source multiagent platform.
 * More details on http://www.janusproject.io
 *
 * Copyright (C) 2014-2015 the original authors or authors.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package io.janusproject.services;

import java.lang.ref.WeakReference;
import java.util.ArrayList;
import java.util.Collection;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Queue;
import java.util.Set;
import java.util.TreeMap;
import java.util.TreeSet;

import com.google.common.util.concurrent.Service;
import com.google.common.util.concurrent.Service.State;
import com.google.common.util.concurrent.ServiceManager;
import io.janusproject.services.infrastructure.InfrastructureService;
import org.arakhne.afc.vmutil.ClassComparator;


/** Tools for launching and stopping services.
 *
 * @author Stéphane Galland
 * @version 2.0.3.1 2016-01-24 00:05:13
 * @mavengroupid io.janusproject
 * @mavenartifactid io.janusproject.kernel
 */
public final class Services {

	private Services() {
		//
	}

	/** Start the services associated to the given service manager.
	 *
	 * 

This starting function supports the {@link DependentService prioritized services}. * * @param manager - the manager of the services to start. */ public static void startServices(ServiceManager manager) { startServices(new GoogleServiceManager(manager)); } /** Start the services associated to the given service manager. * *

This starting function supports the {@link DependentService prioritized services}. * * @param manager - the manager of the services to start. */ public static void startServices(IServiceManager manager) { List otherServices = new ArrayList<>(); List infraServices = new ArrayList<>(); LinkedList serviceQueue = new LinkedList<>(); Accessors accessors = new StartingPhaseAccessors(); // Build the dependency graph buildDependencyGraph(manager, serviceQueue, infraServices, otherServices, accessors); // Launch the services runDependencyGraph(serviceQueue, infraServices, otherServices, accessors); manager.awaitHealthy(); } /** Stop the services associated to the given service manager. * *

This stopping function supports the {@link DependentService prioritized services}. * * @param manager - the manager of the services to stop. */ public static void stopServices(ServiceManager manager) { stopServices(new GoogleServiceManager(manager)); } /** Stop the services associated to the given service manager. * *

This stopping function supports the {@link DependentService prioritized services}. * * @param manager - the manager of the services to stop. */ public static void stopServices(IServiceManager manager) { List otherServices = new ArrayList<>(); List infraServices = new ArrayList<>(); LinkedList serviceQueue = new LinkedList<>(); Accessors accessors = new StoppingPhaseAccessors(); // Build the dependency graph buildInvertedDependencyGraph(manager, serviceQueue, infraServices, otherServices, accessors); // Launch the services runDependencyGraph(serviceQueue, infraServices, otherServices, accessors); manager.awaitStopped(); } private static void addNodeIntoDependencyGraph( DependentService depServ, Map, DependencyNode> dependentServices, List roots) { Class type = depServ.getServiceType(); assert (type != null); assert (type.isInterface()) : type.getName(); DependencyNode node = dependentServices.get(type); if (node == null) { node = new DependencyNode(depServ, type); dependentServices.put(type, node); } else { assert (node.getService() == null); node.setService(depServ); } boolean isRoot = true; Collection> deps = depServ.getServiceDependencies(); for (Class dep : deps) { isRoot = false; DependencyNode depNode = dependentServices.get(dep); if (depNode == null) { depNode = new DependencyNode(dep); dependentServices.put(dep, depNode); } depNode.getNextServices().add(node); } deps = depServ.getServiceWeakDependencies(); for (Class dep : deps) { isRoot = false; DependencyNode depNode = dependentServices.get(dep); if (depNode == null) { depNode = new DependencyNode(dep); dependentServices.put(dep, depNode); } depNode.getNextWeakServices().add(node); } if (isRoot) { roots.add(node); } } /** Build the dependency graph for the services. * * @param manager - lsit of the services. * @param roots - filled with the services that have no dependency. * @param infraServices - filled with the infrastructure services. * @param freeServices - filled with the services that are executed before/after all the dependent services. * @param accessors - permits to retreive information on the services. */ private static void buildDependencyGraph( IServiceManager manager, List roots, List infraServices, List freeServices, Accessors accessors) { Map, DependencyNode> dependentServices = new TreeMap<>(ClassComparator.SINGLETON); Service service; for (Entry entry : manager.servicesByState().entries()) { if (accessors.matches(entry.getKey())) { service = entry.getValue(); if (service instanceof InfrastructureService) { infraServices.add(service); } else if (service instanceof DependentService) { addNodeIntoDependencyGraph((DependentService) service, dependentServices, roots); } else { freeServices.add(service); } } } if (accessors.isAsyncStateWaitingEnabled()) { for (DependencyNode node : dependentServices.values()) { assert (node.getService() != null); if (node.getService() instanceof AsyncStateService) { for (DependencyNode next : node.getNextServices()) { next.getAsyncStateServices().add(new WeakReference<>(node)); } } } } } /** Build the dependency graph for the services. * * @param manager - lsit of the services. * @param roots - filled with the services that have no dependency. * @param infraServices - filled with the infrastructure services. * @param freeServices - filled with the services that are executed before/after all the dependent services. * @param accessors - permits to retreive information on the services. */ private static void buildInvertedDependencyGraph( IServiceManager manager, List roots, List infraServices, List freeServices, Accessors accessors) { Map, DependencyNode> dependentServices = new TreeMap<>(ClassComparator.SINGLETON); Map, DependencyNode> rootServices = new TreeMap<>(ClassComparator.SINGLETON); Service service; for (Entry entry : manager.servicesByState().entries()) { if (accessors.matches(entry.getKey())) { service = entry.getValue(); if (service instanceof InfrastructureService) { infraServices.add(service); } else if (service instanceof DependentService) { DependentService depServ = (DependentService) service; Class type = depServ.getServiceType(); DependencyNode node = dependentServices.get(type); boolean isRoot = true; if (node == null) { node = new DependencyNode(depServ, type); dependentServices.put(type, node); } else { assert (node.getService() == null); node.setService(depServ); isRoot = false; } Collection> deps = depServ.getServiceDependencies(); for (Class dep : deps) { DependencyNode depNode = dependentServices.get(dep); if (depNode == null) { depNode = new DependencyNode(dep); dependentServices.put(dep, depNode); } node.getNextServices().add(depNode); rootServices.remove(depNode.getType()); } deps = depServ.getServiceWeakDependencies(); for (Class dep : deps) { DependencyNode depNode = dependentServices.get(dep); if (depNode == null) { depNode = new DependencyNode(dep); dependentServices.put(dep, depNode); } node.getNextWeakServices().add(depNode); rootServices.remove(depNode.getType()); } if (isRoot) { rootServices.put(type, node); } } else { freeServices.add(service); } } } roots.addAll(rootServices.values()); } /** Run the dependency graph for the services. * * @param roots - filled with the services that have no dependency. * @param infraServices - filled with the infrastructure services. * @param freeServices - filled with the services that are executed before/after all the dependent services. * @param accessors - permits to retreive information on the services. */ private static void runDependencyGraph( Queue roots, List infraServices, List freeServices, Accessors accessors) { final boolean async = accessors.isAsyncStateWaitingEnabled(); Set> executed = new TreeSet<>(ClassComparator.SINGLETON); accessors.runInfrastructureServicesBefore(infraServices); accessors.runFreeServicesBefore(freeServices); while (!roots.isEmpty()) { DependencyNode node = roots.remove(); assert (node != null && node.getType() != null); if (!executed.contains(node.getType())) { executed.add(node.getType()); roots.addAll(node.getNextServices()); roots.addAll(node.getNextWeakServices()); assert (node.getService() != null); if (async) { for (WeakReference asyncService : node.getAsyncStateServices()) { AsyncStateService as = (AsyncStateService) (asyncService.get().getService()); assert (as != null); while (!as.isReadyForOtherServices()) { Thread.yield(); } } } accessors.run(node.getService()); } } accessors.runFreeServicesAfter(freeServices); accessors.runInfrastructureServicesAfter(infraServices); } /** Node that describes a service dependency. * * @author Stéphane Galland * @version 2.0.3.1 2016-01-24 00:05:13 * @mavengroupid io.janusproject * @mavenartifactid io.janusproject.kernel */ private static class DependencyNode { private Service service; private final Class type; private final Collection nextServices = new ArrayList<>(); private final Collection nextWeakServices = new ArrayList<>(); private final Collection> asyncStateServices = new ArrayList<>(); DependencyNode(DependentService service, Class type) { assert (service != null); this.service = service; this.type = type; } DependencyNode(Class type) { this.service = null; this.type = type; } public Service getService() { return this.service; } public void setService(Service service) { this.service = service; } public Class getType() { return this.type; } public Collection> getAsyncStateServices() { return this.asyncStateServices; } public Collection getNextServices() { return this.nextServices; } public Collection getNextWeakServices() { return this.nextWeakServices; } @Override public String toString() { if (this.service == null) { return "!!!" + this.type.getName(); //$NON-NLS-1$ } return this.service.toString(); } } /** Accessors for running services. * * @author Stéphane Galland * @version 2.0.3.1 2016-01-24 00:05:13 * @mavengroupid io.janusproject * @mavenartifactid io.janusproject.kernel */ private interface Accessors { boolean matches(State element); void runInfrastructureServicesBefore(List infraServices); void runFreeServicesBefore(List freeServices); boolean isAsyncStateWaitingEnabled(); void run(Service service); void runFreeServicesAfter(List freeServices); void runInfrastructureServicesAfter(List infraServices); } /** Accessors for running services at start-up. * * @author Stéphane Galland * @version 2.0.3.1 2016-01-24 00:05:13 * @mavengroupid io.janusproject * @mavenartifactid io.janusproject.kernel */ private static class StartingPhaseAccessors implements Accessors { /** Construct. */ StartingPhaseAccessors() { // } @Override public boolean matches(State element) { return element == State.NEW; } @Override public void runFreeServicesBefore(List freeServices) { // } @Override public void runInfrastructureServicesBefore(List infraServices) { for (Service serv : infraServices) { serv.startAsync().awaitRunning(); } } @Override public boolean isAsyncStateWaitingEnabled() { return true; } @Override public void run(Service service) { service.startAsync().awaitRunning(); } @Override public void runFreeServicesAfter(List freeServices) { for (Service serv : freeServices) { serv.startAsync(); } } @Override public void runInfrastructureServicesAfter(List infraServices) { // } } /** Accessors for running agents at end. * * @author Stéphane Galland * @version 2.0.3.1 2016-01-24 00:05:13 * @mavengroupid io.janusproject * @mavenartifactid io.janusproject.kernel */ private static class StoppingPhaseAccessors implements Accessors { /** Construct. */ StoppingPhaseAccessors() { // } @Override public boolean matches(State element) { return element != State.TERMINATED && element != State.STOPPING; } @Override public void runFreeServicesBefore(List freeServices) { for (Service serv : freeServices) { serv.stopAsync(); } } @Override public void runInfrastructureServicesBefore(List infraServices) { // } @Override public boolean isAsyncStateWaitingEnabled() { return false; } @Override public void run(Service service) { service.stopAsync().awaitTerminated(); } @Override public void runFreeServicesAfter(List freeServices) { // } @Override public void runInfrastructureServicesAfter(List infraServices) { for (Service serv : infraServices) { serv.stopAsync(); } } } }





© 2015 - 2025 Weber Informatics LLC | Privacy Policy