WESLEY: Hi, and welcome to "Serverless Migration Station,"
a serverless expedition miniseries dedicated
to helping developers modernize their apps to using the latest
features available to one of our serverless compute platforms.
Today, we're continuing our coverage
of migrating from App Engine Task Queues to Cloud Tasks.
MARTIN: Sounds great, and I'm so happy to be here, Wes.
Last time, in module 7, we added App Engine Task Queues,
specifically push tasks, to our sample App Engine NDB Flask
app.
So what are we doing today?
WESLEY: Oh, that's right, Martin.
For those who haven't seen the module 7 video
or completed its codelab, please pause here to do so,
because we pick up from where module 7 leaves off.
Today we're migrating from App Engine
NDB to Cloud NDB and App Engine Task Queues to Cloud Tasks.
All the links you need are down below.
MARTIN: Now, wait, Wes.
Did you say we're migrating from App Engine NDB and App Engine
Task Queues to Cloud NDB and Cloud Tasks?
Isn't that two migrations?
WESLEY: That's right, Martin.
While the code will undergo both migrations,
we're only focused on App Engine Task Queues to Cloud Tasks,
because moving from App Engine NDB to Cloud NDB
was already covered in module 2.
Modernizing your apps means moving off of the legacy App
Engine services like NDB and Task Queues
to standalone services like Cloud NDB and Cloud Tasks.
So we're doing both at the same time,
preparing our app to upgrade to Python 3 next in module 9.
So for all of you, the same drill as earlier with module 7.
If you haven't seen the module 2 video or completed its codelab,
we invite you to pause and do that here
so you're familiar with it as we're going to concentrate only
on Task Queues here.
MARTIN: Wow.
That's a lot of review, but I think I'm caught up now.
WESLEY: That's great, Martin.
Now that you're up to speed, let's
talk about what we're doing.
Remember the code from module 7 where
we deleted all visits older than the oldest displayed
from Datastore?
Well, we're going to keep that functionality,
but moving the code to Cloud Tasks.
Since it's a standalone product, there's a little bit more setup
to do.
In addition, we're also migrating from Engine NDB
to Cloud NDB, as mentioned before.
MARTIN: Sounds good.
I'm going to do this by hand while you are explaining it.
So would you please point me to the code and the codelab?
WESLEY: Oh, for sure, Martin.
If you did the module 7 codelab, please start
with your own code base.
But if you didn't, clone the repo or download the zip file.
We're going to start with the module 7 code
and finish with what's in the module 8 folder.
Here's the codelab as well, so pause one more time
to get everything you need.
Once you're ready, let's go to the computer
and migrate it now.
If you don't have a confirmed working module 7 app yet,
upload to App Engine with gcloud app deploy.
Most users watching this video will be on Python 2.
So if that's the case, ensure your lib folder is ready to go.
If not, or you're unsure, delete what you have
and run pip install so that you have it.
Confirm the app's the same as from module 7,
whether it's your own or ours.
Once you have, then you're ready to go.
Changes to the config files are nearly identical to the changes
made in module 2.
We're adding use of the Google Cloud client libraries,
and these changes include adding required built-in packages that
go into app.yaml instead of requirements.txt.
Now, any time built-in libraries are used,
a few more lines of code have to be
added to appengine_config to point your app to them,
so make these changes as well.
Now let's do the non-built-in libraries, like Cloud NDB.
In module 2, we added Cloud NDB to requirements.txt.
This time we're also going to add the Cloud Tasks library.
Python 2 users should now delete their lib folder
and run the pip install command to install
Flask, Cloud NDB, and Cloud Tasks to the lib folder.
Again, these updates are just like in module 2,
but adding both Cloud NDB and Cloud Tasks.
Now let's move to main.py.
At the top, swap out the imports of App Engine's Task Queue
and NDB libraries and replacing them with the Google Cloud
equivalents.
The payload sent to Cloud Tasks needs to be JSON encoded,
so we're going to have to use that standard library
module as well.
Next, most cloud libraries require a client
for each service you're using--
in our case, Cloud NDB and Cloud Tasks.
More specifically, Cloud Tasks requires a project ID
and an apps region along with the queue name.
Now, this wasn't required with App Engine Task Queues,
but recognize that Cloud Tasks is now
a separate product that can work with both App Engine
and not App Engine apps, hence the extra red tape.
Fortunately, its client provides a convenience function
named QUEUE_PATH that builds a fully qualified path
string for us.
Be sure to swap in your app's values
into the placeholder constants.
Now, creating a new visit and querying the most recent visits
doesn't really change.
The only difference is due to Cloud NDB
requiring use of its Python context manager
when making Datastore calls.
So you'll see a new width block containing such calls
in both store_visit and fetch_visits.
Review the module 2 codelab and video
if you need more information here.
For us in module 7, things get really interesting from here
on out, meaning that once we grab
the timestamp of the oldest visit displayed,
we can move on.
With the App Engine Task Queue library,
it's a single call to create a push task
and respond back to the user.
With Cloud Tasks, it's also a single call.
However, there's a little bit more setup.
After logging the oldest time stamp,
you see the necessary payload that Cloud Tasks
needs, a flag indicating an App Engine request, a handler
URI, JSON-encoded parameters, and an HTTP header.
Pass this data, plus the Task Queue path from the above,
to create task.
That's it, and the return doesn't change.
As far as the task goes, not much change here either.
Yes, pulling out the parameter is slightly different.
Any Datastore code is within a with blog.
But querying, logging, and deletion of old entities
is pretty much the same.
There are very few changes here because it's mostly still
the same HTTP POST method we had in module 7.
Cloud Tasks is just an alternative execution platform.
You really shouldn't need to change anything in the handler.
Finally, there are no changes to the main application handler
route.
Ensure you've made all the updates we just
covered to your sample app.
After uploading with gcloud app deploy,
it should run exactly the same as before,
except now it uses Cloud Tasks.
If you're using no other legacy App Engine services,
it is now safe to port your app to Python 3.
Congratulations.
MARTIN: Cool.
Thanks for showing us that, Wes.
I'm surprised how similar Cloud Tasks is to App Engine push
tasks.
Is there a guide to help me get a better
grasp of migrating App Engine push queues to Cloud Tasks?
WESLEY: Oh, definitely.
Below, you're going to find a link to the specific migration
guide for moving push queues to Cloud Tasks.
MARTIN: OK, and while you're at it,
can you also point me to the docs for the original App
Engine Task Queues as well as Cloud Tasks?
WESLEY: Rest assured, my friend.
Links to both of those are also down below.
MARTIN: Sounds good.
Usually about this time, I ask you
what other migrations we should look at,
but that's not the case today, is it?
WESLEY: No, Martin, it's not.
The next step is for you to stay tuned for module 9, where we're
going to port this module 8 app, that we just
finished looking at, to Python 3,
including an optional migration to Cloud Firestore.
And we look forward to having you join us on that excursion.
This is Wesley on behalf of Martin and Porter,
and we'll see you at that next "Migration Station"
or on another serverless expedition soon.
In the meantime, happy travels.
[MUSIC PLAYING]