aws-lambda-runner 1.4.0 → 1.4.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 1072f1479b4079a9ad869e54f88e9d7868c5b43b
4
- data.tar.gz: 8385219cdbf104fed5b41b7b44192e78023c0e25
3
+ metadata.gz: fef3ce92ca629b7b66df8d9a5600a690c84c041f
4
+ data.tar.gz: 38d7af195b18d8be62f8ee4591c0cd72ae811744
5
5
  SHA512:
6
- metadata.gz: a36af0663924daa993afb7eac23650e743f7687aa8169a2157959be3866f75e94663a18944da8fd599d8b985d7efb4c709c36abe2b30867d05eda29381a67cd2
7
- data.tar.gz: fa743cd813123c3dc80dee145b0fee65d942a0dec0515c5c063bcd1b0c2978e4deb885a7fe1d7fb8113f6c2e887d67663fcc0cf9eaf74fc3ce99a5ff93bb7897
6
+ metadata.gz: 7c1dab1a066ceaa9608f8041b7e42a1ffa60f7c22ca7a2b6ec504fab3cf36b08bc635bbbfaabaccd7e4a7527d7880c971b42c45c7f5d691a92054e25775d5911
7
+ data.tar.gz: 3a1abbd85b75a90b3307a62c50a4555e85ee3bd452aceb2d17d2e1a4fb0de4264444c7e96167a4dcfcb242efdcc39faee59dc104d4d011f6f297b18e50311bf5
@@ -2,128 +2,170 @@ var merge = require('merge');
2
2
  var url = require('url');
3
3
 
4
4
  var next_id = 0;
5
- // results[id] = { threw: error, completed: [ errorValue, successValue ], timedOut: bool };
6
- var results = {};
5
+ // FIXME: this object grows forever - entries are never removed. Should they
6
+ // be removed by expiry (time), and/or a REST API call?
7
+ var jobs = {};
8
+
9
+ var Job = function () {
10
+ };
11
+
12
+ Job.prototype.doError = function (error) {
13
+ if (!this.completionValues && !this.timedOut) {
14
+ this.threw = error;
15
+ }
16
+ };
17
+
18
+ Job.prototype.doCompletion = function (errorValue, successValue) {
19
+ if (!this.threw && !this.timedOut) {
20
+ this.completionValues = [ errorValue, successValue ];
21
+ }
22
+ };
23
+
24
+ Job.prototype.doTimedOut = function () {
25
+ if (!this.threw && !this.completionValues) {
26
+ this.timedOut = true;
27
+ }
28
+ };
7
29
 
8
30
  var region = function () {
9
31
  return process.env.AWS_DEFAULT_REGION || process.env.AWS_REGION || process.env.AMAZON_REGION || "xx-dummy-0";
10
32
  };
11
33
 
