Skip to content

Commit

Permalink
Merge pull request rstudio#11 from rstudio/bug/memory_leak
Browse files Browse the repository at this point in the history
Use content_by_lua and access_by_lua instead of by_file
  • Loading branch information
cbarraford committed Nov 18, 2014
2 parents 5ae4b9f + 2881566 commit 4b01666
Show file tree
Hide file tree
Showing 8 changed files with 121 additions and 106 deletions.
8 changes: 8 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,14 @@
Changelog
=========

## 2.0.1 (2014-11-18)

### Features
+ [PR](https://github.com/rstudio/redx/pull/11): Fix memory leak

### Backwards Incompatibility Note
This change requires an update to nginx.conf using `content_by_lua`. See the `nginx.conf.example` for an example.

## 2.0 (2014-11-1)

### Features
Expand Down
84 changes: 29 additions & 55 deletions lua/src/bin/api.lua
Original file line number Diff line number Diff line change
Expand Up @@ -9,57 +9,32 @@ do
local _obj_0 = require("lapis.util")
from_json, unescape = _obj_0.from_json, _obj_0.unescape
end
local response
response = function(t)
if t['redis'] then
redis.finish(t['redis'])
end
response = {
status = 500,
json = {
message = "Unknown failure"
}
}
if t['status'] then
response['status'] = t['status']
end
if t['msg'] then
response['json']['message'] = t['msg']
end
if t['data'] then
response['json']['data'] = t['data']
end
if t['msg'] == nil and response['status'] < 300 then
response['json']['message'] = "OK"
end
if t['msg'] == nil and response['status'] == 404 then
response['json']['message'] = "Entry does not exist"
end
if response['status'] >= 300 then
library.log_err(response)
end
return response
end
local webserver
do
local _parent_0 = lapis.Application
local _base_0 = {
['/test'] = respond_to({
GET = function(self)
return {
['status'] = 200
}
end
}),
['/health'] = respond_to({
GET = function(self)
return response(redis.test())
return library.response(redis.test())
end
}),
['/flush'] = respond_to({
DELETE = function(self)
return response(redis.flush())
return library.response(redis.flush())
end
}),
['/orphans'] = respond_to({
GET = function(self)
return response(redis.orphans())
return library.response(redis.orphans())
end,
DELETE = function(self)
return response(redis.delete_batch_data(redis.orphans()['data']))
return library.response(redis.delete_batch_data(redis.orphans()['data']))
end
}),
['/batch'] = respond_to({
Expand All @@ -70,74 +45,74 @@ do
end,
POST = function(self)
if not (self.json_body) then
return response({
return library.response({
status = 400,
msg = "Missing json body"
})
end
return response(redis.save_batch_data(self.json_body, false))
return library.response(redis.save_batch_data(self.json_body, false))
end,
PUT = function(self)
if not (self.json_body) then
return response({
return library.response({
status = 400,
msg = "Missing json body"
})
end
return response(redis.save_batch_data(self.json_body, true))
return library.response(redis.save_batch_data(self.json_body, true))
end,
DELETE = function(self)
if not (self.json_body) then
return response({
return library.response({
status = 400,
msg = "Missing json body"
})
end
return response(redis.delete_batch_data(self.json_body))
return library.response(redis.delete_batch_data(self.json_body))
end
}),
['/frontends'] = respond_to({
GET = function(self)
return response(redis.get_data('frontends', nil))
return library.response(redis.get_data('frontends', nil))
end
}),
['/backends'] = respond_to({
GET = function(self)
return response(redis.get_data('backends', nil))
return library.response(redis.get_data('backends', nil))
end
}),
['/:type/:name'] = respond_to({
GET = function(self)
return response(redis.get_data(self.params.type, unescape(self.params.name)))
return library.response(redis.get_data(self.params.type, unescape(self.params.name)))
end,
DELETE = function(self)
return response(redis.delete_data(self.params.type, unescape(self.params.name)))
return library.response(redis.delete_data(self.params.type, unescape(self.params.name)))
end
}),
['/backends/:name/config/:config'] = respond_to({
GET = function(self)
return response(redis.get_config(unescape(self.params.name), unescape(self.params.config)))
return library.response(redis.get_config(unescape(self.params.name), unescape(self.params.config)))
end
}),
['/backends/:name/config/:config/:value'] = respond_to({
PUT = function(self)
return response(redis.set_config(unescape(self.params.name), unescape(self.params.config), unescape(self.params.value)))
return library.response(redis.set_config(unescape(self.params.name), unescape(self.params.config), unescape(self.params.value)))
end
}),
['/backends/:name/:value/score/:score'] = respond_to({
PUT = function(self)
return response(redis.save_data('backends', unescape(self.params.name), unescape(self.params.value), unescape(self.params.score), false))
return library.response(redis.save_data('backends', unescape(self.params.name), unescape(self.params.value), unescape(self.params.score), false))
end
}),
['/:type/:name/:value'] = respond_to({
POST = function(self)
return response(redis.save_data(self.params.type, unescape(self.params.name), unescape(self.params.value), 0, false))
return library.response(redis.save_data(self.params.type, unescape(self.params.name), unescape(self.params.value), 0, false))
end,
PUT = function(self)
return response(redis.save_data(self.params.type, unescape(self.params.name), unescape(self.params.value), 0, true))
return library.response(redis.save_data(self.params.type, unescape(self.params.name), unescape(self.params.value), 0, true))
end,
DELETE = function(self)
return response(redis.delete_data(self.params.type, unescape(self.params.name), unescape(self.params.value)))
return library.response(redis.delete_data(self.params.type, unescape(self.params.name), unescape(self.params.value)))
end
})
}
Expand All @@ -148,7 +123,7 @@ do
return _parent_0.__init(self, ...)
end,
__base = _base_0,
__name = "webserver",
__name = nil,
__parent = _parent_0
}, {
__index = function(cls, name)
Expand All @@ -169,6 +144,5 @@ do
if _parent_0.__inherited then
_parent_0.__inherited(_parent_0, _class_0)
end
webserver = _class_0
return _class_0
end
return lapis.serve(webserver)
6 changes: 2 additions & 4 deletions lua/src/bin/main.lua
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,6 @@ process_response = function(response)
}
end
end
local webserver
do
local _parent_0 = lapis.Application
local _base_0 = {
Expand Down Expand Up @@ -139,7 +138,7 @@ do
return _parent_0.__init(self, ...)
end,
__base = _base_0,
__name = "webserver",
__name = nil,
__parent = _parent_0
}, {
__index = function(cls, name)
Expand All @@ -160,6 +159,5 @@ do
if _parent_0.__inherited then
_parent_0.__inherited(_parent_0, _class_0)
end
webserver = _class_0
return _class_0
end
return lapis.serve(webserver)
30 changes: 30 additions & 0 deletions lua/src/lib/library.lua
Original file line number Diff line number Diff line change
Expand Up @@ -27,4 +27,34 @@ M.set = function(list)
end
return set
end
M.response = function(t)
if t['redis'] then
redis.finish(t['redis'])
end
local response = {
status = 500,
json = {
message = "Unknown failure"
}
}
if t['status'] then
response['status'] = t['status']
end
if t['msg'] then
response['json']['message'] = t['msg']
end
if t['data'] then
response['json']['data'] = t['data']
end
if t['msg'] == nil and response['status'] < 300 then
response['json']['message'] = "OK"
end
if t['msg'] == nil and response['status'] == 404 then
response['json']['message'] = "Entry does not exist"
end
if response['status'] >= 300 then
library.log_err(response)
end
return response
end
return M
9 changes: 6 additions & 3 deletions nginx.conf.example
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,9 @@ http {

location / {
default_type application/json;
content_by_lua_file "./lua/src/bin/api.lua";
content_by_lua '
require("lapis").serve("api")
';
}
}

Expand All @@ -42,8 +44,9 @@ http {
set $upstream 'fallback';

location / {
default_type application/json;
access_by_lua_file "./lua/src/bin/main.lua";
access_by_lua '
require("lapis").serve("main")
';
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
Expand Down
66 changes: 25 additions & 41 deletions src/bin/api.moon
Original file line number Diff line number Diff line change
Expand Up @@ -2,97 +2,81 @@ lapis = require "lapis"
import respond_to from require "lapis.application"
import from_json, unescape from require "lapis.util"

response = (t) ->
-- close redis connection
redis.finish(t['redis']) if t['redis']

-- setup defaults
response = status: 500, json: { message: "Unknown failure" }

response['status'] = t['status'] if t['status']
response['json']['message'] = t['msg'] if t['msg']
response['json']['data'] = t['data'] if t['data']

-- if a msg wasn't given and the status code is successful (ie 200's), assume msg is "OK"
response['json']['message'] = "OK" if t['msg'] == nil and response['status'] < 300
response['json']['message'] = "Entry does not exist" if t['msg'] == nil and response['status'] == 404

-- log if theres a failure
library.log_err(response) if response['status'] >= 300
return response
class extends lapis.Application
'/test': respond_to {
GET: =>
{'status': 200}
}

webserver = class extends lapis.Application
'/health': respond_to {
GET: =>
response(redis.test())
library.response(redis.test())
}

'/flush': respond_to {
DELETE: =>
response(redis.flush())
library.response(redis.flush())
}

'/orphans': respond_to {
GET: =>
response(redis.orphans())
library.response(redis.orphans())
DELETE: =>
response(redis.delete_batch_data(redis.orphans()['data']))
library.response(redis.delete_batch_data(redis.orphans()['data']))
}

'/batch': respond_to {
before: =>
for k,v in pairs @req.params_post do
@json_body = from_json(k)
POST: =>
return response(status: 400, msg: "Missing json body") unless @json_body
response(redis.save_batch_data(@json_body, false))
return library.response(status: 400, msg: "Missing json body") unless @json_body
library.response(redis.save_batch_data(@json_body, false))
PUT: =>
return response(status: 400, msg: "Missing json body") unless @json_body
response(redis.save_batch_data(@json_body, true))
return library.response(status: 400, msg: "Missing json body") unless @json_body
library.response(redis.save_batch_data(@json_body, true))
DELETE: =>
return response(status: 400, msg: "Missing json body") unless @json_body
response(redis.delete_batch_data(@json_body))
return library.response(status: 400, msg: "Missing json body") unless @json_body
library.response(redis.delete_batch_data(@json_body))
}

'/frontends': respond_to {
GET: =>
response(redis.get_data('frontends', nil))
library.response(redis.get_data('frontends', nil))
}

'/backends': respond_to {
GET: =>
response(redis.get_data('backends', nil))
library.response(redis.get_data('backends', nil))
}

'/:type/:name': respond_to {
GET: =>
response(redis.get_data(@params.type, unescape(@params.name)))
library.response(redis.get_data(@params.type, unescape(@params.name)))
DELETE: =>
response(redis.delete_data(@params.type, unescape(@params.name)))
library.response(redis.delete_data(@params.type, unescape(@params.name)))
}

'/backends/:name/config/:config': respond_to {
GET: =>
response(redis.get_config(unescape(@params.name), unescape(@params.config)))
library.response(redis.get_config(unescape(@params.name), unescape(@params.config)))
}

'/backends/:name/config/:config/:value': respond_to {
PUT: =>
response(redis.set_config(unescape(@params.name), unescape(@params.config), unescape(@params.value)))
library.response(redis.set_config(unescape(@params.name), unescape(@params.config), unescape(@params.value)))
}

'/backends/:name/:value/score/:score': respond_to {
PUT: =>
response(redis.save_data('backends', unescape(@params.name), unescape(@params.value), unescape(@params.score), false))
library.response(redis.save_data('backends', unescape(@params.name), unescape(@params.value), unescape(@params.score), false))
}

'/:type/:name/:value': respond_to {
POST: =>
response(redis.save_data(@params.type, unescape(@params.name), unescape(@params.value), 0, false))
library.response(redis.save_data(@params.type, unescape(@params.name), unescape(@params.value), 0, false))
PUT: =>
response(redis.save_data(@params.type, unescape(@params.name), unescape(@params.value), 0, true))
library.response(redis.save_data(@params.type, unescape(@params.name), unescape(@params.value), 0, true))
DELETE: =>
response(redis.delete_data(@params.type, unescape(@params.name), unescape(@params.value)))
library.response(redis.delete_data(@params.type, unescape(@params.name), unescape(@params.value)))
}

lapis.serve(webserver)
Loading

0 comments on commit 4b01666

Please sign in to comment.