5
\$\begingroup\$

I have a paid app on the app engine. At the moment, usually there is only one instance. The app has a download handler that sends an image after re-sizing it if it is too big. The problem is: if a web page contains many big images (60 or more) the app engine creates another instance. I'm trying to keep the app as cheap as possible and creating too many instances is probably not good for that.

Is there a way to improve this code? Or my concerns are just unfounded?

The application settings are:

automatic_scaling:
  min_idle_instances: 1
  max_pending_latency: 10s

The code:

class ServeHandler(blobstore_handlers.BlobstoreDownloadHandler):
  def get(self, resource):
    resource = str(urllib.unquote(resource))
    blob_info = blobstore.BlobInfo.get(resource)
    if not blob_info:
        pass
    else:
        data = blobstore.fetch_data(blob_info.key(), 0, 50000)
        img0 = images.Image(image_data=data)
        img = images.Image(blob_key=blob_info.key())
        if img0.width >= 800:
            img.resize(width=800)
            img = img.execute_transforms(output_encoding=images.JPEG)
            self.response.headers['Content-Type'] = 'image/jpeg'
            self.response.out.write(img)
        else:
            self.send_blob(blob_info)
\$\endgroup\$
  • 1
    \$\begingroup\$ why not change away from automatic scaling? automatic scaling aggressively spins up new instances. If you want more granular control, consider manual scaling \$\endgroup\$ – Patrice Feb 4 '15 at 18:17
  • \$\begingroup\$ I know, at the moment I prefer to keep automatic scaling. \$\endgroup\$ – chairam Feb 4 '15 at 18:28
  • \$\begingroup\$ is this production code? \$\endgroup\$ – Malachi Feb 4 '15 at 18:43
  • \$\begingroup\$ Do you know about images.get_serving_url? \$\endgroup\$ – Greg Feb 4 '15 at 18:44
  • 1
    \$\begingroup\$ @Malachi yes it does, this is actual code. \$\endgroup\$ – user164483 Feb 4 '15 at 18:56
1
\$\begingroup\$

PEP0008 says use 4 spaces for indentation, it's much clearer where one block starts and another ends that way.

This may be a placeholder but I'll assume your code posted here is real code and say that you should just use if blob_info and remove the pointless pass and else.

if not blob_info:
    pass
else:

I also think you could reformat for better whitespace to make your code more readable. You currently use none and that gives a wall of text effect. This looks nicer:

class ServeHandler(blobstore_handlers.BlobstoreDownloadHandler):

    def get(self, resource):
        resource = str(urllib.unquote(resource))
        blob_info = blobstore.BlobInfo.get(resource)

        if blob_info:
            data = blobstore.fetch_data(blob_info.key(), 0, 50000)
            img0 = images.Image(image_data=data)
            img = images.Image(blob_key=blob_info.key())

            if img0.width >= 800:
                img.resize(width=800)
                img = img.execute_transforms(output_encoding=images.JPEG)
                self.response.headers['Content-Type'] = 'image/jpeg'
                self.response.out.write(img)
            else:
                self.send_blob(blob_info)

You should also add a docstring to your class at least. I can't suggest one given my limited knowledge of your script but they're always helpful for a class.

\$\endgroup\$
0
\$\begingroup\$

As Greg suggests: when you use a get serving url Google will serve the image for you without instances you have to pay for.

You only have to create the serving url once. When you save it you can use it in all your HTML which use the image.

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.