Skip to content

Commit c63cad4

Browse files
committed
Cleaned up memcached example and added tests.
1 parent adc1964 commit c63cad4

File tree

8 files changed

+119
-58
lines changed

8 files changed

+119
-58
lines changed

.travis.yml

+1
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ cache:
3434

3535
services:
3636
- redis-server
37+
- memcached
3738
- docker
3839

3940
env:

README.md

+3
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ and applications on [Google App Engine](http://cloud.google.com/nodejs).
1313
### Frameworks
1414

1515
- Express.js - [Source code][express_1] | [App Engine Tutorial][express_2] | [Live demo][express_3] | [Documentation][express_4]
16+
- Express.js + Memcached Sessions - [Source code][express_5] | [Documentation][express_6]
1617
- Geddy.js - [Source code][geddy_1] | [App Engine Tutorial][geddy_2] | [Live demo][geddy_3] | [Documentation][geddy_4]
1718
- Hapi.js - [Source code][hapi_1] | [App Engine Tutorial][hapi_2] | [Live demo][hapi_3] | [Documentation][hapi_4]
1819
- Loopback.js - [Source code][loopback_1] | [App Engine Tutorial][loopback_2] | [Live demo][loopback_3] | [Documentation][loopback_4]
@@ -68,6 +69,8 @@ See [LICENSE](https://github.com/GoogleCloudPlatform/nodejs-docs-samples/blob/ma
6869
[express_2]: https://cloud.google.com/nodejs/resources/frameworks/express
6970
[express_3]: http://express-dot-nodejs-docs-samples.appspot.com
7071
[express_4]: http://expressjs.com/
72+
[express_5]: https://github.com/GoogleCloudPlatform/nodejs-docs-samples/blob/master/appengine/express-memcached-session
73+
[express_6]: https://github.com/balor/connect-memcached
7174

7275
[geddy_1]: https://github.com/GoogleCloudPlatform/nodejs-docs-samples/blob/master/appengine/geddy
7376
[geddy_2]: https://cloud.google.com/nodejs/resources/frameworks/geddy

appengine/express-memcached-session/README.md

+32-24
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,14 @@
1-
# Express + Memcached Sessions -> Google App Engine
1+
## Express.js + Memcached Sessions on Google App Engine
22

3-
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`.
3+
This is a simple guide to using memcached for session state while running
4+
[Express.js](http://expressjs.com/) on Google App Engine. Each Google App Engine
5+
application comes with a memcached service instance, which can be reached with a
6+
standard memcached driver at `memcache:11211`.
47

58
1. [Create a new Express app](http://expressjs.com/starter/generator.html)
69

7-
2. Create an `app.yaml` in the root of your application with the following contents:
10+
2. Create an `app.yaml` in the root of your application with the following
11+
contents:
812

913
```yaml
1014
runtime: nodejs
@@ -16,33 +20,37 @@ This is a simple guide to using memcached for session state while running [expre
1620

1721
Notice the MEMCACHE_URL environment variable - this is where you can reach your standard memcached cluster across instances.
1822

19-
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:
23+
3. Use the [connect-memcached](https://github.com/balor/connect-memcached)
24+
module. Run `npm install --save connect-memcached`, and add the following to
25+
your server.js or app.js:
2026

2127
```js
2228
var MemcachedStore = require('connect-memcached')(session);
23-
...
29+
// ...
2430
app.use(session({
25-
secret: 'appengineFTW',
26-
key: 'test',
27-
proxy: 'true',
28-
store: new MemcachedStore({
29-
hosts: [process.env.MEMCACHE_URL || '127.0.0.1:11211']
30-
})
31+
secret: 'appengineFTW',
32+
key: 'test',
33+
proxy: 'true',
34+
store: new MemcachedStore({
35+
hosts: [process.env.MEMCACHE_URL || '127.0.0.1:11211']
36+
})
3137
}));
3238
```
33-
4. In your express route handlers, you can now safely use `req.session.*` across multiple nodejs instances:
39+
40+
4. In your express route handlers, you can now safely use `req.session.*` across
41+
multiple nodejs instances:
3442

3543
```js
3644
app.get('/', function(req, res){
37-
publicIp.v4(function (err, ip) {
38-
res.write("<div>" + ip + "</div>");
39-
if(req.session.views) {
40-
++req.session.views;
41-
} else {
42-
req.session.views = 1;
43-
}
44-
res.end('Viewed <strong>' + req.session.views + '</strong> times.');
45-
});
45+
publicIp.v4(function (err, ip) {
46+
res.write('<div>' + ip + '</div>');
47+
if(req.session.views) {
48+
++req.session.views;
49+
} else {
50+
req.session.views = 1;
51+
}
52+
res.end('Viewed <strong>' + req.session.views + '</strong> times.');
53+
});
4654
});
4755
```
4856

@@ -52,13 +60,13 @@ This is a simple guide to using memcached for session state while running [expre
5260

5361
Run memcached on localhost:11211 by running `memcached`
5462

55-
56-
6. Deploy your app. For convenience, you can use an npm script to run the command. Modify your `package.json` to include:
63+
6. Deploy your app. For convenience, you can use an npm script to run the
64+
command. Modify your `package.json` to include:
5765

5866
```js
5967
"scripts": {
6068
"start": "node server.js",
61-
"deploy": "gcloud preview app deploy app.yaml --set-default --project [project id]"
69+
"deploy": "gcloud preview app deploy app.yaml"
6270
}
6371
```
6472

appengine/express-memcached-session/app.yaml

-1
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,6 @@
1212
# limitations under the License.
1313

1414
runtime: nodejs
15-
api_version: 1
1615
vm: true
1716
env_variables:
1817
PORT: 8080

appengine/express-memcached-session/package.json

+11-5
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,20 @@
11
{
2-
"name": "express-memcached-session-demo",
3-
"version": "1.0.0",
2+
"name": "appengine-express-memcached-session",
3+
"description": "An example of using memcached for sessions in Express.js on Google App Engine.",
4+
"version": "0.0.1",
45
"private": true,
6+
"license": "Apache Version 2.0",
7+
"engines": {
8+
"node": "~0.12.7"
9+
},
510
"scripts": {
6-
"deploy": "gcloud preview app deploy app.yaml --set-default --project express-memcached-demo"
11+
"start": "node server.js",
12+
"deploy": "gcloud preview app deploy app.yaml"
713
},
814
"dependencies": {
915
"connect-memcached": "^0.1.0",
10-
"cookie-parser": "~1.3.5",
11-
"express": "~4.12.4",
16+
"cookie-parser": "^1.3.5",
17+
"express": "^4.12.4",
1218
"express-session": "^1.11.3",
1319
"public-ip": "^1.1.0"
1420
}

appengine/express-memcached-session/server.js

+24-20
Original file line numberDiff line numberDiff line change
@@ -24,29 +24,33 @@ var app = express();
2424

2525
app.use(cookieParser());
2626
app.use(session({
27-
secret: 'appengineFTW',
28-
key: 'test',
29-
proxy: 'true',
30-
store: new MemcachedStore({
31-
hosts: [process.env.MEMCACHE_URL || '127.0.0.1:11211']
32-
})
27+
secret: 'your-secret-here',
28+
key: 'test',
29+
proxy: 'true',
30+
store: new MemcachedStore({
31+
hosts: [process.env.MEMCACHE_URL || '127.0.0.1:11211']
32+
})
3333
}));
3434

3535
app.get('/', function(req, res){
36-
publicIp.v4(function (err, ip) {
37-
38-
// This shows the IP for each
39-
res.write('<div>' + ip + '</div>');
40-
41-
if(req.session.views) {
42-
++req.session.views;
43-
} else {
44-
req.session.views = 1;
45-
}
46-
res.end('Viewed <strong>' + req.session.views + '</strong> times.');
47-
});
36+
publicIp.v4(function (err, ip) {
37+
38+
// This shows the IP for each
39+
res.write('<div>' + ip + '</div>');
40+
41+
if(req.session.views) {
42+
++req.session.views;
43+
} else {
44+
req.session.views = 1;
45+
}
46+
res.end('Viewed <strong>' + req.session.views + '</strong> times.');
47+
});
4848
});
4949

50-
http.createServer(app).listen(process.env.PORT || 8080, function() {
50+
if (module === require.main) {
51+
http.createServer(app).listen(process.env.PORT || 8080, function() {
5152
console.log('Listening on %d', this.address().port);
52-
});
53+
});
54+
}
55+
56+
module.exports = app;

test/appengine/all.test.js

+15-8
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,13 @@ var sampleTests = [
3434
msg: 'Hello World! Express.js on Google App Engine.',
3535
TRAVIS_NODE_VERSION: '0.10'
3636
},
37+
{
38+
dir: 'express-memcached-session',
39+
cmd: 'node',
40+
args: ['server.js'],
41+
msg: 'Viewed',
42+
TRAVIS_NODE_VERSION: '0.10'
43+
},
3744
{
3845
dir: 'geddy',
3946
deploy: true,
@@ -82,12 +89,12 @@ var sampleTests = [
8289
args: ['app.js'],
8390
msg: 'Express.js + Mailgun on Google App Engine.'
8491
},
85-
// {
86-
// dir: 'redis',
87-
// cmd: 'node',
88-
// args: ['server.js'],
89-
// msg: '127.0.0.1'
90-
// },
92+
{
93+
dir: 'redis',
94+
cmd: 'node',
95+
args: ['server.js'],
96+
msg: '127.0.0.1'
97+
},
9198
{
9299
dir: 'restify',
93100
deploy: true,
@@ -112,7 +119,7 @@ if (process.env.TRAVIS_NODE_VERSION === '0.10') {
112119
});
113120
}
114121

115-
//if (process.env.TRAVIS_NODE_VERSION === 'stable') {
122+
if (process.env.TRAVIS_NODE_VERSION === 'stable') {
116123
// For some reason the "npm install" step for the Sails sample doesn't work on
117124
// Travis when using Node.js stable. It works locally, however.
118125
sampleTests.push({
@@ -123,7 +130,7 @@ if (process.env.TRAVIS_NODE_VERSION === '0.10') {
123130
msg: 'Hello World! Koa.js on Google App Engine.',
124131
TRAVIS_NODE_VERSION: 'stable'
125132
});
126-
//}
133+
}
127134

128135
// Send a request to the given url and test that the response body has the
129136
// expected value
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
// Copyright 2015, Google, Inc.
2+
// Licensed under the Apache License, Version 2.0 (the "License");
3+
// you may not use this file except in compliance with the License.
4+
// You may obtain a copy of the License at
5+
//
6+
// http://www.apache.org/licenses/LICENSE-2.0
7+
//
8+
// Unless required by applicable law or agreed to in writing, software
9+
// distributed under the License is distributed on an "AS IS" BASIS,
10+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11+
// See the License for the specific language governing permissions and
12+
// limitations under the License.
13+
14+
'use strict';
15+
16+
var assert = require('assert');
17+
var request = require('supertest');
18+
var app = require('../../appengine/express-memcached-session/server.js');
19+
20+
describe('express-memcached-session', function () {
21+
it('should return 200 and the correct response', function (done) {
22+
request(app)
23+
.get('/')
24+
.expect(200)
25+
.expect(function (res) {
26+
assert(res.text.match(/<div>(\d|\d\d|\d\d\d)\.(\d|\d\d|\d\d\d)\.(\d|\d\d|\d\d\d)\.(\d|\d\d|\d\d\d)<\/div>Viewed <strong>\d<\/strong> times./), // jshint ignore:line
27+
'Response should match expected response.\n' +
28+
'Found: ' + res.text
29+
);
30+
})
31+
.end(done);
32+
});
33+
});

0 commit comments

Comments
 (0)