12
- exports.request = function(req, res, opts, handler) {
34
+ var defaultContextObject = function () {
35
+ return {
36
+ // Fixed, but reasonably representative
37
+ functionName: "via-aws-lambda-runner",
38
+ functionVersion: "$LATEST",
39
+ invokedFunctionArn: "arn:aws:lambda:" + region() + ":000000000000:function:via-aws-lambda-runner:$LATEST",
40
+ memoryLimitInMB: 100,
41
+ awsRequestId: "00000000-0000-0000-0000-000000000000",
42
+ logGroupName: "/aws/lambda/via-aws-lambda-runner",
43
+ logStreamName: "some-log-stream-name",
44
+ };
45
+ };
13
46
 
14
- if (req.method === 'POST') {
47
+ var makeContextObject = function (timeout, overrides) {
48
+ var context = merge(true, defaultContextObject(), overrides);
15
49
 
16
- var id = ++next_id;
17
- results[id] = {};
18
-
19
- var requestBody = '';
20
-
21
- req.on('data', function(chunk) {
22
- requestBody += chunk.toString();
23
- });
24
-
25
- req.on('end', function(chunk) {
26
- setTimeout(function() {
27
- if (!results[id].completed) {
28
- results[id].timedOut = true;
29
- }
30
- }, opts.timeout);
31
-
32
- var requestObject;
33
- try {
34
- requestObject = JSON.parse(requestBody);
35
- } catch (e) {
36
- console.log("POSTed bad json: " + e.toString());
37
- res.writeHead(400, {'Content-Type': 'text/plain'});
38
- res.end(e.toString());
39
- return;
40
- }
41
-
42
- res.writeHead(200, {'Content-Type': 'text/plain'});
43
- res.end(String(id));
44
-
45
- var approximateEndTime = (new Date().getTime()) + opts.timeout;
46
-
47
- var context = {
48
- done: function(err, message) {
49
- results[id].completed = [ err, message ];
50
- if (err) {
51
- console.warn('Error:', err);
52
- }
53
- },
54
- getRemainingTimeInMillis: function () {
55
- return approximateEndTime - (new Date().getTime());
56
- },
57
-
58
- // Fixed, but reasonably representative
59
- functionName: "via-aws-lambda-runner",
60
- functionVersion: "$LATEST",
61
- invokedFunctionArn: "arn:aws:lambda:" + region() + ":000000000000:function:via-aws-lambda-runner:$LATEST",
62
- memoryLimitInMB: 100,
63
- awsRequestId: "00000000-0000-0000-0000-000000000000",
64
- logGroupName: "/aws/lambda/via-aws-lambda-runner",
65
- logStreamName: "some-log-stream-name",
66
- };
67
-
68
- context.fail = function(err) { context.done(err, null); };
69
- context.succeed = function(data) { context.done(null, data); };
70
-
71
- var event = requestObject.event;
72
- merge(context, requestObject.context || {});
73
-
74
- try {
75
- handler(event, context);
76
- } catch (e) {
77
- console.log("Handler crashed", e);
78
- results[id].threw = e;
79
- }
80
-
81
- });
50
+ var approximateEndTime = (new Date().getTime()) + timeout;
82
51
 
83
- } else if (req.method === 'DELETE') {
52
+ context.getRemainingTimeInMillis = function () {
53
+ return approximateEndTime - (new Date().getTime());
54
+ };
84
55
 
85
- // FIXME untested
86
- res.writeHead(202, {'Content-Type': 'text/plain'});
87
- var terminationMessage = 'Terminating server at http://[localhost]:' + opts.port + ' for ' + opts['module-path'] + ' / ' + opts.handler;
88
- res.end(terminationMessage + '\n');
89
- console.info(terminationMessage);
90
- server.close();
56
+ context.fail = function(err) { context.done(err, null); };
57
+ context.succeed = function(data) { context.done(null, data); };
91
58
 
92
- } else if (req.method === 'GET') {
59
+ return context;
60
+ };
61
+
62
+ var startJob = function (job, requestObject, handler, opts) {
63
+ setTimeout(function() {
64
+ job.doTimedOut();
65
+ }, opts.timeout);
66
+
67
+ var event = requestObject.event;
68
+
69
+ var context = makeContextObject(opts.timeout, requestObject.context || {});
70
+ context.done = function (err, result) {
71
+ job.doCompletion(err, result);
72
+ if (err) {
73
+ console.warn('Error:', err);
74
+ }
75
+ };
76
+
77
+ try {
78
+ handler(event, context);
79
+ } catch (e) {
80
+ console.log("Handler crashed", e);
81
+ job.doError(e);
82
+ }
83
+ };
93
84
 
94
- var request_id = parseInt(url.parse(req.url, true).query.id);
95
- var result = results[request_id];
85
+ var doCreateJob = function (req, res, opts, handler) {
86
+ var id = ++next_id;
87
+ var job = jobs[id] = new Job();
96
88
 
97
- var status = null;
98
- var responseBody = null;
89
+ var requestBody = '';
99
90
 
100
- if (result === undefined) {
101
- status = 404;
91
+ req.on('data', function(chunk) {
92
+ requestBody += chunk.toString();
93
+ });
94
+
95
+ req.on('end', function() {
96
+ var requestObject;
97
+
98
+ try {
99
+ requestObject = JSON.parse(requestBody);
100
+ } catch (e) {
101
+ console.log("POSTed bad json: " + e.toString());
102
+ res.writeHead(400, {'Content-Type': 'text/plain'});
103
+ res.end(e.toString());
104
+ return;
105
+ }
106
+
107
+ res.writeHead(200, {'Content-Type': 'text/plain'});
108
+ res.end(String(id));
109
+
110
+ startJob(job, requestObject, handler, opts);
111
+ });
112
+ };
113
+
114
+ var getJobStatus = function (result) {
115
+ var status = null;
116
+ var responseBody = null;
117
+
118
+ if (result.completionValues) {
119
+ if (result.completionValues[0] !== null && result.completionValues[0] !== undefined) {
120
+ status = 502;
121
+ responseBody = result.completionValues[0];
102
122
  } else {
103
- if (result.completed) {
104
- if (result.completed[0] !== null && result.completed[0] !== undefined) {
105
- status = 502;
106
- responseBody = result.completed[0];
107
- } else {
108
- status = 201;
109
- responseBody = result.completed[1];
110
- }
111
- } else if (result.threw) {
112
- status = 500;
113
- responseBody = result.threw.toString();
114
- } else if (result.timedOut) {
115
- status = 504;
116
- } else {
117
- // still in progress
118
- status = 200;
119
- }
123
+ status = 201;
124
+ responseBody = result.completionValues[1];
120
125
  }
126
+ } else if (result.threw) {
127
+ status = 500;
128
+ responseBody = result.threw.toString();
129
+ } else if (result.timedOut) {
130
+ status = 504;
131
+ } else {
132
+ // still in progress
133
+ status = 200;
134
+ }
135
+
136
+ return { status: status, data: responseBody };
137
+ };
121
138
 
122
- // non-standard stringification of undefined
123
- if (responseBody === undefined) responseBody = null;
139
+ exports.request = function(req, res, opts, handler) {
124
140
 
125
- res.writeHead(status, {'Content-Type': 'application/json'});
126
- res.end(JSON.stringify(responseBody) + '\n');
141
+ if (req.method === 'POST') {
142
+
143
+ doCreateJob(req, res, opts, handler);
144
+
145
+ } else if (req.method === 'DELETE') {
146
+
147
+ (function () {
148
+ // FIXME untested
149
+ res.writeHead(202, {'Content-Type': 'text/plain'});
150
+ var terminationMessage = 'Terminating server at http://[localhost]:' + opts.port + ' for ' + opts['module-path'] + ' / ' + opts.handler;
151
+ res.end(terminationMessage + '\n');
152
+ console.info(terminationMessage);
153
+ server.close();
154
+ })();
155
+
156
+ } else if (req.method === 'GET') {
157
+
158
+ (function () {
159
+ var request_id = parseInt(url.parse(req.url, true).query.id);
160
+ var result = jobs[request_id];
161
+ var answer = result ? getJobStatus(result) : { status: 404, data: null };
162
+
163
+ // non-standard stringification of undefined
164
+ if (answer.data === undefined) answer.data = null;
165
+
166
+ res.writeHead(answer.status, {'Content-Type': 'application/json'});
167
+ res.end(JSON.stringify(answer.data) + '\n');
168
+ })();
127
169
 
128
170
  } else {
129
171
 
@@ -133,3 +175,5 @@ exports.request = function(req, res, opts, handler) {
133
175
  }
134
176
 
135
177
  };
178
+
179
+ // vi: set sw=2 et :
@@ -4,10 +4,6 @@ require 'json'
4
4
  require 'English'
5
5
  require 'fileutils'
6
6
 
7
- def load_json(name)
8
- File.open(File.join(File.dirname(__FILE__), name)) { |file| return JSON.load(file) }
9
- end
10
-
11
7
  # runs a nodejs lambda program so the s3 events can be sent to it via http post
12
8
  module LambdaRunner
13
9
  # abstract for running the program
@@ -84,7 +80,7 @@ module LambdaRunner
84
80
  record['s3']['object']['key'] = key
85
81
  record
86
82
  end
87
- event.to_json
83
+ event
88
84
  end
89
85
 
90
86
  def self.sns_event(topicArn, messageId, timestamp, messageBody)
@@ -95,8 +91,16 @@ module LambdaRunner
95
91
  record['Sns']['Timestamp'] = timestamp
96
92
  record['Sns']['Message'] = messageBody
97
93
  end
98
- event.to_json
94
+ event
95
+ end
96
+
97
+ private
98
+
99
+ def self.load_json(name)
100
+ base = File.dirname(File.dirname(__FILE__))
101
+ File.open(File.join(base, "samples", name)) { |file| return JSON.load(file) }
99
102
  end
103
+
100
104
  end
101
105
  end
102
106
 
File without changes
File without changes
@@ -4,8 +4,7 @@ require_relative '../lib/lambda_runner'
4
4
  describe LambdaRunner::Events do
5
5
 
6
6
  it "should generate an S3 event" do
7
- json = LambdaRunner::Events.s3_event("some-bucket", "some/key", "local/path")
8
- data = JSON.parse json
7
+ data = LambdaRunner::Events.s3_event("some-bucket", "some/key", "local/path")
9
8
  expect(data["Records"][0]["file"]["path"]).to eq("local/path")
10
9
  expect(data["Records"][0]["s3"]["bucket"]["name"]).to eq("some-bucket")
11
10
  expect(data["Records"][0]["s3"]["bucket"]["arn"]).to eq("arn:aws:s3:::some-bucket")
@@ -13,8 +12,7 @@ describe LambdaRunner::Events do
13
12
  end
14
13
 
15
14
  it "should generate an SNS event" do
16
- json = LambdaRunner::Events.sns_event("some-arn", "some-id", "some-timestamp", "some-body")
17
- data = JSON.parse json
15
+ data = LambdaRunner::Events.sns_event("some-arn", "some-id", "some-timestamp", "some-body")
18
16
  expect(data["Records"][0]["Sns"]["TopicArn"]).to eq("some-arn")
19
17
  expect(data["Records"][0]["Sns"]["MessageId"]).to eq("some-id")
20
18
  expect(data["Records"][0]["Sns"]["Timestamp"]).to eq("some-timestamp")
metadata CHANGED
@@ -1,12 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: aws-lambda-runner
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.4.0
4
+ version: 1.4.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - andrew wheat
8
8
  - tristan hill
9
9
  - stuart hicks
10
+ - rachel evans
10
11
  autorequire:
11
12
  bindir: bin
12
13
  cert_chain: []
@@ -148,11 +149,11 @@ files:
148
149
  - js/request.js
149
150
  - js/startup.js
150
151
  - lib/lambda_runner.rb
151
- - lib/sample_cloudwatch_event.json
152
- - lib/sample_s3_event.json
153
- - lib/sample_s3_test_event.json
154
- - lib/sample_scheduled_event.json
155
- - lib/sample_sns_event.json
152
+ - samples/sample_cloudwatch_event.json
153
+ - samples/sample_s3_event.json
154
+ - samples/sample_s3_test_event.json
155
+ - samples/sample_scheduled_event.json
156
+ - samples/sample_sns_event.json
156
157
  - spec/lambda-runner_spec.rb
157
158
  homepage: https://github.com/bbc/aws-lambda-runner
158
159
  licenses: