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
;
11 import java
.util
.Iterator
;
12 import java
.util
.List
;
14 import java
.util
.concurrent
.atomic
.AtomicInteger
;
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
);
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
,
47 return listBuilder
.build();
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();
61 result
= thisEnvironment
;
68 public int getInstanceCount() {
69 return getInstanceHolders().size() - 1;
72 private ManualServerInstanceHolder
getFirstMaybeAvailableInstanceHolder() {
73 int instance
= instanceCounter
.getAndIncrement() % getInstanceCount();
74 return getInstanceHolder(instance
);
78 public ManualServerInstanceHolder
getAndReserveAvailableInstanceHolder() {
79 ManualServerInstanceHolder result
= null;
80 for (ManualServerInstanceHolder instanceHolder
: new Iterable
<ManualServerInstanceHolder
>() {
82 public Iterator
<ManualServerInstanceHolder
> iterator() {
83 return new FromFirstMaybeAvailableInstanceIterator();
86 if (instanceHolder
.acquireServingPermit()) {
87 result
= instanceHolder
;
95 public void startServing() throws Exception
{
96 requireState("startServing", InstanceState
.STOPPED
);
97 for (ManualServerInstanceHolder instanceHolder
: getInstanceHolders()) {
98 instanceHolder
.startServing();
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
;
127 protected ManualServerInstanceHolder
computeNext() {
128 if (getInstanceCount() == 0) {
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
) {
145 currentInstanceId
= nextInstanceId
;
146 return getInstanceHolder(currentInstanceId
);