CIS 192: Lecture 12 Deploying Apps and Concurrencycis192/fall2014/files/lec12.pdf · I Virtualenv...

26
CIS 192: Lecture 12 Deploying Apps and Concurrency Lili Dworkin University of Pennsylvania

Transcript of CIS 192: Lecture 12 Deploying Apps and Concurrencycis192/fall2014/files/lec12.pdf · I Virtualenv...

Page 1: CIS 192: Lecture 12 Deploying Apps and Concurrencycis192/fall2014/files/lec12.pdf · I Virtualenv (creates standalone Python environments) I Heroku toolbox I Heroku command-line client

CIS 192: Lecture 12Deploying Apps and Concurrency

Lili Dworkin

University of Pennsylvania

Page 2: CIS 192: Lecture 12 Deploying Apps and Concurrencycis192/fall2014/files/lec12.pdf · I Virtualenv (creates standalone Python environments) I Heroku toolbox I Heroku command-line client

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.”

Page 3: CIS 192: Lecture 12 Deploying Apps and Concurrencycis192/fall2014/files/lec12.pdf · I Virtualenv (creates standalone Python environments) I Heroku toolbox I Heroku command-line client

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

Page 4: CIS 192: Lecture 12 Deploying Apps and Concurrencycis192/fall2014/files/lec12.pdf · I Virtualenv (creates standalone Python environments) I Heroku toolbox I Heroku command-line client

Review

Find a partner!

Page 5: CIS 192: Lecture 12 Deploying Apps and Concurrencycis192/fall2014/files/lec12.pdf · I Virtualenv (creates standalone Python environments) I Heroku toolbox I Heroku command-line client

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

Page 6: CIS 192: Lecture 12 Deploying Apps and Concurrencycis192/fall2014/files/lec12.pdf · I Virtualenv (creates standalone Python environments) I Heroku toolbox I Heroku command-line client

Heroku

Prerequisites:

I Virtualenv (creates standalone Python environments)I Heroku toolbox

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

Page 7: CIS 192: Lecture 12 Deploying Apps and Concurrencycis192/fall2014/files/lec12.pdf · I Virtualenv (creates standalone Python environments) I Heroku toolbox I Heroku command-line client

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

Page 8: CIS 192: Lecture 12 Deploying Apps and Concurrencycis192/fall2014/files/lec12.pdf · I Virtualenv (creates standalone Python environments) I Heroku toolbox I Heroku command-line client

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%

Page 9: CIS 192: Lecture 12 Deploying Apps and Concurrencycis192/fall2014/files/lec12.pdf · I Virtualenv (creates standalone Python environments) I Heroku toolbox I Heroku command-line client

Heroku Toolbox

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

prompt$ heroku login

Enter your Heroku credentials.

Email: [email protected]

Password:

Authentication successful.

Page 10: CIS 192: Lecture 12 Deploying Apps and Concurrencycis192/fall2014/files/lec12.pdf · I Virtualenv (creates standalone Python environments) I Heroku toolbox I Heroku command-line client

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”

Page 11: CIS 192: Lecture 12 Deploying Apps and Concurrencycis192/fall2014/files/lec12.pdf · I Virtualenv (creates standalone Python environments) I Heroku toolbox I Heroku command-line client

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

Page 12: CIS 192: Lecture 12 Deploying Apps and Concurrencycis192/fall2014/files/lec12.pdf · I Virtualenv (creates standalone Python environments) I Heroku toolbox I Heroku command-line client

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"

Page 13: CIS 192: Lecture 12 Deploying Apps and Concurrencycis192/fall2014/files/lec12.pdf · I Virtualenv (creates standalone Python environments) I Heroku toolbox I Heroku command-line client

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

Page 14: CIS 192: Lecture 12 Deploying Apps and Concurrencycis192/fall2014/files/lec12.pdf · I Virtualenv (creates standalone Python environments) I Heroku toolbox I Heroku command-line client

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

Page 15: CIS 192: Lecture 12 Deploying Apps and Concurrencycis192/fall2014/files/lec12.pdf · I Virtualenv (creates standalone Python environments) I Heroku toolbox I Heroku command-line client

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

Page 16: CIS 192: Lecture 12 Deploying Apps and Concurrencycis192/fall2014/files/lec12.pdf · I Virtualenv (creates standalone Python environments) I Heroku toolbox I Heroku command-line client

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()

Page 17: CIS 192: Lecture 12 Deploying Apps and Concurrencycis192/fall2014/files/lec12.pdf · I Virtualenv (creates standalone Python environments) I Heroku toolbox I Heroku command-line client

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.

Page 18: CIS 192: Lecture 12 Deploying Apps and Concurrencycis192/fall2014/files/lec12.pdf · I Virtualenv (creates standalone Python environments) I Heroku toolbox I Heroku command-line client

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

Page 19: CIS 192: Lecture 12 Deploying Apps and Concurrencycis192/fall2014/files/lec12.pdf · I Virtualenv (creates standalone Python environments) I Heroku toolbox I Heroku command-line client

Practical Example

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

I One use case: HTTP requests!

I web.py

Page 20: CIS 192: Lecture 12 Deploying Apps and Concurrencycis192/fall2014/files/lec12.pdf · I Virtualenv (creates standalone Python environments) I Heroku toolbox I Heroku command-line client

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

Page 21: CIS 192: Lecture 12 Deploying Apps and Concurrencycis192/fall2014/files/lec12.pdf · I Virtualenv (creates standalone Python environments) I Heroku toolbox I Heroku command-line client

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

Page 22: CIS 192: Lecture 12 Deploying Apps and Concurrencycis192/fall2014/files/lec12.pdf · I Virtualenv (creates standalone Python environments) I Heroku toolbox I Heroku command-line client

Locks

lock = Lock()

def inc_var():

lock.acquire()

var[0] += 1

lock.release()

Page 23: CIS 192: Lecture 12 Deploying Apps and Concurrencycis192/fall2014/files/lec12.pdf · I Virtualenv (creates standalone Python environments) I Heroku toolbox I Heroku command-line client

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

Page 24: CIS 192: Lecture 12 Deploying Apps and Concurrencycis192/fall2014/files/lec12.pdf · I Virtualenv (creates standalone Python environments) I Heroku toolbox I Heroku command-line client

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?

Page 25: CIS 192: Lecture 12 Deploying Apps and Concurrencycis192/fall2014/files/lec12.pdf · I Virtualenv (creates standalone Python environments) I Heroku toolbox I Heroku command-line client

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

Page 26: CIS 192: Lecture 12 Deploying Apps and Concurrencycis192/fall2014/files/lec12.pdf · I Virtualenv (creates standalone Python environments) I Heroku toolbox I Heroku command-line client

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