GAE cron job shuts down unexpectedly - java

I have some cron jobs configured in cron.xml in an application on Google App Engine.
These jobs work once a day on a version of my application and make some work on the db.
For example a cron job calls v1.myapp.appspot.com...
After some weeks this application instance seems to no longer work correctly. It does not execute the cron jobs as I expect.
On GAE Dashboard I found a section with a list of cron job, but I can't see my cron jobs there.
Why did they disapper? What's wrong with my configuration environment? or Why google stops the execution of my cron jobs?

The cron job configuration is an app-wide scope configuration, it's not a configuration of a specific service/version. Every cron deployment (which can be done without necessarily updating a service/version) will overwrite the previously deployed one.
To avoid accidental errors personally I have a single cron config file at the app level, symlinked inside each service as needed.
If you want to keep the cron job for an older version running you need to add a configuration entry for it with a target matching that service/version, otherwise the cron job will stop working when that version is no longer the default one (as the cron-triggered requests will be directed towards the default service/version):
From Creating a cron job:
<?xml version="1.0" encoding="UTF-8"?>
<cronentries>
<cron>
<url>/tasks/summary</url>
<target>beta</target>
<description>daily summary job</description>
<schedule>every 24 hours</schedule>
</cron>
</cronentries>
The target specification is optional and is the name of a
service/version. If present, the target is prepended to your app's
hostname, causing the job to be routed to that service/version. If no
target is specified, the job will run in the default version of the
default service.

Related

How to make a cron job in App Engine that targets a service and a version?

I want to have a cron job that calls my endpoint at a certain services and version (App Engine).
I have created a cron job with the following config:
<?xml version="1.0" encoding="UTF-8"?>
<cronentries>
<cron>
<url>/CleanupRealtimeDatabase</url>
<target>dev-dot-admin</target>
<description>Cleanup Realtime Database (Dev)</description>
<schedule>every 24 hours</schedule>
</cron>
</cronentries>
This will make a call to http://dev-dot-admin.myapp.appspot.com/CleanupRealtimeDatabase
This doesn't work, because it can not combine the -dot- and the .
So the only solution is to use -dot- twice or use . twice. I can't control the second dot in the url (it's not part of the config). But when I change the dot to . in my config above I get the following error:
Bad configuration: XML error validating
/CleanupRealtimeDatabase
dev.admin
Cleanup Realtime Database (Dev)
every 24 hours
against /Users/user/sdk/google-cloud-sdk/platform/google_appengine/google/appengine/tools/java/docs/cron.xsd
Caused by: cvc-pattern-valid: Value 'dev.admin' is not facet-valid
with respect to pattern '[a-z\d-]{1,100}' for type 'target-Type'.
Not sure how to solve this? It feels like a bug in App Engine tooling.
This won't work as the (single) service version that will receive the targeted cron requests is not under the cron configuration control. From the row in the Cron job definitions (emphasis mine):
The target string is prepended to your app's hostname. It is
usually the name of a service. The cron job will be routed to the
version of the named service that is configured for traffic.
Warning: Be careful if you run a cron job with traffic splitting enabled. The request from the cron job is always sent
from the same IP address, so if you've specified IP address splitting,
the logic will route the request to the same version every time. If
you've specified cookie splitting, the request will not be split at
all, because there is no cookie accompanying the request.
If the service name that is specified for target is not found, then the Cron request is routed to either the default service, or to
the version of your app that is configured to receive traffic. For
more information about routing, see How Requests are Routed.
But since the cron service is nothing more than GET requests sent according to the schedule you could have a single generic cron config and, inside its handler, issue yourself more specific HTTP(S) requests to any URLs you desire.
You could use the apps.services.versions API in order to dynamically build the correct list of these per service-version pair URLs.

how to start Quartz Scheduler automatically in Java

I'm using Quartz Scheduler 2.2.1 in a webapp which is built on Tomcat webserver. I use a servlet to start Quartz . However, if the system reboots, I also have to restart Quartz manually by sending request to that servlet. Therefore, the problem is how to start Quartz automatically !
One more thing that is I want to use Quartz to perform a task at 00:00:00 everyday, so what is the best design for the trigger in this case ?
Define a ServletContextListener and implement a contextInitialized() method that starts quartz. This listener gets triggered if the tomcat is restarted or your servlet is redeployed
You should use a custom ServletContextListener and configure it in your web.xml for automatically starting your cron job.
http://docs.oracle.com/cd/B14099_19/web.1012/b14017/filters.htm#i1000654
If not satisfied by the Oracle link, do a little Google and you will get plenty of examples
To start a cron job every day at 12:00 am the below cron pattern should work:
0 0 0 * * ?

How does the JDBCJobStore work .?

So I started to tinker around with JDBCJobStore in Quartz. Firstly, I could not find a single good resource on how to configure it from scratch. After looking for it for a while and singling out a good resource for beginners, I downloaded the sample application at Job scheduling with Quartz. I have a few doubts regarding it.
How does JDBCJobStore capture jobs.? I mean in order for the job to get stored in the database does the job have to run manually once.? Or will JDBCJobStore automatically detect the jobs and their details..?
How does JDBCJobStore schedule the jobs.? Does it hit the database at a fixed interval like a heartbeat to check if there are any scheduled jobs.? Or does it keep the triggers in the memory while the application is running.?
In order to run the jobs will I have to manually specify the details of the job like like name and group and fetch the trigger accordingly.? Is there any alternative to this.?
On each application restart how can I tell the scheduler to start automatically..? Can it be specified somehow.?
If you are using servlet/app server you can start it during startup:
http://quartz-scheduler.org/documentation/quartz-2.2.x/cookbook/ServletInitScheduler
If you are running standalone you have to initialize it manually i think.
You can read more about JobStores here:
http://quartz-scheduler.org/documentation/quartz-2.2.x/tutorials/tutorial-lesson-09
And about jobs and triggers:
http://quartz-scheduler.org/documentation/quartz-2.2.x/tutorials/tutorial-lesson-02
http://quartz-scheduler.org/documentation/quartz-2.2.x/tutorials/tutorial-lesson-03
http://quartz-scheduler.org/documentation/quartz-2.2.x/tutorials/tutorial-lesson-04
I guess that quartz checks jobs based on time interval to proper work in clusters and distributed systems.

GAE : How to configure backends.xml for long time working process

In my java application i'm processing one lack data per day using cron job but it cannot be properly do with cron jobs (DeadLineExceedException) and 10 minute is not enough to complete the process. So i would like switch the process to backends.xml. But i don't know how to move backends.xml. How can i start the process at a fixed time after moving to backends.
If I understand it correctly, you want your Cron jobs to be executed at your backend in order to have a longer deadline in processing jobs. You can add <target>[backend_version]</target> on the cron job definition in your cron.xml in order to have the cron executed at a specific version of your app.
Combined with your backends.xml file, this means that you could configure both files as per the following examples:
backends.xml
<backends>
<backend name="longtimeworker">
<class>B1</class>
<instances>1</instances>
</backend>
and
cron.xml
<cronentries>
<cron>
<url>/longtimeworkingprocesshandler</url>
<schedule>every 12 hours</schedule>
<target>longtimeworker</target>
</cron>
That way, you can configure your cron to be executed at the longtimeworker backend.

running a cron job just once

how can we schedule a cron job to run just once on google app engine for java?
i tried to set a very large value like every 1000 years but doesnt seems to work.
any other option? syntax used is:
<cron>
<url>/AdHocScriptJob</url>
<description>Run adhoc script</description>
<schedule>every 200 minutes</schedule>
<timezone>Asia/Calcutta</timezone>
</cron>
i tried to look at https://developers.google.com/appengine/docs/java/config/cron
That's what task queues are for: https://developers.google.com/appengine/docs/java/taskqueue/overview
Alternatively, you may delete the cron configuration after the task executes or make your code idempotent (e.g. by mixing it with a pull queue).

Categories