Thursday, November 14, 2013

Well, that was fun

So I completed work on my Google Cloud Developer Challenge project and it's live and submitted for consideration. I even put together a quick video walkthrough. Now it's time to sit back, cross my fingers and hope for the best.

The last few days have been a mad scramble, as I was done earlier, but when it came to deploying the project on the real live AppEngine, I ran into a series of production issues. The big one I posted about on StackOverflow, but after not getting any help there, I stumbled across this brilliant AppEngine/CodeIgniter boilerplate on GitHub, so I restarted the project from that and copied my controllers, models and views over there. That worked, so then it was small polish things.

+Ian Barber wrote a great post about improving the credential flow, so that inspired me to come up with a logo, which I did with the Drawing app in Google Drive. I also took out the Drive scope since I wasn't yet using Drive, although I think I will at some point, so the users can pull in files from Drive as well as save their results there.

Then when it time to submit the app, I realized the domain had to be in the format gcdc2013-X.appspot.com. D'oh! Since you cannot rename the instance name, I then had to go and create a new application, configure it, setup billing, etc for the new (& proper) name.

So now we wait & see.


Saturday, November 9, 2013

Great news, even! [appengine project]

Not sure why I didn't stumble upon this until now, but I'm glad that I waited to develop the user aspect to my project. The PHP AppEngine folks have an unofficial blog with some neat tips & tricks, including this dandy to get the Google PHP API client library working inside of your AppEngine app. This is huge because with the library, you can take advantage of some of Google's modern systems.

So now instead of using AppEngine's native User class, I can now use my OAuth login approach. The old (2007!) User class was ok, but you aren't able to do much with the resulting user, beyond getting their nickname and ID #. With OAuth, you can get their profile picture to slap into your header, ask them to integrate with their other services (which you can use the library for, too).

My guess is that Google's working towards getting the library integrated into the runtime, but there's probably some dust that needs to settle somewhere.

Wednesday, November 6, 2013

Fun with AppEngine Task Queues

So AppEngine Task Queues are fun and I say that without really digging deeply in the matter. As part of my project, I incorporated them because I figured my app may take a while to crunch through the data. You have a 60 second limit to normally respond to a user's request, which is probably sufficient enough for my needs, but just in case, I decided to use a Task Queue. That increases the crunching time limit to 10 minutes, which should totally be fine for my needs. If you need more than 10 minutes, I would suggest breaking your crunching into smaller tasks.

One of the issues I ran into was that my task would not execute. I set up the code in its own CodeIgniter controller and I was able to directly access it with my web browser, but when I added the URL to the task queue, it would just sit there. It would try to execute, but nothing would happen. I found my first clue in my AppEngine logs, which read something like this:

INFO     2013-11-06 02:52:10,700 module.py:608] default: "POST /worker/process_set HTTP/1.1" 302 -WARNING  2013-11-06 02:52:10,700 taskqueue_stub.py:1980] Task task4 failed to execute. This task will retry in 0.800 seconds


A task has to return a status between 200 and 299 (inclusive), so that 302 was the clue. 302 is the code for Found and usually is followed by an HTTP redirect Location header. I tried several different things, but what finally worked was declaring the worker path explicitly in my app.yaml (vs. letting the default handler take care of it). This is something I would have to do eventually to lock down the URL from any external requests.

Saturday, November 2, 2013

Uploading in GAE is different

Chugging right along and hit a speed bump, figured it out and got it working. Coming from the CodeIgniter File Uploading Class, the Google AppEngine (GAE) approach is totally different. You pretty much have to throw away what you know & use there. Direct file uploads to your handler will not work. You have to use the GAE API to create a dynamic upload URL to put as your form's action. You miss out on CI's ability to limit file types and image dimensions (you can limit file sizes), but GAE adds cloud storage and the ability to receive very large files (up to 100 TB). GAE passes back the $_FILES super global to a handler you specify when you create the URL.

So the first step is to add the API inclusion in your CI controller. Then in your handler that creates the upload form, you call createUploadUrl and pass that into your template for the form action parameter. Then you create another handler (which name you used in the aforementioned createUploadUrl method) and you can verify the upload from the $_FILES parameter and then do whatever you need.

Here's what my controller ended up looking like:

The Google documentation on the topic was a really good reference. Note that the user has 10 minutes until that dynamic URL expires.

Friday, November 1, 2013

CodeIgniter routing with AppEngine

A few more steps forward on my Deduper project. I designed out the URL's and got the rudimentary homepage and create set form going. Also got it integrated with my local MySQL install. The one thing I learned lately is that with CodeIgniter in Google AppEngine, you have to configure the index_page (in config/config.php) to be blank so index.php doesn't get injected into the various URL's it creates. My app.yaml directs all requests already to index.php, so the extra index.php confuses CodeIgniter's routing.