cis 192: lecture 12 deploying apps and concurrencycis192/fall2014/files/lec12.pdf · i virtualenv...

Post on 25-Sep-2020

2 Views

Category:

Documents

0 Downloads

Preview:

Click to see full reader

TRANSCRIPT

CIS 192: Lecture 12Deploying Apps and Concurrency

Lili Dworkin

University of Pennsylvania

Good Question from Way Back

I All HTTP requests have 1) URL, 2) headers, 3) body

I GET requests: parameters sent in URL

I POST requests: parameters sent in body

Can GET requests have a body?StackOverflow’s response: “Yes, you can send a request body withGET but it should not have any meaning. If you give it meaning byparsing it on the server and changing your response based on itscontents you’re violating the HTTP/1.1 spec.”

Good Question from Last Week

What is the difference between jsonify and json.dumps?

def jsonify(*args, **kwargs):

if __debug__:

_assert_have_json()

return current_app.response_class(json.dumps(dict(*

args, **kwargs), indent=None if request.is_xhr else

2), mimetype='application/json')

I jsonify returns a Response object

I jsonify automatically sets content-type header

I jsonify also sets the indentation

Review

Find a partner!

Deploying Apps

I We’ve been running Flask apps locally on a builtindevelopment server

I When you’re ready to go public, you need to deploy to aproduction server

I Easiest option: use one hosted by someone else!

I We’ll use Heroku, a platform as a service (PaaS) that makesit easy to deploy apps in a variety of languages

Heroku

Prerequisites:

I Virtualenv (creates standalone Python environments)I Heroku toolbox

I Heroku command-line clientI Git (for version control and pushing to Heroku)

Virtualenv

I Allows us to create a virtual Python environment

I Unique, isolated environment for each project

I Use case: different versions of packages for different projects

Virtualenv

How to use it?

prompt$ pip install virtualenv

Now navigate to your project directory:

prompt$ virtualenv --no-site-packages venv

prompt$ source venv/bin/activate

(<name>)prompt$ pip install Flask gunicorn

(<name>)prompt$ deactivate

prompt%

Heroku Toolbox

Once you make a Heroku account, install the Heroku toolbox.Then login:

prompt$ heroku login

Enter your Heroku credentials.

Email: lilidworkin@gmail.com

Password:

Authentication successful.

Procfile

I Use a Procfile to declare what command should be executedto start server

I One might hope to write “web: python hello.py”

I Instead: “web: gunicorn hello:app”

Flask

I Heroku recognizes Python applications by the existence of arequirements.txt file

I Used to specify the required external modules

I prompt% pip freeze > requirements.txt

I Now anyone can install our dependencies by using pip

install -r requirements.txt

Git

Create a new git repository and save our changes:

prompt$ git init

prompt$ echo venv > .gitignore

prompt$ git add .

prompt$ git commit -m "init"

Deploy

Push the application’s repository to Heroku:

prompt% heroku create

Creating stormy-sands-4409...

http://stormy-sands-4409.herokuapp.com/

Git remote heroku added

prompt% git push heroku master

Concurrency

I A process is a running programI Heavy weightI Separate address spacesI Interact through inter-process communication mechanisms

I A process can have multiple threads which allow it to doseveral things at once

I Light weightI Share the same address spaceI Can interact via shared memory

Threads

I Each thread has its own local state

I All threads share the same global state

I In Python, support is provided by the thread (lower level)and threading (higher level) modules

I Python threads are pre-emptive – may be interrupted atarbitrary times

Threading Module

I Create an instance of a Thread objectI Provide a callable object, i.e. function or method

I What does this mean?I Magic method __call__ is defined!

I Provide a tuple of arguments

I To start a thread object executing, invoke start()

Threads

>>> from threading import Thread

>>> def add(x,y):

... print x+y

...

>>> thread = Thread(target=add, args=(5,6))

>>> thread.start()

11

Ok, but one thread isn’t very interesting ... let’s take a look atbasic_threads.py.

Threads

I How to explain the behavior we just saw?

I The “main” thread (our top-level program) finished before theother threads

I We should use join() – when called on a thread object T,this will cause the calling thread (typically “main”) to blockuntil T finishes

Practical Example

I When to use threads in the “real world”?

I One use case: HTTP requests!

I web.py

Problems with Threads

I What happens when a thread gets interrupted in the middleof modifying shared memory?

I threads.py

I The line var[0] += 1 does not execute atomicallyI Thread first has to read var[0]I Then compute var[0] + 1I Then set var[0] to what it just computed

I The thread could be interrupted between any of those actions,and var[0] could be changed without it knowing

Locks

I In order to use shared state, we need to prevent threads fromstepping all over each other

I Mutual exclusion refers to making sure that only some numberof threads (often just 1) are doing something at the same time

I Multiple ways to do this in Python – we will use the Lock class

Locks

lock = Lock()

def inc_var():

lock.acquire()

var[0] += 1

lock.release()

Locks

I Can use with statements with locks!

I Then acquire() and release() get called automatically

lock = Lock()

def inc_var():

with lock:

var[0] += 1

Dining Philosophers

I Between each pair of philosophersis a single chopstick

I Philosophers alternate betweenthinking and eating

I Before eating, first take leftchopstick, then take right

I What if every philosopher takes leftchopstick at the same time?

Global Interpreter Lock (GIL)

The Unwritten Rules of Python:

1. You do not talk about the GIL.

2. You do NOT talk about the GIL.

3. Don’t even mention the GIL. No, seriously.

– David Beazley

Global Interpreter Lock (GIL)

I Only one thread runs in the interpreter at once

I Simplies many low-level details (memory management,callouts to C extensions, etc.)

I But then why did we see a speedup?I When a python thread does something IO related (reading or

writing a file, sending a network request, waiting for aresponse, etc.), it releases the lock

top related