Revision created by MOE tool push_codebase.
[gae.git] / java / src / main / com / google / appengine / tools / development / ManualServer.java
blob14538b6613e8e01b7689a4f1dca73ba973f1069e
1 package com.google.appengine.tools.development;
3 import com.google.appengine.tools.development.ApplicationConfigurationManager.ServerConfigurationHandle;
4 import com.google.appengine.tools.development.InstanceStateHolder.InstanceState;
5 import com.google.apphosting.utils.config.AppEngineConfigException;
6 import com.google.apphosting.utils.config.AppEngineWebXml;
7 import com.google.common.collect.AbstractIterator;
8 import com.google.common.collect.ImmutableList;
10 import java.io.File;
11 import java.util.Iterator;
12 import java.util.List;
13 import java.util.Map;
14 import java.util.concurrent.atomic.AtomicInteger;
16 /**
17 * {@link Server} implementation for manual servers.
19 public class ManualServer extends AbstractServer<ManualServerInstanceHolder> {
20 private final AtomicInteger instanceCounter = new AtomicInteger();
22 ManualServer(ServerConfigurationHandle serverConfigurationHandle, String serverInfo,
23 String address, DevAppServerImpl devAppServer, AppEngineWebXml appEngineWebXml) {
24 super(serverConfigurationHandle, serverInfo, null, address, devAppServer,
25 makeInstanceHolders(serverConfigurationHandle, appEngineWebXml));
28 private static List<ManualServerInstanceHolder> makeInstanceHolders(
29 ServerConfigurationHandle serverConfigurationHandle, AppEngineWebXml appEngineWebXml) {
30 String instancesString = appEngineWebXml.getManualScaling().getInstances();
31 int instances = instancesString == null ? 0 : Integer.parseInt(instancesString);
32 if (instances < 0) {
33 throw new AppEngineConfigException("Invalid instances " + instances + " in file "
34 + serverConfigurationHandle.getModule().getAppEngineWebXmlFile());
37 ImmutableList.Builder<ManualServerInstanceHolder> listBuilder = ImmutableList.builder();
38 for (int ix = LocalEnvironment.MAIN_INSTANCE; ix < instances; ix++) {
39 String serverName = serverConfigurationHandle.getModule().getServerName();
40 InstanceStateHolder stateHolder = new InstanceStateHolder(serverName, ix);
41 ContainerService containerService = ContainerUtils.loadContainer();
42 InstanceHelper instanceHelper =
43 new InstanceHelper(serverName, ix, stateHolder, containerService);
44 listBuilder.add(new ManualServerInstanceHolder(serverName, containerService, ix, stateHolder,
45 instanceHelper));
47 return listBuilder.build();
50 @Override
51 public LocalServerEnvironment doConfigure(
52 ServerConfigurationHandle serverConfigurationHandle, String serverInfo,
53 File externalResourceDir, String address, Map<String, Object> containerConfigProperties,
54 DevAppServerImpl devAppServer) throws Exception {
55 LocalServerEnvironment result = null;
56 for (ManualServerInstanceHolder instanceHolder : getInstanceHolders()) {
57 instanceHolder.setConfiguration(serverConfigurationHandle, serverInfo, externalResourceDir,
58 address, containerConfigProperties, devAppServer);
59 LocalServerEnvironment thisEnvironment = instanceHolder.doConfigure();
60 if (result == null) {
61 result = thisEnvironment;
64 return result;
67 @Override
68 public int getInstanceCount() {
69 return getInstanceHolders().size() - 1;
72 private ManualServerInstanceHolder getFirstMaybeAvailableInstanceHolder() {
73 int instance = instanceCounter.getAndIncrement() % getInstanceCount();
74 return getInstanceHolder(instance);
77 @Override
78 public ManualServerInstanceHolder getAndReserveAvailableInstanceHolder() {
79 ManualServerInstanceHolder result = null;
80 for (ManualServerInstanceHolder instanceHolder : new Iterable<ManualServerInstanceHolder>() {
81 @Override
82 public Iterator<ManualServerInstanceHolder> iterator() {
83 return new FromFirstMaybeAvailableInstanceIterator();
85 }) {
86 if (instanceHolder.acquireServingPermit()) {
87 result = instanceHolder;
88 break;
91 return result;
94 @Override
95 public void startServing() throws Exception {
96 requireState("startServing", InstanceState.STOPPED);
97 for (ManualServerInstanceHolder instanceHolder : getInstanceHolders()) {
98 instanceHolder.startServing();
102 @Override
103 public void stopServing() throws Exception {
104 requireState("stopServing", InstanceState.RUNNING);
105 for (ManualServerInstanceHolder instanceHolder : getInstanceHolders()) {
106 instanceHolder.stopServing();
110 private void requireState(String operation, InstanceState requiredState) {
111 for (ManualServerInstanceHolder instanceHolder : getInstanceHolders()) {
112 instanceHolder.requireState(operation, requiredState);
117 * Iterator for iterating through {@link InstanceHolder} values starting with
118 * {@link #getFirstMaybeAvailableInstanceHolder}.
120 private class FromFirstMaybeAvailableInstanceIterator
121 extends AbstractIterator<ManualServerInstanceHolder> {
122 private static final int INVALID_INSTANCE_ID = -1;
123 private int startInstanceId = INVALID_INSTANCE_ID;
124 private int currentInstanceId = INVALID_INSTANCE_ID;
126 @Override
127 protected ManualServerInstanceHolder computeNext() {
128 if (getInstanceCount() == 0) {
129 endOfData();
130 return null;
133 if (startInstanceId == INVALID_INSTANCE_ID) {
134 ManualServerInstanceHolder instanceHolder = getFirstMaybeAvailableInstanceHolder();
135 startInstanceId = instanceHolder.getInstance();
136 currentInstanceId = startInstanceId;
137 return instanceHolder;
140 int nextInstanceId = (currentInstanceId + 1) % getInstanceCount();
141 if (nextInstanceId == startInstanceId) {
142 endOfData();
143 return null;
144 } else {
145 currentInstanceId = nextInstanceId;
146 return getInstanceHolder(currentInstanceId);