Google App Engine dynamic backends are not stopped - google-app-engine

(If this is not a question for SO, I will be gladly moved elsewhere)
I have a GAE backend that I want to start regularly with cron. With the help of other questions from SO, I set up backends.xml like this
<?xml version="1.0" encoding="UTF-8"?>
<backends>
<backend name="myBackend">
<class>B1</class>
<instances>1</instances>
<options>
<dynamic>true</dynamic>
</options>
</backend>
</backends>
and my cron.xml like this
<?xml version="1.0" encoding="UTF-8"?>
<cronentries>
<cron>
<url>/doHardStuff</url>
<description>doing long running stuff</description>
<schedule>every 3 hours</schedule>
<target>myBackend</target>
</cron>
</cronentries>
And I upload it using mvn-gae (I am writing everything in java with maven) with goals gae:deploy gae:backends-list gae:backends-update
Everything loads fine and the long running stuff is done, however. Even after finishing everything, the dynamic backend still runs and eats my daily backend quota. I can see _ah/stop request in logs after the servlet finishes its job; however the backend still runs after that.
If I stop it manually in engine web console in Main -> Backends -> Start/Stop, it stops eating my quota, however, it won't run at a given time in cron and the cron job will fail.
What should I do? I want the backend to start at the given time and stop when the request is over and the machine is idle. I don't want it running at a different time.

It's working as it's supposed to. Dynamic backends are always "started" in the backends tab in the dashboard, which just means they can get requests and start instances if needed. This doesn't consume any quota.
When the backend gets a request it starts an instance using /_ah/start/ and consumes quota. When it doesn't have any requests to serve for some minutes it stops the instance with an /_ah/stop/ request.
To figure out if the backend instance is still running, change to the instances tab and select the backend "version".
Note that dynamic backends have a 15 minutes quota penalty, which is probably why the quota usage is higher than expected.
For dynamic backends, billing ends fifteen minutes after the last
request has finished processing.
http://developers.google.com/appengine/docs/python/backends/overview#Billing_Quotas_and_Limits

It seems like it takes them 15 minutes to be stopped, according to some pages online.
This seems possible, I will try it.

Related

App Engine Cron Tasks fail with no entries in log. How to debug?

I recently updated my cron.yaml file and now my cron tasks fail with no entries in the logs.
It is acting like the java servlet at the url is not being run.
I can paste the url into a browser and the servlet runs fine.
My cron.yaml file:
cron:
- description: Daily revenues report
url: /revenues
schedule: every day 07:35
timezone: America/Denver
Using below deploycron.sh
PROJECT_ID='my-project-id'
gcloud config set project ${PROJECT_ID}
gcloud info
gcloud app deploy cron.yaml
Is there an error in my .yaml?
Is there a special task queue set up required?
Is some other configuration or permissions piece missing?
It was running fine last week. I have tried deleting and starting over to no avail.
https://console.cloud.google.com/cloudscheduler?project=project-id
Shows the job. Result column 'Failed'.
Logs 'View' link shows:
protoPayload.taskName="01661931846119241031" protoPayload.taskQueueName="__cron"
with no log entries.
Is __cron not automatic?
I am at a loss.
App Engine Standard. Java 8.
After installing the latest update of GCloud locally and re-running the deploy cron script. The cron jobs now run as before. 02/02/2021.
'Failed' means that the endpoint /revenues is not returning a success http status code.
Logs 'View' link shows: protoPayload.taskName="01661931846119241031" protoPayload.taskQueueName="__cron" with no log entries
Maybe don't use the premade filter, and just try filtering for /revenues or viewing all the logs at 07:35 am (when it was supposed to have run)
Is there an error in my .yaml?
if there was then gcloud app deploy cron.yaml would fail
Is there a special task queue set up required?
you shouldn't need to do anything, i didn't
I can paste the url into a browser and the servlet runs fine.
When you paste the url into the browser, is there any redirecting (like from /revenues to /revenues/) or anything that your browser is handling for you. Maybe /revenues is expecting there to be cookies present now.
What are there any special app.yaml or dispatch.yaml rules that /revenues would be hitting?
Is /revenues being handled by a service other than the default service?
I had a similar problem: CRON tasks fail without any logs.
The root cause was that the IP address of App Engine was blocked by the App Engine Firewall. Thus I had to update the allow-list, as described here: https://cloud.google.com/appengine/docs/standard/nodejs/scheduling-jobs-with-cron-yaml#validating_cron_requests
I started having the same problem a few days ago on my existing CRON schedules. I've tried everything including tearing my code down to the bare minimum and creating a new GAE project with the Hello World quick start. It still fails. Nothing useful in the logs and the UI just says 'Failed'. I'm pulling my hair out.
Sorry I don't have an answer to contribute but your post makes me think it's on Google's side. I know they're moving CRON jobs to Cloud Scheduler->App Engine Cron Jobs. My gut tells me it's a permissions issue related to this move and IAM. I'm really at a loss.

Google App Engine: debugging Dashboard > Traffic > Sent

I have an GAE app PHP72, env: standard which is hanging intermittently (once or twice a day for about 5 mins).
When this occurs I see a large spike in GAE dashboard's Traffic Sent graph.
I've reviewed all uses of file_get_contents and curl_exec within the app's scripts, not including those in /vendor/, and don't believe these to be the cause.
Is there a simple way in which I can review more info on these outbound requests?
There is no way to get more details in that dashboard. You're going to need to check your logs at the corresponding times. Obscure things to check for:
Cron jobs coming in at the same times
Task Queues spinning up

Using 1 intance of google-app-engine to monitor external service

I planning to create a NodeJS program, that work 24/7, that ping and make requests to an external server (outside of google cloud) every minute. Just to see that it the external services are are live.
If there is any error it will notify me by SMS & Email.
I don't need any front-end for this app, and no one needs to connect to it. Just simple NodeJS program.
The monitoring and configuration will be by texts files.
Now the questions:
It looks like it will cost me just $1.64. It sounds very cheap. Am I missing something?
It needs to work around the clock, I will request it to start it once, and it need to continue working, (by using setInterval). Is it will be aborted?
What it is exactly mean buy 1 instance. What an instance can do? Only respond to one request or what?
I tried to search in Google: appengine timeout, but didn't found anything that helps.
Free Quota
If you write your application in Python, PHP, Go or Java it can fit in free usage quota:
https://cloud.google.com/appengine/docs/quotas
So there will be absolutely no costs to run it on Google App Engine platform.
There are limit of 657,000 UrlFetch API Calls per day (more than 450 calls per minute in 24/7 mode) for free apps. 4GB traffic may also be sufficient for this kind of work.
Keep in mind there is no SMS sending services provided by Google App Engine and you will need to spend additional UrlFetch API calls to use external SMS services.
Email sending is also limited to 100 Emails per day (or 5000 Emails to admin address), so try not so send repeated notifications about same monitored server every minute, or you'll deplete your Email quote in 1.5 hours.
Scheduled Tasks
There is no way to run single process indefinitely without interruption on App Engine. But you don't have to!
You'll need to encapsulate all the work you're planning to execute in every iteration into single task and then schedule it to run every minute with Cron. See this documentation for Python: https://cloud.google.com/appengine/docs/python/config/cron
It is recommended to have some configuration page where you can set some internal configuration or see monitoring statistics, at least manage flag to temporarily pause tasks execution without redeploying your app.

getLastAccessedTime() in GWT sessions returns 0

I'm trying to add timeouts to GWT sessions, by using the following code to check if a session is alive:
public boolean isSessionAlive() {
return System.currentTimeMillis() - getThreadLocalRequest().getSession()
.getLastAccessedTime() < timeout;
}
I based this code on many examples I saw on web for GWT sessions, such as this.
The above code works great while running on a local web server, but after deploying the project to App Engine it doesn't. The following always returns 0 on App Engine:
getThreadLocalRequest().getSession().getLastAccessedTime()
As far as I understand, the last accessed time is updated on each RPC call.
I made several calls, but this value still remains zero and incorrect result is returned.
Does anybody know how to fix this issue?
Things will change after deployed on GAE
Just today attended the session on app engine by #roman irani .
remember that App Engine is a distributed architecture so a difference from Java EE is that you are never guaranteed the same application server instance during request processing as the previous request. While the object is being serialized correctly in memcache, you still have to call setAttribute() every time due to the fact that memory is not shared.
Clear cut picture here to handle the session
I have found a workaround. Adding the following code in war/WEB-INF/web.xml will cause the session to expire after 30 minutes:
<!-- timeout in minutes -->
<session-config>
<session-timeout>30</session-timeout>
</session-config>
Reference: Session Timeouts with GWT RPC calls.

How do dynamic backends start in Google App Engine

Can we start a dynamic backend programatically? mean while when a backend is starting how can i handle the request by falling back on the application(i mean app.appspot.com).
When i stop a backend manually in admin console, and send a request to it, its not starting "dynamically"
Dynamic backends come into existence when they receive a request, and
are turned down when idle; they are ideal for work that is
intermittent or driven by user activity.
Resident backends run continuously, allowing you to rely on the state
of their memory over time and perform complex initialization.
http://code.google.com/appengine/docs/python/backends/overview.html
I recently started executing a long running task on a dynamic backend and noticed a dramatic increase in the performance of the frontends. I assume this was because the long running task was competing for resources with normal user requests.
Backends are documented quite thoroughly here. Backends have to be started and stopped with appcfg or the admin console, as documented here. A stopped backend will not handle requests - if you want this, you should probably be using the Task Queue instead.
It appears that a dynamic backend need not be explicitly stopped. The overvicew (http://code.google.com/appengine/docs/python/backends/overview.html) states that the billing for a dynamic backend stops 15 minutes after the last request is processed. So, if your app has a cron job, for example, that requires 5 minutes to complete, and needs to run every hour, then you could configure a backend to do this. The cost you'll incur is 15+5 minutes every hour, or 8 hours for the whole day. I suppose the free quota allows you 9 backend hours. So, this type of scenario would be free for you. The backend will start when you send your first request to it through a queue, and will stop 15 minutes after the last request you send is processed completely.

Resources