Tarantool Team's Experience with Lua Developer Tools

Tarantool Team's Experience with Lua Developer Tools

03/03/2019 Tarantool team's experience with Lua developer tools Tarantool team's experience with Lua developer tools Yaroslav Dynnikov Tarantool, Mail.Ru Group 3 March 2019 http://localhost:8000/#1 11 //25 25 03/03/2019 Tarantool team's experience with Lua developer tools Tarantool Tarantool is an open-source data integration platform Tarantool = Database + Application server (Lua) http://localhost:8000/#1 22 //25 25 03/03/2019 Tarantool team's experience with Lua developer tools Tarantool Tarantool is an open-source data integration platform Tarantool = Database + Application server (Lua) Core team Focuses on the product development Solution team Implements projects for the Enterprise http://localhost:8000/#1 33 //25 25 03/03/2019 Tarantool team's experience with Lua developer tools Tarantool Solution Engineering 35 Lua developers ~ 50 Git repos ~ 300,000 SLoC Customers IT, Banking, Telecom, Oil & Gas Goals Develop projects fast and well http://localhost:8000/#1 44 //25 25 03/03/2019 Tarantool team's experience with Lua developer tools Writing better code http://localhost:8000/#1 55 //25 25 03/03/2019 Tarantool team's experience with Lua developer tools Development The sooner code fails - the better - Runtime checks local function handle_stat_request(req) local stat = get_stat() return { status = 200, body = json.encode(stet), } end handle_stat_request() -- returns: "null" http://localhost:8000/#1 66 //25 25 03/03/2019 Tarantool team's experience with Lua developer tools Development The sooner code fails - the better - Runtime checks local function handle_stat_request(req) local stat = get_stat() return { status = 200, body = json.encode(stet), } end handle_stat_request() -- returns: "null" Strict mode restricts access to undeclared globals require('strict').on() handle_stat_request() -- error: variable "stet" is not declared http://localhost:8000/#1 77 //25 25 03/03/2019 Tarantool team's experience with Lua developer tools Development Luacheck highlights mistakes in IDE - Runtime checks local function handle_stat_request(req) local stat, err = get_stat() -- unused variable 'err' if not stat then - Static analysis return { status = 500, body = errr -- accessing undefined variable 'errr' } end end http://localhost:8000/#1 88 //25 25 03/03/2019 Tarantool team's experience with Lua developer tools Development Luacheck highlights mistakes in IDE - Runtime checks local function handle_stat_request(req) local stat, err = get_stat() -- unused variable 'err' if not stat then - Static analysis return { status = 500, body = errr -- accessing undefined variable 'errr' } end end It also takes part in CI/CD $ luacheck server.lua Checking server.lua 1 warnings server.lua:3:15: unused variable err server.lua:8:28: accessing undefined variable errr Total: 1 warnings / 0 errors in 1 file http://localhost:8000/#1 99 //25 25 03/03/2019 Tarantool team's experience with Lua developer tools Development Error messages should help in problem investigation - Runtime checks local function get_stat(uri, opts) return http.get('http://' .. uri .. '/stat', opts) - Static analysis end get_stat(req.uri) -- req.uri == nil - Type checking -- error: attempt to concatenate a nil value -- Bad http://localhost:8000/#1 1010 //25 25 03/03/2019 Tarantool team's experience with Lua developer tools Development Error messages should help in problem investigation - Runtime checks local function get_stat(uri, opts) return http.get('http://' .. uri .. '/stat', opts) - Static analysis end get_stat(req.uri) -- req.uri == nil - Type checking -- error: attempt to concatenate a nil value -- Bad Public API should be validated local function get_stat(uri, opts) assert(type(uri) == 'string', 'uri must be a string') end get_stat(req.uri) -- req.uri == nil -- error: uri must be a string -- Better http://localhost:8000/#1 1111 //25 25 03/03/2019 Tarantool team's experience with Lua developer tools Development Some mistakes are still hard to catch - Runtime checks get_stat('localhost', {timeuot = 1}) -- ^^ typo -- No error, but does not work as expected - Static analysis -- Still bad - Type checking http://localhost:8000/#1 1212 //25 25 03/03/2019 Tarantool team's experience with Lua developer tools Development Some mistakes are still hard to catch - Runtime checks get_stat('localhost', {timeuot = 1}) -- ^^ typo -- No error, but does not work as expected - Static analysis -- Still bad - Type checking Checks validates API conventions using debug.getlocal require('checks') local function get_stat(uri, opts) checks('string', {timeout = '?number'}) end get_stat() -- error: bad argument #1 to get_stat (string expected, got nil) get_stat('localhost', {timeuot = 1}) -- error: unexpected argument opts.timeuot to get_stat http://localhost:8000/#1 1313 //25 25 03/03/2019 Tarantool team's experience with Lua developer tools Development All problems are investigated by logs - Runtime checks local req = {} local ok, resp = xpcall(handle_stat_request, debug.traceback, req) - Static analysis if not ok then log.error(resp) - Type checking end - Error handling $ tarantool server.lua ... ... E> stat.lua:14: bad argument #1 to get_stat (string expected, got nil) stack traceback: [C]: in function 'error' checks.lua:140: in function 'checks' stat.lua:14: in function 'get_stat' handlers.lua:25: in function 'handle_stat_request' [C]: in function 'xpcall' server.lua:13: in main chunk http://localhost:8000/#1 1414 //25 25 03/03/2019 Tarantool team's experience with Lua developer tools Development Business logic errors must be handled the other way - Runtime checks local function get_stat(uri) checks('string') - Static analysis if not stats[uri] then error('Unknown URI') - Type checking -- Can not tell bad request from developer mistake end end - Error handling local function get_stat(uri) checks('string') if not stats[uri] then return nil, 'Unknown URI' -- No stack trace end end http://localhost:8000/#1 1515 //25 25 03/03/2019 Tarantool team's experience with Lua developer tools Development function errors.new(str) return { - Runtime checks str = str, stack = debug.traceback(), line = ..., - Static analysis file = ..., ... } - Type checking end - Error handling local errors = require('errors') local function get_stat(uri) checks('string') if not stats[uri] then return nil, errors.new('Unknown uri') end end http://localhost:8000/#1 1616 //25 25 03/03/2019 Tarantool team's experience with Lua developer tools Testing http://localhost:8000/#1 1717 //25 25 03/03/2019 Tarantool team's experience with Lua developer tools Testing Luacov measures lines coverage - Coverage -- script.lua -- ==================================== function get_stat(uri, opts) 1 checks('string') 1 return http.get('http://' .. uri .. '/stat', opts) end 1 get_stat('localhost:8080') -- coverage 100% Line is covered ⇏ it won't raise http://localhost:8000/#1 1818 //25 25 03/03/2019 Tarantool team's experience with Lua developer tools Testing Luacov measures lines coverage - Coverage -- script.lua -- ==================================== function get_stat(uri, opts) 1 checks('string') 1 return http.get('http://' .. uri .. '/stat', opts) end 1 get_stat('localhost:8080') -- coverage 100% Line is covered ⇏ it won't raise get_stat('localhost:9') -- connection refused get_stat('google.com') -- 404 -- what else can http.get return? No condition coverage http://localhost:8000/#1 1919 //25 25 03/03/2019 Tarantool team's experience with Lua developer tools Testing gperftools, callgrind collect C stack traces jit.p captures Lua call graph - Coverage No tool captures both - Performance http://localhost:8000/#1 2020 //25 25 03/03/2019 Tarantool team's experience with Lua developer tools Code sharing http://localhost:8000/#1 2121 //25 25 03/03/2019 Tarantool team's experience with Lua developer tools Code sharing Within team - Destinations LuaRocks For customers and users RPM Deb tar.gz LuaRocks http://localhost:8000/#1 2222 //25 25 03/03/2019 Tarantool team's experience with Lua developer tools Code sharing For development: - Destinations luarocks make luarocks test (looking forward to v3.0) - LuaRocks For shipping: luarocks pack luarocks install For CI/CD: luarocks write_rockspec luarocks new_version http://localhost:8000/#1 2323 //25 25 03/03/2019 Tarantool team's experience with Lua developer tools Conclusions The sooner mistake is found - the better. Use strict mode Enable luacheck in IDE and in CI/CD Use type checks Log debug.traceback Do not chase line coverage, be thoughtful http://localhost:8000/#1 2424 //25 25 03/03/2019 Tarantool team's experience with Lua developer tools Links tarantool.io github.com/tarantool/tarantool checks: github.com/tarantool/checks luacheck: github.com/mpeterv/luacheck test-run: github.com/tarantool/test-run luaunit: github.com/bluebird75/luaunit pytest: https://pytest.org/ gperftools: github.com/tarantool/gperftools jit.p https://blast.hk/moonloader/luajit/ext_profiler.html luarocks: https://luarocks.org/ Questions? http://localhost:8000/#1 2525 //25 25.

View Full Text

Details

  • File Type
    pdf
  • Upload Time
    -
  • Content Languages
    English
  • Upload User
    Anonymous/Not logged-in
  • File Pages
    25 Page
  • File Size
    -

Download

Channel Download Status
Express Download Enable

Copyright

We respect the copyrights and intellectual property rights of all users. All uploaded documents are either original works of the uploader or authorized works of the rightful owners.

  • Not to be reproduced or distributed without explicit permission.
  • Not used for commercial purposes outside of approved use cases.
  • Not used to infringe on the rights of the original creators.
  • If you believe any content infringes your copyright, please contact us immediately.

Support

For help with questions, suggestions, or problems, please contact us