-
Notifications
You must be signed in to change notification settings - Fork 1.9k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Cleaned up memcached example and added tests. #26
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -34,6 +34,7 @@ cache: | |
|
||
services: | ||
- redis-server | ||
- memcached | ||
- docker | ||
|
||
env: | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,65 +1,93 @@ | ||
# Express + Memcached Sessions -> Google App Engine | ||
## Express.js + Memcached Sessions on Google App Engine | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Seems like this readme is too heavy. What's the point of the sample code if you put everything in the readme? :P There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I made the readme more lightweight, it now mirrors more closely the format used by the tutorials for the other framework examples. |
||
|
||
This is a simple guide to using memcached for session state while running [expressjs](http://expressjs.com/) on Google App Engine. Each Google App Engine application comes with a memcached service instance, which can be reached with a standard memcached driver at `memcache:11211`. | ||
This is a simple guide to using memcached for session state while running | ||
[Express.js](http://expressjs.com/) on Google App Engine. Each Google App Engine | ||
application comes with a memcached service instance, which can be reached with a | ||
standard memcached driver at `memcache:11211`. This sample uses the | ||
[connect-memcached](https://github.com/balor/connect-memcached) module to store | ||
session data in memcached. | ||
|
||
1. [Create a new Express app](http://expressjs.com/starter/generator.html) | ||
## Clone the Express.js + Memcached Sessions app | ||
|
||
2. Create an `app.yaml` in the root of your application with the following contents: | ||
If you haven't already, copy the repository to your local machine by entering | ||
the following command in your terminal window: | ||
|
||
```yaml | ||
runtime: nodejs | ||
vm: true | ||
env_variables: | ||
PORT: 8080 | ||
MEMCACHE_URL: memcache:11211 | ||
``` | ||
``` | ||
$ git clone https://github.com/GoogleCloudPlatform/nodejs-docs-samples.git | ||
$ cd nodejs-docs-samples/appengine/express-memcached-session | ||
``` | ||
|
||
Alternatively, you can [download the sample][download] as a zip and extract it. | ||
|
||
## Run the app on your local computer | ||
|
||
1. Install dependencies. Enter the following command: | ||
|
||
Notice the MEMCACHE_URL environment variable - this is where you can reach your standard memcached cluster across instances. | ||
3. Use the [connect-memcached](https://github.com/balor/connect-memcached) module. Run `npm install --save connect-memcached`, and add the following to your server.js or app.js: | ||
|
||
```js | ||
var MemcachedStore = require('connect-memcached')(session); | ||
... | ||
app.use(session({ | ||
secret: 'appengineFTW', | ||
key: 'test', | ||
proxy: 'true', | ||
store: new MemcachedStore({ | ||
hosts: [process.env.MEMCACHE_URL || '127.0.0.1:11211'] | ||
}) | ||
})); | ||
``` | ||
4. In your express route handlers, you can now safely use `req.session.*` across multiple nodejs instances: | ||
|
||
```js | ||
app.get('/', function(req, res){ | ||
publicIp.v4(function (err, ip) { | ||
res.write("<div>" + ip + "</div>"); | ||
if(req.session.views) { | ||
++req.session.views; | ||
} else { | ||
req.session.views = 1; | ||
} | ||
res.end('Viewed <strong>' + req.session.views + '</strong> times.'); | ||
}); | ||
}); | ||
$ npm install | ||
``` | ||
|
||
5. To test the sample locally, you can install memcached. | ||
- OSX + [Brew](http://brew.sh/): `brew install memcached` | ||
- Windows + [Chocolatey](https://chocolatey.org/packages/memcached): `choco install memcached` | ||
2. Run the start script. | ||
|
||
Run memcached on localhost:11211 by running `memcached` | ||
|
||
```` | ||
$ npm start | ||
``` | ||
6. Deploy your app. For convenience, you can use an npm script to run the command. Modify your `package.json` to include: | ||
3. In your web browser, enter the following address: | ||
```js | ||
"scripts": { | ||
"start": "node server.js", | ||
"deploy": "gcloud preview app deploy app.yaml --set-default --project [project id]" | ||
} | ||
``` | ||
$ http://localhost:8080 | ||
``` | ||
You can see the sample app displayed in the page. This page was delivered by the | ||
Express.js web server running on your computer. | ||
In your terminal window, press Ctrl+C to exit the web server. | ||
## Deploy the app to Google Cloud Platform | ||
In your terminal window, enter the following command to deploy the sample: | ||
``` | ||
$ gcloud preview app deploy app.yaml --promote | ||
``` | ||
### See the app run in the cloud | ||
In your web browser, enter the following address: | ||
``` | ||
https://<your-project-id>.appspot.com | ||
``` | ||
For convenience, you can use an npm script to run the gcloud command. Add these lines to your package.json file: | ||
``` | ||
"scripts": { | ||
"start": "node server.js", | ||
"deploy": "gcloud preview app deploy app.yaml --promote --project <your-project-id>" | ||
} | ||
``` | ||
At the terminal you can now run the following command to deploy your application: | ||
``` | ||
$ npm run deploy | ||
``` | ||
## Configuration | ||
Every Managed VMs application requires an app.yaml file to describe its deployment configuration. | ||
```yaml | ||
runtime: nodejs | ||
vm: true | ||
env_variables: | ||
PORT: 8080 | ||
MEMCACHE_URL: memcache:11211 | ||
``` | ||
Notice the `MEMCACHE_URL` environment variable–this is where you can reach your | ||
standard memcached cluster across instances. | ||
At the terminal you can now run `npm run deploy` to deploy your application. | ||
[download]: https://github.com/GoogleCloudPlatform/nodejs-docs-samples/archive/master.zip |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -12,7 +12,6 @@ | |
# limitations under the License. | ||
|
||
runtime: nodejs | ||
api_version: 1 | ||
vm: true | ||
env_variables: | ||
PORT: 8080 | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -16,37 +16,40 @@ | |
var express = require('express'); | ||
var session = require('express-session'); | ||
var cookieParser = require('cookie-parser'); | ||
var http = require('http'); | ||
var MemcachedStore = require('connect-memcached')(session); | ||
var publicIp = require('public-ip'); | ||
|
||
var app = express(); | ||
|
||
app.use(cookieParser()); | ||
app.use(session({ | ||
secret: 'appengineFTW', | ||
key: 'test', | ||
proxy: 'true', | ||
store: new MemcachedStore({ | ||
hosts: [process.env.MEMCACHE_URL || '127.0.0.1:11211'] | ||
}) | ||
secret: 'your-secret-here', | ||
key: 'view:count', | ||
proxy: 'true', | ||
store: new MemcachedStore({ | ||
hosts: [process.env.MEMCACHE_URL || '127.0.0.1:11211'] | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Now that you slimmed down the readme, a little comment here about how There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It's set by GAE? So it doesn't need to be set in the There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Nvm, just saw the full thing. A comment in the readme about the There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think there is one at the bottom. |
||
}) | ||
})); | ||
|
||
app.get('/', function(req, res){ | ||
publicIp.v4(function (err, ip) { | ||
|
||
// This shows the IP for each | ||
res.write('<div>' + ip + '</div>'); | ||
if(req.session.views) { | ||
++req.session.views; | ||
} else { | ||
req.session.views = 1; | ||
} | ||
res.end('Viewed <strong>' + req.session.views + '</strong> times.'); | ||
}); | ||
publicIp.v4(function (err, ip) { | ||
|
||
// This shows the IP for each | ||
res.write('<div>' + ip + '</div>'); | ||
|
||
if(req.session.views) { | ||
++req.session.views; | ||
} else { | ||
req.session.views = 1; | ||
} | ||
res.end('Viewed <strong>' + req.session.views + '</strong> times.'); | ||
}); | ||
}); | ||
|
||
http.createServer(app).listen(process.env.PORT || 8080, function() { | ||
if (module === require.main) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. why is this needed here? Is it for tests? I don't often see this in other samples. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. for tests There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. gotcha. |
||
app.listen(process.env.PORT || 8080, function() { | ||
console.log('Listening on %d', this.address().port); | ||
}); | ||
}); | ||
} | ||
|
||
module.exports = app; |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
// Copyright 2015, Google, Inc. | ||
// Licensed under the Apache License, Version 2.0 (the "License"); | ||
// you may not use this file except in compliance with the License. | ||
// You may obtain a copy of the License at | ||
// | ||
// http://www.apache.org/licenses/LICENSE-2.0 | ||
// | ||
// Unless required by applicable law or agreed to in writing, software | ||
// distributed under the License is distributed on an "AS IS" BASIS, | ||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
// See the License for the specific language governing permissions and | ||
// limitations under the License. | ||
|
||
'use strict'; | ||
|
||
var request = require('supertest'); | ||
var app = require('../../appengine/express-memcached-session/server.js'); | ||
|
||
describe('express-memcached-session', function () { | ||
it('should return 200', function (done) { | ||
request(app) | ||
.get('/') | ||
.expect(200) | ||
.end(done); | ||
}); | ||
}); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit that you don't have to fix now: it would be better to have more described anchors here.
express_6
is kinda of funny.