Theodore Norvell
Theodore Norvell

Reputation: 16231

Need all requests from the same client to go to the same instance

I have a GWT based Java web application deployed to Google App Engine, in which the servelet reads and changes state held in memory. The client code might send requests to change this state and, subsequently, to change or read the same state. So it's important that all requests from the same instance of the client page go to the same instance of the application's version.

Since I don't expect a lot of traffic, I don't mind limiting the maximum number of instances to 1. But I'd like that one instance to exist more or less permanently. (If a user takes more than, say, an hour between requests, I don't mind if their data is lost.)

In detail, the way I'm managing state is that I have a static variable that points to a hash table, the hash table maps strings to states. On the first request from the client, a new unique string is created and a new state and a new entry is made in the hash table. The string is returned in the response. On subsequent requests, the client sends the string so that the servelet can find the state that it needs to mutate or read. I can't keep the state in a database because it is very complex and not at all serializable.

What are the ways to ensure that all requests from a given client instance go to the same server instance?

Upvotes: 0

Views: 498

Answers (2)

Dan Cornilescu
Dan Cornilescu

Reputation: 39824

I second Dave's answer, GAE is not exactly the right fit for what you desire.

However there could be ways around it, but in only a few specific cases: if you're using the standard GAE environment with manual scaling and a subsequent request is always based on URLs embedded in the response to the previous request.

You could craft the URLs in a response to a request according to the targeted routing rules such that subsequent requests hit the same instance. From Targeted routing:

  • If you are still using backends or have manually-scaled services, you can target and send a request to a instance by including the instance ID. The instance ID is an integer in the range from 0 up to the total number of instances that are running, and can be specified as follows:

Sends a request to a specific service and version within a specific instance:

https://INSTANCE_ID-dot-VERSION_ID-dot-SERVICE_ID-dot-MY_PROJECT_ID.appspot.com
http://INSTANCE_ID.VERSION_ID.SERVICE_ID.MY_CUSTOM_DOMAIN

Note: Targeting an instance is not supported in services that are configured for auto scaling or basic scaling. The instance ID must be an integer in the range from 0, up to the total number of instances running. Regardless of your scaling type or instance class, it is not possible to send a request to a specific instance without targeting a service or version within that instance.

To determine the instance ID you could use the modules API, for example:

// Get the instance handling the current request.
int currentInstance = modulesApi.getCurrentInstance();

Note that if the targeted instance goes down you will keep getting errors permanently (that instance will not come back), so you might want to think at a fall-back solution for going somehow to a non-instance-based based page from where you could hitch a flow on another instance.

But such solution is not available in the GAE flex environment. From Targeted routing:

Note: In the flexible environment, targeting an instance is not supported. It is not possible to send requests directly to a specific instance.

Upvotes: 1

Dave W. Smith
Dave W. Smith

Reputation: 24966

What are the ways to ensure that all requests from a given client instance go to the same server instance?

There are no ways, by design. If you want to persist state between requests reliably, use the datastore, with memcache as a cache.

Adding: You can also use cookies if your data storage is meager, obfuscating/encrypting them as needed.

App Engine assumes that applications hold no essential state between requests. That makes spinning up/shutting down instances a non-issue.

Upvotes: 3

Related Questions